roavatar-renderer 1.5.15 → 1.5.17

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/dist/index.js CHANGED
@@ -1117,6 +1117,11 @@ const RED_GREEN_RGTC2_Format = 36285;
1117
1117
  const SIGNED_RED_GREEN_RGTC2_Format = 36286;
1118
1118
  const InterpolateDiscrete = 2300;
1119
1119
  const InterpolateLinear = 2301;
1120
+ const InterpolateSmooth = 2302;
1121
+ const ZeroCurvatureEnding = 2400;
1122
+ const ZeroSlopeEnding = 2401;
1123
+ const WrapAroundEnding = 2402;
1124
+ const NormalAnimationBlendMode = 2500;
1120
1125
  const BasicDepthPacking = 3200;
1121
1126
  const RGBADepthPacking = 3201;
1122
1127
  const TangentSpaceNormalMap = 0;
@@ -15538,6 +15543,1128 @@ class MeshDistanceMaterial extends Material {
15538
15543
  return this;
15539
15544
  }
15540
15545
  }
15546
+ function convertArray(array, type) {
15547
+ if (!array || array.constructor === type) return array;
15548
+ if (typeof type.BYTES_PER_ELEMENT === "number") {
15549
+ return new type(array);
15550
+ }
15551
+ return Array.prototype.slice.call(array);
15552
+ }
15553
+ function isTypedArray(object) {
15554
+ return ArrayBuffer.isView(object) && !(object instanceof DataView);
15555
+ }
15556
+ function getKeyframeOrder(times) {
15557
+ function compareTime(i, j) {
15558
+ return times[i] - times[j];
15559
+ }
15560
+ const n = times.length;
15561
+ const result = new Array(n);
15562
+ for (let i = 0; i !== n; ++i) result[i] = i;
15563
+ result.sort(compareTime);
15564
+ return result;
15565
+ }
15566
+ function sortedArray(values, stride, order) {
15567
+ const nValues = values.length;
15568
+ const result = new values.constructor(nValues);
15569
+ for (let i = 0, dstOffset = 0; dstOffset !== nValues; ++i) {
15570
+ const srcOffset = order[i] * stride;
15571
+ for (let j = 0; j !== stride; ++j) {
15572
+ result[dstOffset++] = values[srcOffset + j];
15573
+ }
15574
+ }
15575
+ return result;
15576
+ }
15577
+ function flattenJSON(jsonKeys, times, values, valuePropertyName) {
15578
+ let i = 1, key = jsonKeys[0];
15579
+ while (key !== void 0 && key[valuePropertyName] === void 0) {
15580
+ key = jsonKeys[i++];
15581
+ }
15582
+ if (key === void 0) return;
15583
+ let value = key[valuePropertyName];
15584
+ if (value === void 0) return;
15585
+ if (Array.isArray(value)) {
15586
+ do {
15587
+ value = key[valuePropertyName];
15588
+ if (value !== void 0) {
15589
+ times.push(key.time);
15590
+ values.push(...value);
15591
+ }
15592
+ key = jsonKeys[i++];
15593
+ } while (key !== void 0);
15594
+ } else if (value.toArray !== void 0) {
15595
+ do {
15596
+ value = key[valuePropertyName];
15597
+ if (value !== void 0) {
15598
+ times.push(key.time);
15599
+ value.toArray(values, values.length);
15600
+ }
15601
+ key = jsonKeys[i++];
15602
+ } while (key !== void 0);
15603
+ } else {
15604
+ do {
15605
+ value = key[valuePropertyName];
15606
+ if (value !== void 0) {
15607
+ times.push(key.time);
15608
+ values.push(value);
15609
+ }
15610
+ key = jsonKeys[i++];
15611
+ } while (key !== void 0);
15612
+ }
15613
+ }
15614
+ class Interpolant {
15615
+ /**
15616
+ * Constructs a new interpolant.
15617
+ *
15618
+ * @param {TypedArray} parameterPositions - The parameter positions hold the interpolation factors.
15619
+ * @param {TypedArray} sampleValues - The sample values.
15620
+ * @param {number} sampleSize - The sample size
15621
+ * @param {TypedArray} [resultBuffer] - The result buffer.
15622
+ */
15623
+ constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) {
15624
+ this.parameterPositions = parameterPositions;
15625
+ this._cachedIndex = 0;
15626
+ this.resultBuffer = resultBuffer !== void 0 ? resultBuffer : new sampleValues.constructor(sampleSize);
15627
+ this.sampleValues = sampleValues;
15628
+ this.valueSize = sampleSize;
15629
+ this.settings = null;
15630
+ this.DefaultSettings_ = {};
15631
+ }
15632
+ /**
15633
+ * Evaluate the interpolant at position `t`.
15634
+ *
15635
+ * @param {number} t - The interpolation factor.
15636
+ * @return {TypedArray} The result buffer.
15637
+ */
15638
+ evaluate(t) {
15639
+ const pp = this.parameterPositions;
15640
+ let i1 = this._cachedIndex, t1 = pp[i1], t0 = pp[i1 - 1];
15641
+ validate_interval: {
15642
+ seek: {
15643
+ let right;
15644
+ linear_scan: {
15645
+ forward_scan: if (!(t < t1)) {
15646
+ for (let giveUpAt = i1 + 2; ; ) {
15647
+ if (t1 === void 0) {
15648
+ if (t < t0) break forward_scan;
15649
+ i1 = pp.length;
15650
+ this._cachedIndex = i1;
15651
+ return this.copySampleValue_(i1 - 1);
15652
+ }
15653
+ if (i1 === giveUpAt) break;
15654
+ t0 = t1;
15655
+ t1 = pp[++i1];
15656
+ if (t < t1) {
15657
+ break seek;
15658
+ }
15659
+ }
15660
+ right = pp.length;
15661
+ break linear_scan;
15662
+ }
15663
+ if (!(t >= t0)) {
15664
+ const t1global = pp[1];
15665
+ if (t < t1global) {
15666
+ i1 = 2;
15667
+ t0 = t1global;
15668
+ }
15669
+ for (let giveUpAt = i1 - 2; ; ) {
15670
+ if (t0 === void 0) {
15671
+ this._cachedIndex = 0;
15672
+ return this.copySampleValue_(0);
15673
+ }
15674
+ if (i1 === giveUpAt) break;
15675
+ t1 = t0;
15676
+ t0 = pp[--i1 - 1];
15677
+ if (t >= t0) {
15678
+ break seek;
15679
+ }
15680
+ }
15681
+ right = i1;
15682
+ i1 = 0;
15683
+ break linear_scan;
15684
+ }
15685
+ break validate_interval;
15686
+ }
15687
+ while (i1 < right) {
15688
+ const mid = i1 + right >>> 1;
15689
+ if (t < pp[mid]) {
15690
+ right = mid;
15691
+ } else {
15692
+ i1 = mid + 1;
15693
+ }
15694
+ }
15695
+ t1 = pp[i1];
15696
+ t0 = pp[i1 - 1];
15697
+ if (t0 === void 0) {
15698
+ this._cachedIndex = 0;
15699
+ return this.copySampleValue_(0);
15700
+ }
15701
+ if (t1 === void 0) {
15702
+ i1 = pp.length;
15703
+ this._cachedIndex = i1;
15704
+ return this.copySampleValue_(i1 - 1);
15705
+ }
15706
+ }
15707
+ this._cachedIndex = i1;
15708
+ this.intervalChanged_(i1, t0, t1);
15709
+ }
15710
+ return this.interpolate_(i1, t0, t, t1);
15711
+ }
15712
+ /**
15713
+ * Returns the interpolation settings.
15714
+ *
15715
+ * @return {Object} The interpolation settings.
15716
+ */
15717
+ getSettings_() {
15718
+ return this.settings || this.DefaultSettings_;
15719
+ }
15720
+ /**
15721
+ * Copies a sample value to the result buffer.
15722
+ *
15723
+ * @param {number} index - An index into the sample value buffer.
15724
+ * @return {TypedArray} The result buffer.
15725
+ */
15726
+ copySampleValue_(index) {
15727
+ const result = this.resultBuffer, values = this.sampleValues, stride = this.valueSize, offset = index * stride;
15728
+ for (let i = 0; i !== stride; ++i) {
15729
+ result[i] = values[offset + i];
15730
+ }
15731
+ return result;
15732
+ }
15733
+ /**
15734
+ * Copies a sample value to the result buffer.
15735
+ *
15736
+ * @abstract
15737
+ * @param {number} i1 - An index into the sample value buffer.
15738
+ * @param {number} t0 - The previous interpolation factor.
15739
+ * @param {number} t - The current interpolation factor.
15740
+ * @param {number} t1 - The next interpolation factor.
15741
+ * @return {TypedArray} The result buffer.
15742
+ */
15743
+ interpolate_() {
15744
+ throw new Error("call to abstract method");
15745
+ }
15746
+ /**
15747
+ * Optional method that is executed when the interval has changed.
15748
+ *
15749
+ * @param {number} i1 - An index into the sample value buffer.
15750
+ * @param {number} t0 - The previous interpolation factor.
15751
+ * @param {number} t - The current interpolation factor.
15752
+ */
15753
+ intervalChanged_() {
15754
+ }
15755
+ }
15756
+ class CubicInterpolant extends Interpolant {
15757
+ /**
15758
+ * Constructs a new cubic interpolant.
15759
+ *
15760
+ * @param {TypedArray} parameterPositions - The parameter positions hold the interpolation factors.
15761
+ * @param {TypedArray} sampleValues - The sample values.
15762
+ * @param {number} sampleSize - The sample size
15763
+ * @param {TypedArray} [resultBuffer] - The result buffer.
15764
+ */
15765
+ constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) {
15766
+ super(parameterPositions, sampleValues, sampleSize, resultBuffer);
15767
+ this._weightPrev = -0;
15768
+ this._offsetPrev = -0;
15769
+ this._weightNext = -0;
15770
+ this._offsetNext = -0;
15771
+ this.DefaultSettings_ = {
15772
+ endingStart: ZeroCurvatureEnding,
15773
+ endingEnd: ZeroCurvatureEnding
15774
+ };
15775
+ }
15776
+ intervalChanged_(i1, t0, t1) {
15777
+ const pp = this.parameterPositions;
15778
+ let iPrev = i1 - 2, iNext = i1 + 1, tPrev = pp[iPrev], tNext = pp[iNext];
15779
+ if (tPrev === void 0) {
15780
+ switch (this.getSettings_().endingStart) {
15781
+ case ZeroSlopeEnding:
15782
+ iPrev = i1;
15783
+ tPrev = 2 * t0 - t1;
15784
+ break;
15785
+ case WrapAroundEnding:
15786
+ iPrev = pp.length - 2;
15787
+ tPrev = t0 + pp[iPrev] - pp[iPrev + 1];
15788
+ break;
15789
+ default:
15790
+ iPrev = i1;
15791
+ tPrev = t1;
15792
+ }
15793
+ }
15794
+ if (tNext === void 0) {
15795
+ switch (this.getSettings_().endingEnd) {
15796
+ case ZeroSlopeEnding:
15797
+ iNext = i1;
15798
+ tNext = 2 * t1 - t0;
15799
+ break;
15800
+ case WrapAroundEnding:
15801
+ iNext = 1;
15802
+ tNext = t1 + pp[1] - pp[0];
15803
+ break;
15804
+ default:
15805
+ iNext = i1 - 1;
15806
+ tNext = t0;
15807
+ }
15808
+ }
15809
+ const halfDt = (t1 - t0) * 0.5, stride = this.valueSize;
15810
+ this._weightPrev = halfDt / (t0 - tPrev);
15811
+ this._weightNext = halfDt / (tNext - t1);
15812
+ this._offsetPrev = iPrev * stride;
15813
+ this._offsetNext = iNext * stride;
15814
+ }
15815
+ interpolate_(i1, t0, t, t1) {
15816
+ const result = this.resultBuffer, values = this.sampleValues, stride = this.valueSize, o1 = i1 * stride, o0 = o1 - stride, oP = this._offsetPrev, oN = this._offsetNext, wP = this._weightPrev, wN = this._weightNext, p2 = (t - t0) / (t1 - t0), pp = p2 * p2, ppp = pp * p2;
15817
+ const sP = -wP * ppp + 2 * wP * pp - wP * p2;
15818
+ const s0 = (1 + wP) * ppp + (-1.5 - 2 * wP) * pp + (-0.5 + wP) * p2 + 1;
15819
+ const s1 = (-1 - wN) * ppp + (1.5 + wN) * pp + 0.5 * p2;
15820
+ const sN = wN * ppp - wN * pp;
15821
+ for (let i = 0; i !== stride; ++i) {
15822
+ result[i] = sP * values[oP + i] + s0 * values[o0 + i] + s1 * values[o1 + i] + sN * values[oN + i];
15823
+ }
15824
+ return result;
15825
+ }
15826
+ }
15827
+ class LinearInterpolant extends Interpolant {
15828
+ /**
15829
+ * Constructs a new linear interpolant.
15830
+ *
15831
+ * @param {TypedArray} parameterPositions - The parameter positions hold the interpolation factors.
15832
+ * @param {TypedArray} sampleValues - The sample values.
15833
+ * @param {number} sampleSize - The sample size
15834
+ * @param {TypedArray} [resultBuffer] - The result buffer.
15835
+ */
15836
+ constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) {
15837
+ super(parameterPositions, sampleValues, sampleSize, resultBuffer);
15838
+ }
15839
+ interpolate_(i1, t0, t, t1) {
15840
+ const result = this.resultBuffer, values = this.sampleValues, stride = this.valueSize, offset1 = i1 * stride, offset0 = offset1 - stride, weight1 = (t - t0) / (t1 - t0), weight0 = 1 - weight1;
15841
+ for (let i = 0; i !== stride; ++i) {
15842
+ result[i] = values[offset0 + i] * weight0 + values[offset1 + i] * weight1;
15843
+ }
15844
+ return result;
15845
+ }
15846
+ }
15847
+ class DiscreteInterpolant extends Interpolant {
15848
+ /**
15849
+ * Constructs a new discrete interpolant.
15850
+ *
15851
+ * @param {TypedArray} parameterPositions - The parameter positions hold the interpolation factors.
15852
+ * @param {TypedArray} sampleValues - The sample values.
15853
+ * @param {number} sampleSize - The sample size
15854
+ * @param {TypedArray} [resultBuffer] - The result buffer.
15855
+ */
15856
+ constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) {
15857
+ super(parameterPositions, sampleValues, sampleSize, resultBuffer);
15858
+ }
15859
+ interpolate_(i1) {
15860
+ return this.copySampleValue_(i1 - 1);
15861
+ }
15862
+ }
15863
+ class KeyframeTrack {
15864
+ /**
15865
+ * Constructs a new keyframe track.
15866
+ *
15867
+ * @param {string} name - The keyframe track's name.
15868
+ * @param {Array<number>} times - A list of keyframe times.
15869
+ * @param {Array<number|string|boolean>} values - A list of keyframe values.
15870
+ * @param {(InterpolateLinear|InterpolateDiscrete|InterpolateSmooth)} [interpolation] - The interpolation type.
15871
+ */
15872
+ constructor(name, times, values, interpolation) {
15873
+ if (name === void 0) throw new Error("THREE.KeyframeTrack: track name is undefined");
15874
+ if (times === void 0 || times.length === 0) throw new Error("THREE.KeyframeTrack: no keyframes in track named " + name);
15875
+ this.name = name;
15876
+ this.times = convertArray(times, this.TimeBufferType);
15877
+ this.values = convertArray(values, this.ValueBufferType);
15878
+ this.setInterpolation(interpolation || this.DefaultInterpolation);
15879
+ }
15880
+ /**
15881
+ * Converts the keyframe track to JSON.
15882
+ *
15883
+ * @static
15884
+ * @param {KeyframeTrack} track - The keyframe track to serialize.
15885
+ * @return {Object} The serialized keyframe track as JSON.
15886
+ */
15887
+ static toJSON(track) {
15888
+ const trackType = track.constructor;
15889
+ let json;
15890
+ if (trackType.toJSON !== this.toJSON) {
15891
+ json = trackType.toJSON(track);
15892
+ } else {
15893
+ json = {
15894
+ "name": track.name,
15895
+ "times": convertArray(track.times, Array),
15896
+ "values": convertArray(track.values, Array)
15897
+ };
15898
+ const interpolation = track.getInterpolation();
15899
+ if (interpolation !== track.DefaultInterpolation) {
15900
+ json.interpolation = interpolation;
15901
+ }
15902
+ }
15903
+ json.type = track.ValueTypeName;
15904
+ return json;
15905
+ }
15906
+ /**
15907
+ * Factory method for creating a new discrete interpolant.
15908
+ *
15909
+ * @static
15910
+ * @param {TypedArray} [result] - The result buffer.
15911
+ * @return {DiscreteInterpolant} The new interpolant.
15912
+ */
15913
+ InterpolantFactoryMethodDiscrete(result) {
15914
+ return new DiscreteInterpolant(this.times, this.values, this.getValueSize(), result);
15915
+ }
15916
+ /**
15917
+ * Factory method for creating a new linear interpolant.
15918
+ *
15919
+ * @static
15920
+ * @param {TypedArray} [result] - The result buffer.
15921
+ * @return {LinearInterpolant} The new interpolant.
15922
+ */
15923
+ InterpolantFactoryMethodLinear(result) {
15924
+ return new LinearInterpolant(this.times, this.values, this.getValueSize(), result);
15925
+ }
15926
+ /**
15927
+ * Factory method for creating a new smooth interpolant.
15928
+ *
15929
+ * @static
15930
+ * @param {TypedArray} [result] - The result buffer.
15931
+ * @return {CubicInterpolant} The new interpolant.
15932
+ */
15933
+ InterpolantFactoryMethodSmooth(result) {
15934
+ return new CubicInterpolant(this.times, this.values, this.getValueSize(), result);
15935
+ }
15936
+ /**
15937
+ * Defines the interpolation factor method for this keyframe track.
15938
+ *
15939
+ * @param {(InterpolateLinear|InterpolateDiscrete|InterpolateSmooth)} interpolation - The interpolation type.
15940
+ * @return {KeyframeTrack} A reference to this keyframe track.
15941
+ */
15942
+ setInterpolation(interpolation) {
15943
+ let factoryMethod;
15944
+ switch (interpolation) {
15945
+ case InterpolateDiscrete:
15946
+ factoryMethod = this.InterpolantFactoryMethodDiscrete;
15947
+ break;
15948
+ case InterpolateLinear:
15949
+ factoryMethod = this.InterpolantFactoryMethodLinear;
15950
+ break;
15951
+ case InterpolateSmooth:
15952
+ factoryMethod = this.InterpolantFactoryMethodSmooth;
15953
+ break;
15954
+ }
15955
+ if (factoryMethod === void 0) {
15956
+ const message = "unsupported interpolation for " + this.ValueTypeName + " keyframe track named " + this.name;
15957
+ if (this.createInterpolant === void 0) {
15958
+ if (interpolation !== this.DefaultInterpolation) {
15959
+ this.setInterpolation(this.DefaultInterpolation);
15960
+ } else {
15961
+ throw new Error(message);
15962
+ }
15963
+ }
15964
+ console.warn("THREE.KeyframeTrack:", message);
15965
+ return this;
15966
+ }
15967
+ this.createInterpolant = factoryMethod;
15968
+ return this;
15969
+ }
15970
+ /**
15971
+ * Returns the current interpolation type.
15972
+ *
15973
+ * @return {(InterpolateLinear|InterpolateDiscrete|InterpolateSmooth)} The interpolation type.
15974
+ */
15975
+ getInterpolation() {
15976
+ switch (this.createInterpolant) {
15977
+ case this.InterpolantFactoryMethodDiscrete:
15978
+ return InterpolateDiscrete;
15979
+ case this.InterpolantFactoryMethodLinear:
15980
+ return InterpolateLinear;
15981
+ case this.InterpolantFactoryMethodSmooth:
15982
+ return InterpolateSmooth;
15983
+ }
15984
+ }
15985
+ /**
15986
+ * Returns the value size.
15987
+ *
15988
+ * @return {number} The value size.
15989
+ */
15990
+ getValueSize() {
15991
+ return this.values.length / this.times.length;
15992
+ }
15993
+ /**
15994
+ * Moves all keyframes either forward or backward in time.
15995
+ *
15996
+ * @param {number} timeOffset - The offset to move the time values.
15997
+ * @return {KeyframeTrack} A reference to this keyframe track.
15998
+ */
15999
+ shift(timeOffset) {
16000
+ if (timeOffset !== 0) {
16001
+ const times = this.times;
16002
+ for (let i = 0, n = times.length; i !== n; ++i) {
16003
+ times[i] += timeOffset;
16004
+ }
16005
+ }
16006
+ return this;
16007
+ }
16008
+ /**
16009
+ * Scale all keyframe times by a factor (useful for frame - seconds conversions).
16010
+ *
16011
+ * @param {number} timeScale - The time scale.
16012
+ * @return {KeyframeTrack} A reference to this keyframe track.
16013
+ */
16014
+ scale(timeScale) {
16015
+ if (timeScale !== 1) {
16016
+ const times = this.times;
16017
+ for (let i = 0, n = times.length; i !== n; ++i) {
16018
+ times[i] *= timeScale;
16019
+ }
16020
+ }
16021
+ return this;
16022
+ }
16023
+ /**
16024
+ * Removes keyframes before and after animation without changing any values within the defined time range.
16025
+ *
16026
+ * Note: The method does not shift around keys to the start of the track time, because for interpolated
16027
+ * keys this will change their values
16028
+ *
16029
+ * @param {number} startTime - The start time.
16030
+ * @param {number} endTime - The end time.
16031
+ * @return {KeyframeTrack} A reference to this keyframe track.
16032
+ */
16033
+ trim(startTime, endTime) {
16034
+ const times = this.times, nKeys = times.length;
16035
+ let from = 0, to = nKeys - 1;
16036
+ while (from !== nKeys && times[from] < startTime) {
16037
+ ++from;
16038
+ }
16039
+ while (to !== -1 && times[to] > endTime) {
16040
+ --to;
16041
+ }
16042
+ ++to;
16043
+ if (from !== 0 || to !== nKeys) {
16044
+ if (from >= to) {
16045
+ to = Math.max(to, 1);
16046
+ from = to - 1;
16047
+ }
16048
+ const stride = this.getValueSize();
16049
+ this.times = times.slice(from, to);
16050
+ this.values = this.values.slice(from * stride, to * stride);
16051
+ }
16052
+ return this;
16053
+ }
16054
+ /**
16055
+ * Performs minimal validation on the keyframe track. Returns `true` if the values
16056
+ * are valid.
16057
+ *
16058
+ * @return {boolean} Whether the keyframes are valid or not.
16059
+ */
16060
+ validate() {
16061
+ let valid = true;
16062
+ const valueSize = this.getValueSize();
16063
+ if (valueSize - Math.floor(valueSize) !== 0) {
16064
+ console.error("THREE.KeyframeTrack: Invalid value size in track.", this);
16065
+ valid = false;
16066
+ }
16067
+ const times = this.times, values = this.values, nKeys = times.length;
16068
+ if (nKeys === 0) {
16069
+ console.error("THREE.KeyframeTrack: Track is empty.", this);
16070
+ valid = false;
16071
+ }
16072
+ let prevTime = null;
16073
+ for (let i = 0; i !== nKeys; i++) {
16074
+ const currTime = times[i];
16075
+ if (typeof currTime === "number" && isNaN(currTime)) {
16076
+ console.error("THREE.KeyframeTrack: Time is not a valid number.", this, i, currTime);
16077
+ valid = false;
16078
+ break;
16079
+ }
16080
+ if (prevTime !== null && prevTime > currTime) {
16081
+ console.error("THREE.KeyframeTrack: Out of order keys.", this, i, currTime, prevTime);
16082
+ valid = false;
16083
+ break;
16084
+ }
16085
+ prevTime = currTime;
16086
+ }
16087
+ if (values !== void 0) {
16088
+ if (isTypedArray(values)) {
16089
+ for (let i = 0, n = values.length; i !== n; ++i) {
16090
+ const value = values[i];
16091
+ if (isNaN(value)) {
16092
+ console.error("THREE.KeyframeTrack: Value is not a valid number.", this, i, value);
16093
+ valid = false;
16094
+ break;
16095
+ }
16096
+ }
16097
+ }
16098
+ }
16099
+ return valid;
16100
+ }
16101
+ /**
16102
+ * Optimizes this keyframe track by removing equivalent sequential keys (which are
16103
+ * common in morph target sequences).
16104
+ *
16105
+ * @return {AnimationClip} A reference to this animation clip.
16106
+ */
16107
+ optimize() {
16108
+ const times = this.times.slice(), values = this.values.slice(), stride = this.getValueSize(), smoothInterpolation = this.getInterpolation() === InterpolateSmooth, lastIndex = times.length - 1;
16109
+ let writeIndex = 1;
16110
+ for (let i = 1; i < lastIndex; ++i) {
16111
+ let keep = false;
16112
+ const time2 = times[i];
16113
+ const timeNext = times[i + 1];
16114
+ if (time2 !== timeNext && (i !== 1 || time2 !== times[0])) {
16115
+ if (!smoothInterpolation) {
16116
+ const offset = i * stride, offsetP = offset - stride, offsetN = offset + stride;
16117
+ for (let j = 0; j !== stride; ++j) {
16118
+ const value = values[offset + j];
16119
+ if (value !== values[offsetP + j] || value !== values[offsetN + j]) {
16120
+ keep = true;
16121
+ break;
16122
+ }
16123
+ }
16124
+ } else {
16125
+ keep = true;
16126
+ }
16127
+ }
16128
+ if (keep) {
16129
+ if (i !== writeIndex) {
16130
+ times[writeIndex] = times[i];
16131
+ const readOffset = i * stride, writeOffset = writeIndex * stride;
16132
+ for (let j = 0; j !== stride; ++j) {
16133
+ values[writeOffset + j] = values[readOffset + j];
16134
+ }
16135
+ }
16136
+ ++writeIndex;
16137
+ }
16138
+ }
16139
+ if (lastIndex > 0) {
16140
+ times[writeIndex] = times[lastIndex];
16141
+ for (let readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++j) {
16142
+ values[writeOffset + j] = values[readOffset + j];
16143
+ }
16144
+ ++writeIndex;
16145
+ }
16146
+ if (writeIndex !== times.length) {
16147
+ this.times = times.slice(0, writeIndex);
16148
+ this.values = values.slice(0, writeIndex * stride);
16149
+ } else {
16150
+ this.times = times;
16151
+ this.values = values;
16152
+ }
16153
+ return this;
16154
+ }
16155
+ /**
16156
+ * Returns a new keyframe track with copied values from this instance.
16157
+ *
16158
+ * @return {KeyframeTrack} A clone of this instance.
16159
+ */
16160
+ clone() {
16161
+ const times = this.times.slice();
16162
+ const values = this.values.slice();
16163
+ const TypedKeyframeTrack = this.constructor;
16164
+ const track = new TypedKeyframeTrack(this.name, times, values);
16165
+ track.createInterpolant = this.createInterpolant;
16166
+ return track;
16167
+ }
16168
+ }
16169
+ KeyframeTrack.prototype.ValueTypeName = "";
16170
+ KeyframeTrack.prototype.TimeBufferType = Float32Array;
16171
+ KeyframeTrack.prototype.ValueBufferType = Float32Array;
16172
+ KeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear;
16173
+ class BooleanKeyframeTrack extends KeyframeTrack {
16174
+ /**
16175
+ * Constructs a new boolean keyframe track.
16176
+ *
16177
+ * This keyframe track type has no `interpolation` parameter because the
16178
+ * interpolation is always discrete.
16179
+ *
16180
+ * @param {string} name - The keyframe track's name.
16181
+ * @param {Array<number>} times - A list of keyframe times.
16182
+ * @param {Array<boolean>} values - A list of keyframe values.
16183
+ */
16184
+ constructor(name, times, values) {
16185
+ super(name, times, values);
16186
+ }
16187
+ }
16188
+ BooleanKeyframeTrack.prototype.ValueTypeName = "bool";
16189
+ BooleanKeyframeTrack.prototype.ValueBufferType = Array;
16190
+ BooleanKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete;
16191
+ BooleanKeyframeTrack.prototype.InterpolantFactoryMethodLinear = void 0;
16192
+ BooleanKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = void 0;
16193
+ class ColorKeyframeTrack extends KeyframeTrack {
16194
+ /**
16195
+ * Constructs a new color keyframe track.
16196
+ *
16197
+ * @param {string} name - The keyframe track's name.
16198
+ * @param {Array<number>} times - A list of keyframe times.
16199
+ * @param {Array<number>} values - A list of keyframe values.
16200
+ * @param {(InterpolateLinear|InterpolateDiscrete|InterpolateSmooth)} [interpolation] - The interpolation type.
16201
+ */
16202
+ constructor(name, times, values, interpolation) {
16203
+ super(name, times, values, interpolation);
16204
+ }
16205
+ }
16206
+ ColorKeyframeTrack.prototype.ValueTypeName = "color";
16207
+ class NumberKeyframeTrack extends KeyframeTrack {
16208
+ /**
16209
+ * Constructs a new number keyframe track.
16210
+ *
16211
+ * @param {string} name - The keyframe track's name.
16212
+ * @param {Array<number>} times - A list of keyframe times.
16213
+ * @param {Array<number>} values - A list of keyframe values.
16214
+ * @param {(InterpolateLinear|InterpolateDiscrete|InterpolateSmooth)} [interpolation] - The interpolation type.
16215
+ */
16216
+ constructor(name, times, values, interpolation) {
16217
+ super(name, times, values, interpolation);
16218
+ }
16219
+ }
16220
+ NumberKeyframeTrack.prototype.ValueTypeName = "number";
16221
+ class QuaternionLinearInterpolant extends Interpolant {
16222
+ /**
16223
+ * Constructs a new SLERP interpolant.
16224
+ *
16225
+ * @param {TypedArray} parameterPositions - The parameter positions hold the interpolation factors.
16226
+ * @param {TypedArray} sampleValues - The sample values.
16227
+ * @param {number} sampleSize - The sample size
16228
+ * @param {TypedArray} [resultBuffer] - The result buffer.
16229
+ */
16230
+ constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) {
16231
+ super(parameterPositions, sampleValues, sampleSize, resultBuffer);
16232
+ }
16233
+ interpolate_(i1, t0, t, t1) {
16234
+ const result = this.resultBuffer, values = this.sampleValues, stride = this.valueSize, alpha = (t - t0) / (t1 - t0);
16235
+ let offset = i1 * stride;
16236
+ for (let end = offset + stride; offset !== end; offset += 4) {
16237
+ Quaternion.slerpFlat(result, 0, values, offset - stride, values, offset, alpha);
16238
+ }
16239
+ return result;
16240
+ }
16241
+ }
16242
+ class QuaternionKeyframeTrack extends KeyframeTrack {
16243
+ /**
16244
+ * Constructs a new Quaternion keyframe track.
16245
+ *
16246
+ * @param {string} name - The keyframe track's name.
16247
+ * @param {Array<number>} times - A list of keyframe times.
16248
+ * @param {Array<number>} values - A list of keyframe values.
16249
+ * @param {(InterpolateLinear|InterpolateDiscrete|InterpolateSmooth)} [interpolation] - The interpolation type.
16250
+ */
16251
+ constructor(name, times, values, interpolation) {
16252
+ super(name, times, values, interpolation);
16253
+ }
16254
+ /**
16255
+ * Overwritten so the method returns Quaternion based interpolant.
16256
+ *
16257
+ * @static
16258
+ * @param {TypedArray} [result] - The result buffer.
16259
+ * @return {QuaternionLinearInterpolant} The new interpolant.
16260
+ */
16261
+ InterpolantFactoryMethodLinear(result) {
16262
+ return new QuaternionLinearInterpolant(this.times, this.values, this.getValueSize(), result);
16263
+ }
16264
+ }
16265
+ QuaternionKeyframeTrack.prototype.ValueTypeName = "quaternion";
16266
+ QuaternionKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = void 0;
16267
+ class StringKeyframeTrack extends KeyframeTrack {
16268
+ /**
16269
+ * Constructs a new string keyframe track.
16270
+ *
16271
+ * This keyframe track type has no `interpolation` parameter because the
16272
+ * interpolation is always discrete.
16273
+ *
16274
+ * @param {string} name - The keyframe track's name.
16275
+ * @param {Array<number>} times - A list of keyframe times.
16276
+ * @param {Array<string>} values - A list of keyframe values.
16277
+ */
16278
+ constructor(name, times, values) {
16279
+ super(name, times, values);
16280
+ }
16281
+ }
16282
+ StringKeyframeTrack.prototype.ValueTypeName = "string";
16283
+ StringKeyframeTrack.prototype.ValueBufferType = Array;
16284
+ StringKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete;
16285
+ StringKeyframeTrack.prototype.InterpolantFactoryMethodLinear = void 0;
16286
+ StringKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = void 0;
16287
+ class VectorKeyframeTrack extends KeyframeTrack {
16288
+ /**
16289
+ * Constructs a new vector keyframe track.
16290
+ *
16291
+ * @param {string} name - The keyframe track's name.
16292
+ * @param {Array<number>} times - A list of keyframe times.
16293
+ * @param {Array<number>} values - A list of keyframe values.
16294
+ * @param {(InterpolateLinear|InterpolateDiscrete|InterpolateSmooth)} [interpolation] - The interpolation type.
16295
+ */
16296
+ constructor(name, times, values, interpolation) {
16297
+ super(name, times, values, interpolation);
16298
+ }
16299
+ }
16300
+ VectorKeyframeTrack.prototype.ValueTypeName = "vector";
16301
+ class AnimationClip {
16302
+ /**
16303
+ * Constructs a new animation clip.
16304
+ *
16305
+ * Note: Instead of instantiating an AnimationClip directly with the constructor, you can
16306
+ * use the static interface of this class for creating clips. In most cases though, animation clips
16307
+ * will automatically be created by loaders when importing animated 3D assets.
16308
+ *
16309
+ * @param {string} [name=''] - The clip's name.
16310
+ * @param {number} [duration=-1] - The clip's duration in seconds. If a negative value is passed,
16311
+ * the duration will be calculated from the passed keyframes.
16312
+ * @param {Array<KeyframeTrack>} tracks - An array of keyframe tracks.
16313
+ * @param {(NormalAnimationBlendMode|AdditiveAnimationBlendMode)} [blendMode=NormalAnimationBlendMode] - Defines how the animation
16314
+ * is blended/combined when two or more animations are simultaneously played.
16315
+ */
16316
+ constructor(name = "", duration = -1, tracks = [], blendMode = NormalAnimationBlendMode) {
16317
+ this.name = name;
16318
+ this.tracks = tracks;
16319
+ this.duration = duration;
16320
+ this.blendMode = blendMode;
16321
+ this.uuid = generateUUID();
16322
+ this.userData = {};
16323
+ if (this.duration < 0) {
16324
+ this.resetDuration();
16325
+ }
16326
+ }
16327
+ /**
16328
+ * Factory method for creating an animation clip from the given JSON.
16329
+ *
16330
+ * @static
16331
+ * @param {Object} json - The serialized animation clip.
16332
+ * @return {AnimationClip} The new animation clip.
16333
+ */
16334
+ static parse(json) {
16335
+ const tracks = [], jsonTracks = json.tracks, frameTime = 1 / (json.fps || 1);
16336
+ for (let i = 0, n = jsonTracks.length; i !== n; ++i) {
16337
+ tracks.push(parseKeyframeTrack(jsonTracks[i]).scale(frameTime));
16338
+ }
16339
+ const clip = new this(json.name, json.duration, tracks, json.blendMode);
16340
+ clip.uuid = json.uuid;
16341
+ clip.userData = JSON.parse(json.userData || "{}");
16342
+ return clip;
16343
+ }
16344
+ /**
16345
+ * Serializes the given animation clip into JSON.
16346
+ *
16347
+ * @static
16348
+ * @param {AnimationClip} clip - The animation clip to serialize.
16349
+ * @return {Object} The JSON object.
16350
+ */
16351
+ static toJSON(clip) {
16352
+ const tracks = [], clipTracks = clip.tracks;
16353
+ const json = {
16354
+ "name": clip.name,
16355
+ "duration": clip.duration,
16356
+ "tracks": tracks,
16357
+ "uuid": clip.uuid,
16358
+ "blendMode": clip.blendMode,
16359
+ "userData": JSON.stringify(clip.userData)
16360
+ };
16361
+ for (let i = 0, n = clipTracks.length; i !== n; ++i) {
16362
+ tracks.push(KeyframeTrack.toJSON(clipTracks[i]));
16363
+ }
16364
+ return json;
16365
+ }
16366
+ /**
16367
+ * Returns a new animation clip from the passed morph targets array of a
16368
+ * geometry, taking a name and the number of frames per second.
16369
+ *
16370
+ * Note: The fps parameter is required, but the animation speed can be
16371
+ * overridden via {@link AnimationAction#setDuration}.
16372
+ *
16373
+ * @static
16374
+ * @param {string} name - The name of the animation clip.
16375
+ * @param {Array<Object>} morphTargetSequence - A sequence of morph targets.
16376
+ * @param {number} fps - The Frames-Per-Second value.
16377
+ * @param {boolean} noLoop - Whether the clip should be no loop or not.
16378
+ * @return {AnimationClip} The new animation clip.
16379
+ */
16380
+ static CreateFromMorphTargetSequence(name, morphTargetSequence, fps, noLoop) {
16381
+ const numMorphTargets = morphTargetSequence.length;
16382
+ const tracks = [];
16383
+ for (let i = 0; i < numMorphTargets; i++) {
16384
+ let times = [];
16385
+ let values = [];
16386
+ times.push(
16387
+ (i + numMorphTargets - 1) % numMorphTargets,
16388
+ i,
16389
+ (i + 1) % numMorphTargets
16390
+ );
16391
+ values.push(0, 1, 0);
16392
+ const order = getKeyframeOrder(times);
16393
+ times = sortedArray(times, 1, order);
16394
+ values = sortedArray(values, 1, order);
16395
+ if (!noLoop && times[0] === 0) {
16396
+ times.push(numMorphTargets);
16397
+ values.push(values[0]);
16398
+ }
16399
+ tracks.push(
16400
+ new NumberKeyframeTrack(
16401
+ ".morphTargetInfluences[" + morphTargetSequence[i].name + "]",
16402
+ times,
16403
+ values
16404
+ ).scale(1 / fps)
16405
+ );
16406
+ }
16407
+ return new this(name, -1, tracks);
16408
+ }
16409
+ /**
16410
+ * Searches for an animation clip by name, taking as its first parameter
16411
+ * either an array of clips, or a mesh or geometry that contains an
16412
+ * array named "animations" property.
16413
+ *
16414
+ * @static
16415
+ * @param {(Array<AnimationClip>|Object3D)} objectOrClipArray - The array or object to search through.
16416
+ * @param {string} name - The name to search for.
16417
+ * @return {?AnimationClip} The found animation clip. Returns `null` if no clip has been found.
16418
+ */
16419
+ static findByName(objectOrClipArray, name) {
16420
+ let clipArray = objectOrClipArray;
16421
+ if (!Array.isArray(objectOrClipArray)) {
16422
+ const o = objectOrClipArray;
16423
+ clipArray = o.geometry && o.geometry.animations || o.animations;
16424
+ }
16425
+ for (let i = 0; i < clipArray.length; i++) {
16426
+ if (clipArray[i].name === name) {
16427
+ return clipArray[i];
16428
+ }
16429
+ }
16430
+ return null;
16431
+ }
16432
+ /**
16433
+ * Returns an array of new AnimationClips created from the morph target
16434
+ * sequences of a geometry, trying to sort morph target names into
16435
+ * animation-group-based patterns like "Walk_001, Walk_002, Run_001, Run_002...".
16436
+ *
16437
+ * See {@link MD2Loader#parse} as an example for how the method should be used.
16438
+ *
16439
+ * @static
16440
+ * @param {Array<Object>} morphTargets - A sequence of morph targets.
16441
+ * @param {number} fps - The Frames-Per-Second value.
16442
+ * @param {boolean} noLoop - Whether the clip should be no loop or not.
16443
+ * @return {Array<AnimationClip>} An array of new animation clips.
16444
+ */
16445
+ static CreateClipsFromMorphTargetSequences(morphTargets, fps, noLoop) {
16446
+ const animationToMorphTargets = {};
16447
+ const pattern = /^([\w-]*?)([\d]+)$/;
16448
+ for (let i = 0, il = morphTargets.length; i < il; i++) {
16449
+ const morphTarget = morphTargets[i];
16450
+ const parts = morphTarget.name.match(pattern);
16451
+ if (parts && parts.length > 1) {
16452
+ const name = parts[1];
16453
+ let animationMorphTargets = animationToMorphTargets[name];
16454
+ if (!animationMorphTargets) {
16455
+ animationToMorphTargets[name] = animationMorphTargets = [];
16456
+ }
16457
+ animationMorphTargets.push(morphTarget);
16458
+ }
16459
+ }
16460
+ const clips = [];
16461
+ for (const name in animationToMorphTargets) {
16462
+ clips.push(this.CreateFromMorphTargetSequence(name, animationToMorphTargets[name], fps, noLoop));
16463
+ }
16464
+ return clips;
16465
+ }
16466
+ /**
16467
+ * Parses the `animation.hierarchy` format and returns a new animation clip.
16468
+ *
16469
+ * @static
16470
+ * @deprecated since r175.
16471
+ * @param {Object} animation - A serialized animation clip as JSON.
16472
+ * @param {Array<Bones>} bones - An array of bones.
16473
+ * @return {?AnimationClip} The new animation clip.
16474
+ */
16475
+ static parseAnimation(animation, bones) {
16476
+ console.warn("THREE.AnimationClip: parseAnimation() is deprecated and will be removed with r185");
16477
+ if (!animation) {
16478
+ console.error("THREE.AnimationClip: No animation in JSONLoader data.");
16479
+ return null;
16480
+ }
16481
+ const addNonemptyTrack = function(trackType, trackName, animationKeys, propertyName, destTracks) {
16482
+ if (animationKeys.length !== 0) {
16483
+ const times = [];
16484
+ const values = [];
16485
+ flattenJSON(animationKeys, times, values, propertyName);
16486
+ if (times.length !== 0) {
16487
+ destTracks.push(new trackType(trackName, times, values));
16488
+ }
16489
+ }
16490
+ };
16491
+ const tracks = [];
16492
+ const clipName = animation.name || "default";
16493
+ const fps = animation.fps || 30;
16494
+ const blendMode = animation.blendMode;
16495
+ let duration = animation.length || -1;
16496
+ const hierarchyTracks = animation.hierarchy || [];
16497
+ for (let h = 0; h < hierarchyTracks.length; h++) {
16498
+ const animationKeys = hierarchyTracks[h].keys;
16499
+ if (!animationKeys || animationKeys.length === 0) continue;
16500
+ if (animationKeys[0].morphTargets) {
16501
+ const morphTargetNames = {};
16502
+ let k;
16503
+ for (k = 0; k < animationKeys.length; k++) {
16504
+ if (animationKeys[k].morphTargets) {
16505
+ for (let m = 0; m < animationKeys[k].morphTargets.length; m++) {
16506
+ morphTargetNames[animationKeys[k].morphTargets[m]] = -1;
16507
+ }
16508
+ }
16509
+ }
16510
+ for (const morphTargetName in morphTargetNames) {
16511
+ const times = [];
16512
+ const values = [];
16513
+ for (let m = 0; m !== animationKeys[k].morphTargets.length; ++m) {
16514
+ const animationKey = animationKeys[k];
16515
+ times.push(animationKey.time);
16516
+ values.push(animationKey.morphTarget === morphTargetName ? 1 : 0);
16517
+ }
16518
+ tracks.push(new NumberKeyframeTrack(".morphTargetInfluence[" + morphTargetName + "]", times, values));
16519
+ }
16520
+ duration = morphTargetNames.length * fps;
16521
+ } else {
16522
+ const boneName = ".bones[" + bones[h].name + "]";
16523
+ addNonemptyTrack(
16524
+ VectorKeyframeTrack,
16525
+ boneName + ".position",
16526
+ animationKeys,
16527
+ "pos",
16528
+ tracks
16529
+ );
16530
+ addNonemptyTrack(
16531
+ QuaternionKeyframeTrack,
16532
+ boneName + ".quaternion",
16533
+ animationKeys,
16534
+ "rot",
16535
+ tracks
16536
+ );
16537
+ addNonemptyTrack(
16538
+ VectorKeyframeTrack,
16539
+ boneName + ".scale",
16540
+ animationKeys,
16541
+ "scl",
16542
+ tracks
16543
+ );
16544
+ }
16545
+ }
16546
+ if (tracks.length === 0) {
16547
+ return null;
16548
+ }
16549
+ const clip = new this(clipName, duration, tracks, blendMode);
16550
+ return clip;
16551
+ }
16552
+ /**
16553
+ * Sets the duration of this clip to the duration of its longest keyframe track.
16554
+ *
16555
+ * @return {AnimationClip} A reference to this animation clip.
16556
+ */
16557
+ resetDuration() {
16558
+ const tracks = this.tracks;
16559
+ let duration = 0;
16560
+ for (let i = 0, n = tracks.length; i !== n; ++i) {
16561
+ const track = this.tracks[i];
16562
+ duration = Math.max(duration, track.times[track.times.length - 1]);
16563
+ }
16564
+ this.duration = duration;
16565
+ return this;
16566
+ }
16567
+ /**
16568
+ * Trims all tracks to the clip's duration.
16569
+ *
16570
+ * @return {AnimationClip} A reference to this animation clip.
16571
+ */
16572
+ trim() {
16573
+ for (let i = 0; i < this.tracks.length; i++) {
16574
+ this.tracks[i].trim(0, this.duration);
16575
+ }
16576
+ return this;
16577
+ }
16578
+ /**
16579
+ * Performs minimal validation on each track in the clip. Returns `true` if all
16580
+ * tracks are valid.
16581
+ *
16582
+ * @return {boolean} Whether the clip's keyframes are valid or not.
16583
+ */
16584
+ validate() {
16585
+ let valid = true;
16586
+ for (let i = 0; i < this.tracks.length; i++) {
16587
+ valid = valid && this.tracks[i].validate();
16588
+ }
16589
+ return valid;
16590
+ }
16591
+ /**
16592
+ * Optimizes each track by removing equivalent sequential keys (which are
16593
+ * common in morph target sequences).
16594
+ *
16595
+ * @return {AnimationClip} A reference to this animation clip.
16596
+ */
16597
+ optimize() {
16598
+ for (let i = 0; i < this.tracks.length; i++) {
16599
+ this.tracks[i].optimize();
16600
+ }
16601
+ return this;
16602
+ }
16603
+ /**
16604
+ * Returns a new animation clip with copied values from this instance.
16605
+ *
16606
+ * @return {AnimationClip} A clone of this instance.
16607
+ */
16608
+ clone() {
16609
+ const tracks = [];
16610
+ for (let i = 0; i < this.tracks.length; i++) {
16611
+ tracks.push(this.tracks[i].clone());
16612
+ }
16613
+ const clip = new this.constructor(this.name, this.duration, tracks, this.blendMode);
16614
+ clip.userData = JSON.parse(JSON.stringify(this.userData));
16615
+ return clip;
16616
+ }
16617
+ /**
16618
+ * Serializes this animation clip into JSON.
16619
+ *
16620
+ * @return {Object} The JSON object.
16621
+ */
16622
+ toJSON() {
16623
+ return this.constructor.toJSON(this);
16624
+ }
16625
+ }
16626
+ function getTrackTypeForValueTypeName(typeName) {
16627
+ switch (typeName.toLowerCase()) {
16628
+ case "scalar":
16629
+ case "double":
16630
+ case "float":
16631
+ case "number":
16632
+ case "integer":
16633
+ return NumberKeyframeTrack;
16634
+ case "vector":
16635
+ case "vector2":
16636
+ case "vector3":
16637
+ case "vector4":
16638
+ return VectorKeyframeTrack;
16639
+ case "color":
16640
+ return ColorKeyframeTrack;
16641
+ case "quaternion":
16642
+ return QuaternionKeyframeTrack;
16643
+ case "bool":
16644
+ case "boolean":
16645
+ return BooleanKeyframeTrack;
16646
+ case "string":
16647
+ return StringKeyframeTrack;
16648
+ }
16649
+ throw new Error("THREE.KeyframeTrack: Unsupported typeName: " + typeName);
16650
+ }
16651
+ function parseKeyframeTrack(json) {
16652
+ if (json.type === void 0) {
16653
+ throw new Error("THREE.KeyframeTrack: track type undefined, can not parse");
16654
+ }
16655
+ const trackType = getTrackTypeForValueTypeName(json.type);
16656
+ if (json.times === void 0) {
16657
+ const times = [], values = [];
16658
+ flattenJSON(json.keys, times, values, "value");
16659
+ json.times = times;
16660
+ json.values = values;
16661
+ }
16662
+ if (trackType.parse !== void 0) {
16663
+ return trackType.parse(json);
16664
+ } else {
16665
+ return new trackType(json.name, json.times, json.values, json.interpolation);
16666
+ }
16667
+ }
15541
16668
  class Light extends Object3D {
15542
16669
  /**
15543
16670
  * Constructs a new light.
@@ -30421,7 +31548,9 @@ class Event {
30421
31548
  return new Connection(callback, this);
30422
31549
  }
30423
31550
  Fire(...args) {
30424
- for (const callback of this._callbacks) {
31551
+ for (let i = this._callbacks.length - 1; i >= 0; i--) {
31552
+ const callback = this._callbacks[i];
31553
+ if (!callback) return;
30425
31554
  callback(...args);
30426
31555
  }
30427
31556
  }
@@ -30432,7 +31561,9 @@ class Event {
30432
31561
  }
30433
31562
  }
30434
31563
  Clear() {
30435
- for (const callback of this._callbacks) {
31564
+ for (let i = this._callbacks.length - 1; i >= 0; i--) {
31565
+ const callback = this._callbacks[i];
31566
+ if (!callback) return;
30436
31567
  this.Disconnect(callback);
30437
31568
  }
30438
31569
  this._callbacks = [];
@@ -30506,6 +31637,9 @@ class Instance {
30506
31637
  get name() {
30507
31638
  return this.Prop("Name");
30508
31639
  }
31640
+ get Parent() {
31641
+ return this.parent;
31642
+ }
30509
31643
  createWrapper() {
30510
31644
  const wrapper = GetWrapperForInstance(this);
30511
31645
  if (wrapper && !this._hasWrappered) {
@@ -33733,7 +34867,7 @@ class Outfit {
33733
34867
  staticFacialAnimation = true;
33734
34868
  }
33735
34869
  let meta = void 0;
33736
- if (assetOrder !== void 0 || assetPos || assetRot || assetScale || assetHeadShape !== void 0) {
34870
+ if (assetOrder !== void 0 || assetPos || assetRot || assetScale || assetHeadShape !== void 0 || staticFacialAnimation !== void 0) {
33737
34871
  meta = new AssetMeta();
33738
34872
  meta.order = assetOrder;
33739
34873
  meta.position = assetPos;
@@ -36361,11 +37495,15 @@ const API = {
36361
37495
  if (response instanceof ArrayBuffer) {
36362
37496
  const buffer2 = response;
36363
37497
  const mesh = new FileMesh();
36364
- await mesh.fromBuffer(buffer2);
36365
- if (FLAGS.ENABLE_API_CACHE && FLAGS.ENABLE_API_MESH_CACHE) {
36366
- CACHE.Mesh.set(cacheStr, mesh.clone());
37498
+ try {
37499
+ await mesh.fromBuffer(buffer2);
37500
+ if (FLAGS.ENABLE_API_CACHE && FLAGS.ENABLE_API_MESH_CACHE) {
37501
+ CACHE.Mesh.set(cacheStr, mesh.clone());
37502
+ }
37503
+ return mesh;
37504
+ } catch {
37505
+ return new Response();
36367
37506
  }
36368
- return mesh;
36369
37507
  } else {
36370
37508
  return response;
36371
37509
  }
@@ -42738,6 +43876,7 @@ class ModelLayersDesc {
42738
43876
  targetDeformers;
42739
43877
  targetParents;
42740
43878
  layers;
43879
+ destroyConnection;
42741
43880
  //requires compilation
42742
43881
  _targetMeshes;
42743
43882
  uvToHits;
@@ -43017,16 +44156,23 @@ function getModelLayersDesc(model) {
43017
44156
  if (oldLayerDesc && newLayerDesc.isSame(oldLayerDesc)) {
43018
44157
  return oldLayerDesc;
43019
44158
  } else {
44159
+ oldLayerDesc?.destroyConnection?.Disconnect();
43020
44160
  modelLayers.set(model, newLayerDesc);
44161
+ newLayerDesc.destroyConnection = model.Destroying.Connect(() => {
44162
+ modelLayers.delete(model);
44163
+ newLayerDesc.destroyConnection?.Disconnect();
44164
+ newLayerDesc.destroyConnection = void 0;
44165
+ });
43021
44166
  return newLayerDesc;
43022
44167
  }
43023
44168
  }
43024
44169
  const modelHSRDescs = /* @__PURE__ */ new Map();
43025
- const CACHE_uvToHits = /* @__PURE__ */ new Map();
44170
+ const CACHE_uvToHits = new Cache();
43026
44171
  class HSRDesc {
43027
44172
  layers;
43028
44173
  layerTransparent;
43029
44174
  uvsToHits;
44175
+ destroyConnection;
43030
44176
  isSame(other) {
43031
44177
  if (!this.layers && other.layers || this.layers && !other.layers) {
43032
44178
  return false;
@@ -43212,7 +44358,13 @@ function getModelHSRDesc(model) {
43212
44358
  if (oldLayerDesc && newHSRDesc.isSame(oldLayerDesc)) {
43213
44359
  return oldLayerDesc;
43214
44360
  } else {
44361
+ oldLayerDesc?.destroyConnection?.Disconnect();
43215
44362
  modelHSRDescs.set(model, newHSRDesc);
44363
+ newHSRDesc.destroyConnection = model.Destroying.Connect(() => {
44364
+ modelHSRDescs.delete(model);
44365
+ newHSRDesc.destroyConnection?.Disconnect();
44366
+ newHSRDesc.destroyConnection = void 0;
44367
+ });
43216
44368
  return newHSRDesc;
43217
44369
  }
43218
44370
  }
@@ -43266,7 +44418,7 @@ function buildWedge(x, y, z) {
43266
44418
  mesh.coreMesh.increaseFaces(2 * 5);
43267
44419
  let totalVerts = 0;
43268
44420
  let totalFaces = 0;
43269
- totalVerts = addQuad(mesh, totalVerts, totalFaces, [-x, -y, -z], [x, -y, -z], [x, y, z], [-x, y, z], [0, 1, 0], void 0, void 0, void 0, [0, 0], [1, 0], [1, 1], [0, 1]);
44421
+ totalVerts = addQuad(mesh, totalVerts, totalFaces, [-x, -y, -z], [x, -y, -z], [x, y, z], [-x, y, z], normalize([0, 1, -1]), void 0, void 0, void 0, [0, 0], [1, 0], [1, 1], [0, 1]);
43270
44422
  totalFaces += 2;
43271
44423
  totalVerts = addQuad(mesh, totalVerts, totalFaces, [-x, -y, z], [x, -y, z], [x, -y, -z], [-x, -y, -z], [0, -1, 0], void 0, void 0, void 0, [0, 0], [1, 0], [1, 1], [0, 1]);
43272
44424
  totalFaces += 2;
@@ -43277,7 +44429,7 @@ function buildWedge(x, y, z) {
43277
44429
  addQuad(mesh, totalVerts, totalFaces, [x, y, z], [x, -y, -z], [x, -y, -z], [x, -y, z], [1, 0, 0], void 0, void 0, void 0, [0, 0], [1, 0], [1, 1], [0, 1]);
43278
44430
  return mesh;
43279
44431
  }
43280
- const HSR_CACHE = /* @__PURE__ */ new Map();
44432
+ const HSR_CACHE = new Cache();
43281
44433
  function doHSR(totalUvToHits, targetCage, mesh, moveVerts = true, cacheStr) {
43282
44434
  let closestVertIndexArr = void 0;
43283
44435
  if (cacheStr) {
@@ -43785,7 +44937,7 @@ class MeshDesc {
43785
44937
  }
43786
44938
  threeMesh.castShadow = true;
43787
44939
  threeMesh.geometry = geometry;
43788
- threeMesh.name = this.instance?.PropOrDefault("Name", "Mesh");
44940
+ threeMesh.name = this.instance?.PropOrDefault("Name", "Mesh") + "_" + this.instance?.id;
43789
44941
  threeMesh.scale.set(mesh.size[0], mesh.size[1], mesh.size[2]);
43790
44942
  this.compilationTimestamp = Date.now() / 1e3;
43791
44943
  return threeMesh;
@@ -43818,6 +44970,11 @@ class MeshDesc {
43818
44970
  fromPart(child) {
43819
44971
  this.canHaveSkinning = false;
43820
44972
  if (child.className === "WedgePart") this.shape = "wedge";
44973
+ switch (child.PropOrDefault("Shape", PartType.Block)) {
44974
+ case PartType.Wedge:
44975
+ this.shape = "wedge";
44976
+ break;
44977
+ }
43821
44978
  const specialMesh = child.FindFirstChildOfClass("SpecialMesh");
43822
44979
  if (specialMesh) {
43823
44980
  switch (specialMesh.Property("MeshType")) {
@@ -45324,10 +46481,13 @@ const __vite_glob_0_11 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.de
45324
46481
  function diffCFrame(parent, child) {
45325
46482
  return parent.inverse().multiply(child);
45326
46483
  }
46484
+ function getBoneName(bone) {
46485
+ return bone.userData.name || bone.name.split("_").pop();
46486
+ }
45327
46487
  function boneIsChildOf(bone, parentName) {
45328
46488
  let nextParent = bone.parent;
45329
46489
  while (nextParent) {
45330
- if (nextParent.name === parentName) {
46490
+ if (getBoneName(nextParent) === parentName) {
45331
46491
  return true;
45332
46492
  }
45333
46493
  nextParent = nextParent.parent;
@@ -45355,13 +46515,15 @@ class SkeletonDesc {
45355
46515
  const boneArr = [];
45356
46516
  for (let i = 0; i < skinning.bones.length; i++) {
45357
46517
  const threeBone = new Bone();
45358
- threeBone.name = skinning.bones[i].name || "";
45359
- if (threeBone.name === "HumanoidRootNode") {
45360
- threeBone.name = "HumanoidRootPart";
46518
+ let boneName = skinning.bones[i].name || "";
46519
+ if (boneName === "HumanoidRootNode") {
46520
+ boneName = "HumanoidRootPart";
45361
46521
  }
45362
- if (threeBone.name === "root") {
45363
- threeBone.name = "Root";
46522
+ if (boneName === "root") {
46523
+ boneName = "Root";
45364
46524
  }
46525
+ threeBone.name = "Skeleton_" + this.meshDesc.instance?.id + "_" + boneName;
46526
+ threeBone.userData.name = boneName;
45365
46527
  boneArr.push(threeBone);
45366
46528
  }
45367
46529
  this.bones = boneArr;
@@ -45396,9 +46558,10 @@ class SkeletonDesc {
45396
46558
  throw new Error("FileMesh has no root bone");
45397
46559
  } else {
45398
46560
  log(false, rootBone);
45399
- if (rootBone && rootBone.name !== "Root") {
46561
+ if (rootBone && getBoneName(rootBone) !== "Root") {
45400
46562
  const trueRootBone = new Bone();
45401
- trueRootBone.name = "Root";
46563
+ trueRootBone.name = "Skeleton_" + this.meshDesc.instance?.id + "_Root";
46564
+ trueRootBone.userData.name = "Root";
45402
46565
  trueRootBone.position.set(0, 0, 0);
45403
46566
  trueRootBone.rotation.set(0, 0, 0, "YXZ");
45404
46567
  this.boneSourceParts.unshift(void 0);
@@ -45426,7 +46589,7 @@ class SkeletonDesc {
45426
46589
  }
45427
46590
  getBoneWithName(name) {
45428
46591
  for (const bone of this.bones) {
45429
- if (bone.name === name) {
46592
+ if (getBoneName(bone) === name) {
45430
46593
  return bone;
45431
46594
  }
45432
46595
  }
@@ -45475,13 +46638,13 @@ class SkeletonDesc {
45475
46638
  return sourceNode;
45476
46639
  }
45477
46640
  getBoneWorldCFrame(bone, assembly, selfInstance, includeTransform) {
45478
- const node = assembly.getNode(bone.name);
46641
+ const node = assembly.getNode(getBoneName(bone));
45479
46642
  const selfNode = selfInstance.w.GetAssemblyNode();
45480
46643
  const sourceNode = this.getSourceNode(selfNode, bone, assembly);
45481
- if (bone.name === "Root") {
46644
+ if (getBoneName(bone) === "Root") {
45482
46645
  return assembly.traverseCFrame(selfNode, includeTransform, true);
45483
46646
  } else if (node) {
45484
- if (this.meshDesc.wasDeformed && !this.meshDesc.wasAutoSkinned && bone.name === "Head") {
46647
+ if (this.meshDesc.wasDeformed && !this.meshDesc.wasAutoSkinned && getBoneName(bone) === "Head") {
45485
46648
  const ogCF = assembly.traverseCFrame(node, includeTransform, true);
45486
46649
  const connectorOffset = node.getConnectorOffset(includeTransform).inverse();
45487
46650
  connectorOffset.Orientation = [0, 0, 0];
@@ -45498,7 +46661,7 @@ class SkeletonDesc {
45498
46661
  return this.meshDesc.fileMesh?.facs?.faceBoneNames.includes(boneName);
45499
46662
  }
45500
46663
  addFACS(restCF, bone, assembly) {
45501
- const isFACS = this.isFACS(bone.name);
46664
+ const isFACS = this.isFACS(getBoneName(bone));
45502
46665
  if (!isFACS) return restCF;
45503
46666
  const facsMesh = this.meshDesc.fileMesh;
45504
46667
  const facs = this.meshDesc.fileMesh?.facs;
@@ -45513,7 +46676,7 @@ class SkeletonDesc {
45513
46676
  new FaceControlsWrapper(faceControls);
45514
46677
  for (let j = 0; j < facs.faceBoneNames.length; j++) {
45515
46678
  const boneName = facs.faceBoneNames[j];
45516
- if (boneName === bone.name) {
46679
+ if (boneName === getBoneName(bone)) {
45517
46680
  let totalPosition = new Vector32();
45518
46681
  let totalRotation = new Vector32();
45519
46682
  for (let i = 0; i < facs.faceControlNames.length; i++) {
@@ -45576,7 +46739,7 @@ class SkeletonDesc {
45576
46739
  let parentBone = bone.parent;
45577
46740
  if (!(parentBone instanceof Bone)) parentBone = null;
45578
46741
  if (bone && parentBone) {
45579
- if ((boneIsChildOf(bone, "DynamicHead") || bone.name === "DynamicHead") && this.meshDesc.wasDeformed && !this.meshDesc.wasAutoSkinned) {
46742
+ if ((boneIsChildOf(bone, "DynamicHead") || getBoneName(bone) === "DynamicHead") && this.meshDesc.wasDeformed && !this.meshDesc.wasAutoSkinned) {
45580
46743
  const parentBoneWorldCFrame = this.getOriginalWorldCFrameNoChange(parentBone);
45581
46744
  const boneWorldCFrameNoChange = this.getOriginalWorldCFrameNoChange(bone);
45582
46745
  let diffCF = diffCFrame(parentBoneWorldCFrame, boneWorldCFrameNoChange);
@@ -49136,307 +50299,6 @@ const __vite_glob_0_20 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.de
49136
50299
  __proto__: null,
49137
50300
  PartWrapper
49138
50301
  }, Symbol.toStringTag, { value: "Module" }));
49139
- class SoundWrapperData {
49140
- audioContext;
49141
- gainNode;
49142
- buffer;
49143
- playingSource;
49144
- }
49145
- class SoundWrapper extends InstanceWrapper {
49146
- static className = "Sound";
49147
- static requiredProperties = ["Name", "Looped", "Playing", "Volume", "_data"];
49148
- setup() {
49149
- if (!this.instance.HasProperty("Name")) this.instance.addProperty(new Property("Name", DataType.String), this.instance.className);
49150
- if (!this.instance.HasProperty("Looped")) this.instance.addProperty(new Property("Looped", DataType.Bool), false);
49151
- if (!this.instance.HasProperty("Playing")) this.instance.addProperty(new Property("Playing", DataType.Bool), false);
49152
- if (!this.instance.HasProperty("Volume")) this.instance.addProperty(new Property("Volume", DataType.Float32), false);
49153
- if (!this.instance.HasProperty("_data")) this.instance.addProperty(new Property("_data", DataType.NonSerializable), new SoundWrapperData());
49154
- }
49155
- get data() {
49156
- return this.instance.Prop("_data");
49157
- }
49158
- created() {
49159
- if (this.instance.Prop("Playing")) {
49160
- this.Play();
49161
- }
49162
- this.instance.Destroying.Connect(() => {
49163
- if (this.data.playingSource) {
49164
- this.Stop();
49165
- }
49166
- this.data.audioContext = void 0;
49167
- this.data.gainNode = void 0;
49168
- this.data.buffer = void 0;
49169
- });
49170
- }
49171
- _updateVolume() {
49172
- if (this.data.gainNode) {
49173
- if (this.instance.HasProperty("Volume")) {
49174
- const volume = this.instance.Prop("Volume");
49175
- this.data.gainNode.gain.value = volume;
49176
- }
49177
- }
49178
- }
49179
- setPlaying(value) {
49180
- this.instance.setProperty("Playing", value);
49181
- }
49182
- playSource() {
49183
- if (!this.data.audioContext || !this.data.gainNode || !this.data.buffer) return;
49184
- this.data.playingSource = this.data.audioContext.createBufferSource();
49185
- this.data.playingSource.buffer = this.data.buffer;
49186
- this.data.playingSource.connect(this.data.gainNode);
49187
- this.data.gainNode.connect(this.data.audioContext.destination);
49188
- this._updateVolume();
49189
- this.data.playingSource.start(0);
49190
- this.data.playingSource.onended = (() => {
49191
- if (this.instance.Prop("Looped")) {
49192
- this.Play();
49193
- } else {
49194
- this.Stop();
49195
- }
49196
- });
49197
- }
49198
- Play() {
49199
- if (!FLAGS.AUDIO_ENABLED) return;
49200
- this.Stop();
49201
- this.setPlaying(true);
49202
- if (!this.data.audioContext) {
49203
- this.data.audioContext = new AudioContext();
49204
- }
49205
- if (!this.data.gainNode) {
49206
- this.data.gainNode = this.data.audioContext.createGain();
49207
- }
49208
- if (!this.data.buffer) {
49209
- let audioUrl = void 0;
49210
- if (this.instance.HasProperty("SoundId")) {
49211
- audioUrl = this.instance.Prop("SoundId");
49212
- } else if (this.instance.HasProperty("AudioContent")) {
49213
- audioUrl = this.instance.Prop("AudioContent").uri;
49214
- }
49215
- if (audioUrl && audioUrl.length > 0) {
49216
- API.Asset.GetAssetBuffer(audioUrl).then((responseBuffer) => {
49217
- if (responseBuffer instanceof Response || !this.data.audioContext) return;
49218
- const buffer2 = responseBuffer.slice(0);
49219
- this.data.audioContext.decodeAudioData(buffer2).then((decodedData) => {
49220
- if (!this.data.audioContext || !this.data.gainNode) return;
49221
- this.data.buffer = decodedData;
49222
- this.playSource();
49223
- });
49224
- });
49225
- }
49226
- } else if (this.data.buffer) {
49227
- this.playSource();
49228
- }
49229
- }
49230
- Stop() {
49231
- this.setPlaying(false);
49232
- if (this.data.playingSource) {
49233
- this.data.playingSource.stop();
49234
- this.data.playingSource = void 0;
49235
- }
49236
- }
49237
- }
49238
- const __vite_glob_0_22 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
49239
- __proto__: null,
49240
- SoundWrapper
49241
- }, Symbol.toStringTag, { value: "Module" }));
49242
- class ScriptWrapperData {
49243
- shouldStop = false;
49244
- }
49245
- class ScriptWrapper extends InstanceWrapper {
49246
- static className = "Script";
49247
- static requiredProperties = ["Name", "_data"];
49248
- setup() {
49249
- if (!this.instance.HasProperty("Name")) this.instance.addProperty(new Property("Name", DataType.String), this.instance.className);
49250
- if (!this.instance.HasProperty("_data")) this.instance.addProperty(new Property("_data", DataType.NonSerializable), new ScriptWrapperData());
49251
- }
49252
- get data() {
49253
- return this.instance.Prop("_data");
49254
- }
49255
- created() {
49256
- this.Run();
49257
- }
49258
- Run() {
49259
- switch (this.instance.Prop("Name")) {
49260
- case "ChickenSounds":
49261
- case "HarmonicaSounds":
49262
- case "SoundPlayer":
49263
- this.SoundPlayer(this.instance);
49264
- break;
49265
- }
49266
- }
49267
- //Scripts
49268
- async SoundPlayer(script) {
49269
- let Handle = void 0;
49270
- if (script.parent && script.parent.Prop("Name") === "Handle") {
49271
- Handle = script.parent;
49272
- } else if (script.parent && script.parent.FindFirstChild("Handle")) {
49273
- Handle = script.parent.FindFirstChild("Handle");
49274
- }
49275
- if (!Handle) return;
49276
- const Hat = Handle.parent;
49277
- if (!Hat) return;
49278
- const Sounds = [];
49279
- for (const child of Handle.GetDescendants()) {
49280
- if (child.className === "Sound") {
49281
- Sounds.push(child);
49282
- }
49283
- }
49284
- function IsBeingWorn() {
49285
- return Hat?.parent?.FindFirstChild("Humanoid");
49286
- }
49287
- let maxTime = 20;
49288
- if (script.Prop("Name") === "SoundPlayer") {
49289
- maxTime = 15;
49290
- }
49291
- while (true) {
49292
- await Wait(mathRandom(5, maxTime));
49293
- if (this.instance.destroyed || this.data.shouldStop) return;
49294
- if (IsBeingWorn()) {
49295
- const index = mathRandom(0, Sounds.length - 1);
49296
- const Sound = Sounds[index];
49297
- const soundWrapper = new SoundWrapper(Sound);
49298
- soundWrapper.Play();
49299
- }
49300
- }
49301
- }
49302
- }
49303
- const __vite_glob_0_21 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
49304
- __proto__: null,
49305
- ScriptWrapper
49306
- }, Symbol.toStringTag, { value: "Module" }));
49307
- class ToolWrapper extends InstanceWrapper {
49308
- static className = "Tool";
49309
- static requiredProperties = [
49310
- "Name",
49311
- "Grip"
49312
- ];
49313
- setup() {
49314
- if (!this.instance.HasProperty("Name")) this.instance.addProperty(new Property("Name", DataType.String), this.instance.className);
49315
- if (!this.instance.HasProperty("Grip")) this.instance.addProperty(new Property("Grip", DataType.CFrame), new CFrame());
49316
- }
49317
- created() {
49318
- this.instance.AncestryChanged.Connect(() => {
49319
- this.createWeld();
49320
- });
49321
- }
49322
- //doing this is actually inaccurate because tools dont create welds, but its easier
49323
- createWeld() {
49324
- const handle = this.instance.FindFirstChild("Handle");
49325
- const rig = this.instance.parent;
49326
- const grip = this.instance.PropOrDefault("Grip", new CFrame()).clone();
49327
- if (handle) {
49328
- const oldToolWeld = handle.FindFirstChild("ToolWeld_GripRoAvatar");
49329
- if (oldToolWeld) {
49330
- oldToolWeld.Destroy();
49331
- }
49332
- }
49333
- const humanoid = rig?.FindFirstChildOfClass("Humanoid");
49334
- if (handle && rig && rig.className === "Model" && humanoid) {
49335
- const rightHand = rig.FindFirstChild("RightHand") || rig.FindFirstChild("Right Arm");
49336
- if (rightHand) {
49337
- for (const child of rightHand.GetDescendants()) {
49338
- if (child.Prop("Name") === "RightGripAttachment") {
49339
- const rightGripAttCF = child.PropOrDefault("CFrame", new CFrame()).clone();
49340
- if (humanoid.Prop("RigType") === HumanoidRigType.R6) {
49341
- rightGripAttCF.Orientation[0] -= 90;
49342
- }
49343
- const weld = new Instance("Weld");
49344
- weld.addProperty(new Property("Name", DataType.String), "ToolWeld_GripRoAvatar");
49345
- weld.addProperty(new Property("Archivable", DataType.Bool), true);
49346
- weld.addProperty(new Property("C0", DataType.CFrame), rightGripAttCF);
49347
- weld.addProperty(new Property("C1", DataType.CFrame), grip);
49348
- weld.addProperty(new Property("Part0", DataType.Referent), child.parent);
49349
- weld.addProperty(new Property("Part1", DataType.Referent), handle);
49350
- weld.addProperty(new Property("Active", DataType.Bool), true);
49351
- weld.addProperty(new Property("Enabled", DataType.Bool), false);
49352
- weld.setParent(handle);
49353
- weld.setProperty("Enabled", true);
49354
- }
49355
- }
49356
- }
49357
- }
49358
- }
49359
- }
49360
- const __vite_glob_0_23 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
49361
- __proto__: null,
49362
- ToolWrapper
49363
- }, Symbol.toStringTag, { value: "Module" }));
49364
- class WedgePartWrapper extends BasePartWrapper {
49365
- static className = "WedgePart";
49366
- }
49367
- const __vite_glob_0_24 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
49368
- __proto__: null,
49369
- WedgePartWrapper
49370
- }, Symbol.toStringTag, { value: "Module" }));
49371
- class WeldWrapper extends JointInstanceWrapper {
49372
- static className = "Weld";
49373
- }
49374
- const __vite_glob_0_25 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
49375
- __proto__: null,
49376
- WeldWrapper
49377
- }, Symbol.toStringTag, { value: "Module" }));
49378
- const modules$1 = /* @__PURE__ */ Object.assign({ "./instance/Accessory.ts": __vite_glob_0_0$1, "./instance/AccessoryDescription.ts": __vite_glob_0_1$1, "./instance/AnimationConstraint.ts": __vite_glob_0_2$1, "./instance/Animator.ts": __vite_glob_0_3, "./instance/Attachment.ts": __vite_glob_0_4, "./instance/BasePart.ts": __vite_glob_0_5, "./instance/BodyColors.ts": __vite_glob_0_6, "./instance/BodyPartDescription.ts": __vite_glob_0_7, "./instance/Bone.ts": __vite_glob_0_8, "./instance/Constraint.ts": __vite_glob_0_9, "./instance/Decal.ts": __vite_glob_0_10, "./instance/FaceControls.ts": __vite_glob_0_11, "./instance/HumanoidDescription.ts": __vite_glob_0_12, "./instance/InstanceWrapper.ts": __vite_glob_0_13, "./instance/JointInstance.ts": __vite_glob_0_14, "./instance/MakeupDescription.ts": __vite_glob_0_15, "./instance/ManualWeld.ts": __vite_glob_0_16, "./instance/MeshPart.ts": __vite_glob_0_17, "./instance/Model.ts": __vite_glob_0_18, "./instance/Motor6D.ts": __vite_glob_0_19, "./instance/Part.ts": __vite_glob_0_20, "./instance/Script.ts": __vite_glob_0_21, "./instance/Sound.ts": __vite_glob_0_22, "./instance/Tool.ts": __vite_glob_0_23, "./instance/WedgePart.ts": __vite_glob_0_24, "./instance/Weld.ts": __vite_glob_0_25 });
49379
- function RegisterWrappers() {
49380
- for (const module of Object.values(modules$1)) {
49381
- for (const exprt of Object.values(module)) {
49382
- let prototype = Object.getPrototypeOf(exprt);
49383
- while (prototype) {
49384
- if (prototype === InstanceWrapper) {
49385
- exprt.register();
49386
- break;
49387
- }
49388
- prototype = Object.getPrototypeOf(prototype);
49389
- }
49390
- }
49391
- }
49392
- }
49393
- const attachmentGeometry = new SphereGeometry(0.125, 16, 8);
49394
- class AttachmentDesc extends RenderDesc {
49395
- static classTypes = ["Attachment"];
49396
- visible = false;
49397
- cframe = new CFrame();
49398
- isSame(other) {
49399
- return this.visible === other.visible && this.cframe.isSame(other.cframe);
49400
- }
49401
- needsRegeneration(other) {
49402
- return this.visible !== other.visible;
49403
- }
49404
- virtualFromRenderDesc(other) {
49405
- this.cframe = other.cframe.clone();
49406
- }
49407
- fromInstance(child) {
49408
- const attachmentW = new AttachmentWrapper(child);
49409
- this.cframe = attachmentW.getWorldCFrame();
49410
- this.visible = child.PropOrDefault("Visible", this.visible) || FLAGS.ALWAYS_SHOW_ATTACHMENTS;
49411
- }
49412
- async compileResults() {
49413
- this.results = [];
49414
- if (this.visible) {
49415
- const mesh = new Mesh(attachmentGeometry, new MeshLambertMaterial({ color: 65280 }));
49416
- mesh.name = this.instance ? this.instance.PropOrDefault("Name", "Unknown") + "_Att" : "Unknown_Att";
49417
- this.results.push(mesh);
49418
- }
49419
- this.updateResults();
49420
- return this.results;
49421
- }
49422
- updateResults() {
49423
- if (!this.results) return;
49424
- for (const attachment of this.results) {
49425
- const resultCF = this.cframe;
49426
- setTHREEObjectCF(attachment, resultCF);
49427
- }
49428
- }
49429
- dispose(_renderer, scene) {
49430
- if (!this.results) return;
49431
- for (const result of this.results) {
49432
- scene.remove(result);
49433
- }
49434
- }
49435
- }
49436
- const __vite_glob_0_0 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
49437
- __proto__: null,
49438
- AttachmentDesc
49439
- }, Symbol.toStringTag, { value: "Module" }));
49440
50302
  const particle_vertexShader = (
49441
50303
  /*glsl*/
49442
50304
  `
@@ -49894,8 +50756,8 @@ class EmitterDesc extends DisposableDesc {
49894
50756
  }
49895
50757
  return this.result;
49896
50758
  }
49897
- emit(groupDesc) {
49898
- if (this.particles.length >= this.maxCount || groupDesc.enabled === false) {
50759
+ emit(groupDesc, force = false) {
50760
+ if (this.particles.length >= this.maxCount || groupDesc.enabled === false && !force) {
49899
50761
  return;
49900
50762
  }
49901
50763
  const speed = randomBetween(this.speed.Min, this.speed.Max);
@@ -50093,6 +50955,7 @@ class EmitterGroupDesc extends RenderDesc {
50093
50955
  this.lowerBound = other.lowerBound;
50094
50956
  this.higherBound = other.higherBound;
50095
50957
  this.emitterDir = other.emitterDir;
50958
+ this.enabled = other.enabled;
50096
50959
  for (let i = 0; i < this.emitterDescs.length; i++) {
50097
50960
  this.emitterDescs[i].fromEmitterDesc(other.emitterDescs[i]);
50098
50961
  }
@@ -50334,6 +51197,521 @@ const __vite_glob_0_1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def
50334
51197
  __proto__: null,
50335
51198
  EmitterGroupDesc
50336
51199
  }, Symbol.toStringTag, { value: "Module" }));
51200
+ class ParticleEmitterWrapper extends InstanceWrapper {
51201
+ static className = "ParticleEmitter";
51202
+ static requiredProperties = [
51203
+ "Name"
51204
+ ];
51205
+ setup() {
51206
+ if (!this.instance.HasProperty("Name")) this.instance.addProperty(new Property("Name", DataType.String), this.instance.className);
51207
+ }
51208
+ Emit(count = 16) {
51209
+ const renderDescs = RBXRenderer.getRenderDescs(this.instance);
51210
+ for (const renderDesc of renderDescs) {
51211
+ if (renderDesc instanceof EmitterGroupDesc) {
51212
+ for (const emitterDesc of renderDesc.emitterDescs) {
51213
+ for (let i = 0; i < count; i++) {
51214
+ emitterDesc.emit(renderDesc, true);
51215
+ }
51216
+ }
51217
+ }
51218
+ }
51219
+ }
51220
+ }
51221
+ const __vite_glob_0_21 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51222
+ __proto__: null,
51223
+ ParticleEmitterWrapper
51224
+ }, Symbol.toStringTag, { value: "Module" }));
51225
+ class SoundWrapperData {
51226
+ audioContext;
51227
+ gainNode;
51228
+ buffer;
51229
+ playingSource;
51230
+ }
51231
+ class SoundWrapper extends InstanceWrapper {
51232
+ static className = "Sound";
51233
+ static requiredProperties = ["Name", "Looped", "Playing", "Volume", "_data"];
51234
+ setup() {
51235
+ if (!this.instance.HasProperty("Name")) this.instance.addProperty(new Property("Name", DataType.String), this.instance.className);
51236
+ if (!this.instance.HasProperty("Looped")) this.instance.addProperty(new Property("Looped", DataType.Bool), false);
51237
+ if (!this.instance.HasProperty("Playing")) this.instance.addProperty(new Property("Playing", DataType.Bool), false);
51238
+ if (!this.instance.HasProperty("Volume")) this.instance.addProperty(new Property("Volume", DataType.Float32), false);
51239
+ if (!this.instance.HasProperty("_data")) this.instance.addProperty(new Property("_data", DataType.NonSerializable), new SoundWrapperData());
51240
+ }
51241
+ get data() {
51242
+ return this.instance.Prop("_data");
51243
+ }
51244
+ created() {
51245
+ if (this.instance.Prop("Playing")) {
51246
+ this.Play();
51247
+ }
51248
+ this.instance.Destroying.Connect(() => {
51249
+ if (this.data.playingSource) {
51250
+ this.Stop();
51251
+ }
51252
+ this.data.audioContext = void 0;
51253
+ this.data.gainNode = void 0;
51254
+ this.data.buffer = void 0;
51255
+ });
51256
+ }
51257
+ _updateVolume() {
51258
+ if (this.data.gainNode) {
51259
+ if (this.instance.HasProperty("Volume")) {
51260
+ const volume = this.instance.Prop("Volume");
51261
+ this.data.gainNode.gain.value = volume;
51262
+ }
51263
+ }
51264
+ }
51265
+ setPlaying(value) {
51266
+ this.instance.setProperty("Playing", value);
51267
+ }
51268
+ playSource() {
51269
+ if (!this.data.audioContext || !this.data.gainNode || !this.data.buffer) return;
51270
+ this.data.playingSource = this.data.audioContext.createBufferSource();
51271
+ this.data.playingSource.buffer = this.data.buffer;
51272
+ this.data.playingSource.connect(this.data.gainNode);
51273
+ this.data.gainNode.connect(this.data.audioContext.destination);
51274
+ this._updateVolume();
51275
+ this.data.playingSource.start(0);
51276
+ this.data.playingSource.onended = (() => {
51277
+ if (this.instance.Prop("Looped")) {
51278
+ this.Play();
51279
+ } else {
51280
+ this.Stop();
51281
+ }
51282
+ });
51283
+ }
51284
+ Play() {
51285
+ if (!FLAGS.AUDIO_ENABLED) return;
51286
+ this.Stop();
51287
+ this.setPlaying(true);
51288
+ if (!this.data.audioContext) {
51289
+ this.data.audioContext = new AudioContext();
51290
+ }
51291
+ if (!this.data.gainNode) {
51292
+ this.data.gainNode = this.data.audioContext.createGain();
51293
+ }
51294
+ if (!this.data.buffer) {
51295
+ let audioUrl = void 0;
51296
+ if (this.instance.HasProperty("SoundId")) {
51297
+ audioUrl = this.instance.Prop("SoundId");
51298
+ } else if (this.instance.HasProperty("AudioContent")) {
51299
+ audioUrl = this.instance.Prop("AudioContent").uri;
51300
+ }
51301
+ if (audioUrl && audioUrl.length > 0) {
51302
+ API.Asset.GetAssetBuffer(audioUrl).then((responseBuffer) => {
51303
+ if (responseBuffer instanceof Response || !this.data.audioContext) return;
51304
+ const buffer2 = responseBuffer.slice(0);
51305
+ this.data.audioContext.decodeAudioData(buffer2).then((decodedData) => {
51306
+ if (!this.data.audioContext || !this.data.gainNode) return;
51307
+ this.data.buffer = decodedData;
51308
+ this.playSource();
51309
+ });
51310
+ });
51311
+ }
51312
+ } else if (this.data.buffer) {
51313
+ this.playSource();
51314
+ }
51315
+ }
51316
+ Stop() {
51317
+ this.setPlaying(false);
51318
+ if (this.data.playingSource) {
51319
+ this.data.playingSource.stop();
51320
+ this.data.playingSource = void 0;
51321
+ }
51322
+ }
51323
+ }
51324
+ const __vite_glob_0_23 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51325
+ __proto__: null,
51326
+ SoundWrapper
51327
+ }, Symbol.toStringTag, { value: "Module" }));
51328
+ class ScriptWrapperData {
51329
+ shouldStop = false;
51330
+ }
51331
+ class ScriptWrapper extends InstanceWrapper {
51332
+ static className = "Script";
51333
+ static requiredProperties = ["Name", "_data"];
51334
+ setup() {
51335
+ if (!this.instance.HasProperty("Name")) this.instance.addProperty(new Property("Name", DataType.String), this.instance.className);
51336
+ if (!this.instance.HasProperty("_data")) this.instance.addProperty(new Property("_data", DataType.NonSerializable), new ScriptWrapperData());
51337
+ }
51338
+ get data() {
51339
+ return this.instance.Prop("_data");
51340
+ }
51341
+ created() {
51342
+ this.Run();
51343
+ }
51344
+ Run() {
51345
+ switch (this.instance.Prop("Name")) {
51346
+ case "ChickenSounds":
51347
+ case "HarmonicaSounds":
51348
+ case "SoundPlayer":
51349
+ this.SoundPlayer(this.instance);
51350
+ break;
51351
+ case "HatScript2.0":
51352
+ this.HatScript20(this.instance);
51353
+ break;
51354
+ }
51355
+ }
51356
+ //Scripts
51357
+ async SoundPlayer(script) {
51358
+ let Handle = void 0;
51359
+ if (script.parent && script.parent.Prop("Name") === "Handle") {
51360
+ Handle = script.parent;
51361
+ } else if (script.parent && script.parent.FindFirstChild("Handle")) {
51362
+ Handle = script.parent.FindFirstChild("Handle");
51363
+ }
51364
+ if (!Handle) return;
51365
+ const Hat = Handle.parent;
51366
+ if (!Hat) return;
51367
+ const Sounds = [];
51368
+ for (const child of Handle.GetDescendants()) {
51369
+ if (child.className === "Sound") {
51370
+ Sounds.push(child);
51371
+ }
51372
+ }
51373
+ function IsBeingWorn() {
51374
+ return Hat?.parent?.FindFirstChild("Humanoid");
51375
+ }
51376
+ let maxTime = 20;
51377
+ if (script.Prop("Name") === "SoundPlayer") {
51378
+ maxTime = 15;
51379
+ }
51380
+ while (true) {
51381
+ await Wait(mathRandom(5, maxTime));
51382
+ if (this.instance.destroyed || this.data.shouldStop) return;
51383
+ if (IsBeingWorn()) {
51384
+ const index = mathRandom(0, Sounds.length - 1);
51385
+ const Sound = Sounds[index];
51386
+ const soundWrapper = new SoundWrapper(Sound);
51387
+ soundWrapper.Play();
51388
+ }
51389
+ }
51390
+ }
51391
+ async HatScript20(script) {
51392
+ const now = /* @__PURE__ */ new Date();
51393
+ const month = now.getMonth();
51394
+ const day = now.getDay();
51395
+ const data = this.data;
51396
+ let hw;
51397
+ let tg;
51398
+ let xm;
51399
+ let bd;
51400
+ let pt;
51401
+ let vt;
51402
+ let af;
51403
+ if (month == 10 && day > 21) {
51404
+ hw = true;
51405
+ } else if (month == 11 && day > 19) {
51406
+ tg = true;
51407
+ } else if (month == 12 && day > 17 && day < 28) {
51408
+ xm = true;
51409
+ } else if (month == 9 && day == 1) {
51410
+ bd = true;
51411
+ } else if (month == 3 && day > 11 && day < 20) {
51412
+ pt = true;
51413
+ } else if (month == 2 && day > 8 && day < 17) {
51414
+ vt = true;
51415
+ } else if (month == 4 && day == 1) {
51416
+ af = true;
51417
+ }
51418
+ let emitter = script.parent?.Child("ParticleEmitter");
51419
+ const burst = script.parent?.Child("Burst");
51420
+ async function snowBlower() {
51421
+ const snow1 = script.parent?.Child("Snowflake1");
51422
+ const snow2 = script.parent?.Child("Snowflake2");
51423
+ while (true) {
51424
+ await Wait(Math.random() * 5);
51425
+ if (script.destroyed || data.shouldStop) return;
51426
+ snow1?.setProperty("Enabled", false);
51427
+ snow2?.setProperty("Enabled", true);
51428
+ await Wait(Math.random() * 5);
51429
+ if (script.destroyed || data.shouldStop) return;
51430
+ snow1?.setProperty("Enabled", true);
51431
+ snow2?.setProperty("Enabled", false);
51432
+ if (Math.random() > 0.97) {
51433
+ snow1?.setProperty("Enabled", false);
51434
+ await Wait(4);
51435
+ if (script.destroyed || data.shouldStop) return;
51436
+ (snow1?.w).Emit(22);
51437
+ await Wait(Math.random());
51438
+ if (script.destroyed || data.shouldStop) return;
51439
+ (snow2?.w).Emit(22);
51440
+ await Wait(2);
51441
+ if (script.destroyed || data.shouldStop) return;
51442
+ }
51443
+ }
51444
+ }
51445
+ async function leafBlower() {
51446
+ const leaf1 = script.parent?.Child("Leaf1");
51447
+ const leaf2 = script.parent?.Child("Leaf2");
51448
+ while (true) {
51449
+ await Wait(Math.random() * 5);
51450
+ if (script.destroyed || data.shouldStop) return;
51451
+ leaf1?.setProperty("Enabled", false);
51452
+ leaf2?.setProperty("Enabled", true);
51453
+ await Wait(Math.random() * 5);
51454
+ if (script.destroyed || data.shouldStop) return;
51455
+ leaf1?.setProperty("Enabled", true);
51456
+ leaf2?.setProperty("Enabled", false);
51457
+ if (Math.random() > 0.97) {
51458
+ leaf1?.setProperty("Enabled", false);
51459
+ await Wait(4);
51460
+ if (script.destroyed || data.shouldStop) return;
51461
+ (leaf1?.w).Emit(22);
51462
+ await Wait(Math.random());
51463
+ if (script.destroyed || data.shouldStop) return;
51464
+ (leaf2?.w).Emit(22);
51465
+ await Wait(2);
51466
+ if (script.destroyed || data.shouldStop) return;
51467
+ }
51468
+ }
51469
+ }
51470
+ async function cloverBlower() {
51471
+ const leaf1 = script.parent?.Child("Clover1");
51472
+ const leaf2 = script.parent?.Child("Clover2");
51473
+ while (true) {
51474
+ await Wait(Math.random() * 5);
51475
+ if (script.destroyed || data.shouldStop) return;
51476
+ leaf1?.setProperty("Enabled", false);
51477
+ leaf2?.setProperty("Enabled", true);
51478
+ await Wait(Math.random() * 5);
51479
+ if (script.destroyed || data.shouldStop) return;
51480
+ leaf1?.setProperty("Enabled", true);
51481
+ leaf2?.setProperty("Enabled", false);
51482
+ if (Math.random() > 0.97) {
51483
+ leaf1?.setProperty("Enabled", false);
51484
+ await Wait(4);
51485
+ if (script.destroyed || data.shouldStop) return;
51486
+ (leaf1?.w).Emit(22);
51487
+ await Wait(Math.random());
51488
+ if (script.destroyed || data.shouldStop) return;
51489
+ (leaf2?.w).Emit(22);
51490
+ await Wait(2);
51491
+ if (script.destroyed || data.shouldStop) return;
51492
+ }
51493
+ }
51494
+ }
51495
+ if (hw) {
51496
+ emitter?.setProperty("Enabled", false);
51497
+ emitter = script.parent?.Child("Hallow");
51498
+ if (script.parent?.parent?.IsA("MeshPart")) {
51499
+ script.parent?.parent?.setProperty("TextureID", "rbxassetid://6991166143");
51500
+ } else {
51501
+ script.parent?.parent?.Child("Mesh")?.setProperty("TextureId", "rbxassetid://6991166143");
51502
+ }
51503
+ } else if (tg) {
51504
+ if (script.parent?.parent?.IsA("MeshPart")) {
51505
+ script.parent?.parent?.setProperty("TextureID", "rbxassetid://6991393806");
51506
+ } else {
51507
+ script.parent?.parent?.Child("Mesh")?.setProperty("TextureId", "rbxassetid://6991393806");
51508
+ }
51509
+ leafBlower();
51510
+ } else if (xm) {
51511
+ emitter?.setProperty("Enabled", false);
51512
+ emitter = script.parent?.Child("Snowflake3");
51513
+ snowBlower();
51514
+ } else if (bd) {
51515
+ emitter?.setProperty("Enabled", false);
51516
+ emitter = script.parent?.Child("Confetti");
51517
+ if (script.parent?.parent?.IsA("MeshPart")) {
51518
+ script.parent?.parent?.setProperty("TextureID", "rbxassetid://2399316028");
51519
+ } else {
51520
+ script.parent?.parent?.Child("Mesh")?.setProperty("TextureId", "rbxassetid://2399316028");
51521
+ }
51522
+ } else if (pt) {
51523
+ if (script.Parent?.Parent?.IsA("MeshPart")) {
51524
+ script.parent?.parent?.setProperty("TextureID", "rbxassetid://2399447918");
51525
+ } else {
51526
+ script.parent?.parent?.Child("Mesh")?.setProperty("TextureId", "rbxassetid://2399447918");
51527
+ }
51528
+ cloverBlower();
51529
+ } else if (vt) {
51530
+ emitter?.setProperty("Enabled", false);
51531
+ emitter = script.Parent?.Child("Heart");
51532
+ if (script.Parent?.Parent?.IsA("MeshPart")) {
51533
+ script.parent?.parent?.setProperty("TextureID", "rbxassetid://2399448372");
51534
+ } else {
51535
+ script.parent?.parent?.Child("Mesh")?.setProperty("TextureId", "rbxassetid://2399448372");
51536
+ }
51537
+ } else if (af) {
51538
+ emitter?.setProperty("Enabled", false);
51539
+ emitter = script.Parent?.Child("Hats");
51540
+ script.Parent?.Child("Smokescreen")?.setProperty("Enabled", true);
51541
+ script.Parent?.Parent?.setProperty("Transparency", 1);
51542
+ }
51543
+ while (true) {
51544
+ await Wait(1.3);
51545
+ if (script.destroyed || data.shouldStop) return;
51546
+ emitter?.setProperty("Enabled", false);
51547
+ await Wait(0.8);
51548
+ if (script.destroyed || data.shouldStop) return;
51549
+ emitter?.setProperty("Enabled", true);
51550
+ const rando = Math.random();
51551
+ if (rando > 0.97) {
51552
+ emitter?.setProperty("Enabled", false);
51553
+ await Wait(4);
51554
+ if (script.destroyed || data.shouldStop) return;
51555
+ burst?.setProperty("Enabled", true);
51556
+ await Wait(2);
51557
+ if (script.destroyed || data.shouldStop) return;
51558
+ burst?.setProperty("Enabled", false);
51559
+ emitter?.setProperty("Enabled", true);
51560
+ } else if (rando > 0.969) {
51561
+ emitter?.setProperty("Enabled", false);
51562
+ await Wait(4);
51563
+ if (script.destroyed || data.shouldStop) return;
51564
+ for (const v of script.Parent?.GetChildren() || []) {
51565
+ if (v.IsA("ParticleEmitter")) {
51566
+ v.w.Emit(mathRandom(6, 10));
51567
+ await Wait(0.5);
51568
+ if (script.destroyed || data.shouldStop) return;
51569
+ }
51570
+ }
51571
+ await Wait(2);
51572
+ if (script.destroyed || data.shouldStop) return;
51573
+ emitter?.setProperty("Enabled", true);
51574
+ }
51575
+ }
51576
+ }
51577
+ }
51578
+ const __vite_glob_0_22 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51579
+ __proto__: null,
51580
+ ScriptWrapper
51581
+ }, Symbol.toStringTag, { value: "Module" }));
51582
+ class ToolWrapper extends InstanceWrapper {
51583
+ static className = "Tool";
51584
+ static requiredProperties = [
51585
+ "Name",
51586
+ "Grip"
51587
+ ];
51588
+ setup() {
51589
+ if (!this.instance.HasProperty("Name")) this.instance.addProperty(new Property("Name", DataType.String), this.instance.className);
51590
+ if (!this.instance.HasProperty("Grip")) this.instance.addProperty(new Property("Grip", DataType.CFrame), new CFrame());
51591
+ }
51592
+ created() {
51593
+ this.instance.AncestryChanged.Connect(() => {
51594
+ this.createWeld();
51595
+ });
51596
+ }
51597
+ //doing this is actually inaccurate because tools dont create welds, but its easier
51598
+ createWeld() {
51599
+ const handle = this.instance.FindFirstChild("Handle");
51600
+ const rig = this.instance.parent;
51601
+ const grip = this.instance.PropOrDefault("Grip", new CFrame()).clone();
51602
+ if (handle) {
51603
+ const oldToolWeld = handle.FindFirstChild("ToolWeld_GripRoAvatar");
51604
+ if (oldToolWeld) {
51605
+ oldToolWeld.Destroy();
51606
+ }
51607
+ }
51608
+ const humanoid = rig?.FindFirstChildOfClass("Humanoid");
51609
+ if (handle && rig && rig.className === "Model" && humanoid) {
51610
+ const rightHand = rig.FindFirstChild("RightHand") || rig.FindFirstChild("Right Arm");
51611
+ if (rightHand) {
51612
+ for (const child of rightHand.GetDescendants()) {
51613
+ if (child.Prop("Name") === "RightGripAttachment") {
51614
+ const rightGripAttCF = child.PropOrDefault("CFrame", new CFrame()).clone();
51615
+ if (humanoid.Prop("RigType") === HumanoidRigType.R6) {
51616
+ rightGripAttCF.Orientation[0] -= 90;
51617
+ }
51618
+ const weld = new Instance("Weld");
51619
+ weld.addProperty(new Property("Name", DataType.String), "ToolWeld_GripRoAvatar");
51620
+ weld.addProperty(new Property("Archivable", DataType.Bool), true);
51621
+ weld.addProperty(new Property("C0", DataType.CFrame), rightGripAttCF);
51622
+ weld.addProperty(new Property("C1", DataType.CFrame), grip);
51623
+ weld.addProperty(new Property("Part0", DataType.Referent), child.parent);
51624
+ weld.addProperty(new Property("Part1", DataType.Referent), handle);
51625
+ weld.addProperty(new Property("Active", DataType.Bool), true);
51626
+ weld.addProperty(new Property("Enabled", DataType.Bool), false);
51627
+ weld.setParent(handle);
51628
+ weld.setProperty("Enabled", true);
51629
+ }
51630
+ }
51631
+ }
51632
+ }
51633
+ }
51634
+ }
51635
+ const __vite_glob_0_24 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51636
+ __proto__: null,
51637
+ ToolWrapper
51638
+ }, Symbol.toStringTag, { value: "Module" }));
51639
+ class WedgePartWrapper extends BasePartWrapper {
51640
+ static className = "WedgePart";
51641
+ }
51642
+ const __vite_glob_0_25 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51643
+ __proto__: null,
51644
+ WedgePartWrapper
51645
+ }, Symbol.toStringTag, { value: "Module" }));
51646
+ class WeldWrapper extends JointInstanceWrapper {
51647
+ static className = "Weld";
51648
+ }
51649
+ const __vite_glob_0_26 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51650
+ __proto__: null,
51651
+ WeldWrapper
51652
+ }, Symbol.toStringTag, { value: "Module" }));
51653
+ const modules$1 = /* @__PURE__ */ Object.assign({ "./instance/Accessory.ts": __vite_glob_0_0$1, "./instance/AccessoryDescription.ts": __vite_glob_0_1$1, "./instance/AnimationConstraint.ts": __vite_glob_0_2$1, "./instance/Animator.ts": __vite_glob_0_3, "./instance/Attachment.ts": __vite_glob_0_4, "./instance/BasePart.ts": __vite_glob_0_5, "./instance/BodyColors.ts": __vite_glob_0_6, "./instance/BodyPartDescription.ts": __vite_glob_0_7, "./instance/Bone.ts": __vite_glob_0_8, "./instance/Constraint.ts": __vite_glob_0_9, "./instance/Decal.ts": __vite_glob_0_10, "./instance/FaceControls.ts": __vite_glob_0_11, "./instance/HumanoidDescription.ts": __vite_glob_0_12, "./instance/InstanceWrapper.ts": __vite_glob_0_13, "./instance/JointInstance.ts": __vite_glob_0_14, "./instance/MakeupDescription.ts": __vite_glob_0_15, "./instance/ManualWeld.ts": __vite_glob_0_16, "./instance/MeshPart.ts": __vite_glob_0_17, "./instance/Model.ts": __vite_glob_0_18, "./instance/Motor6D.ts": __vite_glob_0_19, "./instance/Part.ts": __vite_glob_0_20, "./instance/ParticleEmitter.ts": __vite_glob_0_21, "./instance/Script.ts": __vite_glob_0_22, "./instance/Sound.ts": __vite_glob_0_23, "./instance/Tool.ts": __vite_glob_0_24, "./instance/WedgePart.ts": __vite_glob_0_25, "./instance/Weld.ts": __vite_glob_0_26 });
51654
+ function RegisterWrappers() {
51655
+ for (const module of Object.values(modules$1)) {
51656
+ for (const exprt of Object.values(module)) {
51657
+ let prototype = Object.getPrototypeOf(exprt);
51658
+ while (prototype) {
51659
+ if (prototype === InstanceWrapper) {
51660
+ exprt.register();
51661
+ break;
51662
+ }
51663
+ prototype = Object.getPrototypeOf(prototype);
51664
+ }
51665
+ }
51666
+ }
51667
+ }
51668
+ const attachmentGeometry = new SphereGeometry(0.125, 16, 8);
51669
+ class AttachmentDesc extends RenderDesc {
51670
+ static classTypes = ["Attachment"];
51671
+ visible = false;
51672
+ cframe = new CFrame();
51673
+ isSame(other) {
51674
+ return this.visible === other.visible && this.cframe.isSame(other.cframe);
51675
+ }
51676
+ needsRegeneration(other) {
51677
+ return this.visible !== other.visible;
51678
+ }
51679
+ virtualFromRenderDesc(other) {
51680
+ this.cframe = other.cframe.clone();
51681
+ }
51682
+ fromInstance(child) {
51683
+ const attachmentW = new AttachmentWrapper(child);
51684
+ this.cframe = attachmentW.getWorldCFrame();
51685
+ this.visible = child.PropOrDefault("Visible", this.visible) || FLAGS.ALWAYS_SHOW_ATTACHMENTS;
51686
+ }
51687
+ async compileResults() {
51688
+ this.results = [];
51689
+ if (this.visible) {
51690
+ const mesh = new Mesh(attachmentGeometry, new MeshLambertMaterial({ color: 65280 }));
51691
+ mesh.name = this.instance ? this.instance.PropOrDefault("Name", "Unknown") + "_Att" : "Unknown_Att";
51692
+ this.results.push(mesh);
51693
+ }
51694
+ this.updateResults();
51695
+ return this.results;
51696
+ }
51697
+ updateResults() {
51698
+ if (!this.results) return;
51699
+ for (const attachment of this.results) {
51700
+ const resultCF = this.cframe;
51701
+ setTHREEObjectCF(attachment, resultCF);
51702
+ }
51703
+ }
51704
+ dispose(_renderer, scene) {
51705
+ if (!this.results) return;
51706
+ for (const result of this.results) {
51707
+ scene.remove(result);
51708
+ }
51709
+ }
51710
+ }
51711
+ const __vite_glob_0_0 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51712
+ __proto__: null,
51713
+ AttachmentDesc
51714
+ }, Symbol.toStringTag, { value: "Module" }));
50337
51715
  function disposeLight(scene, light) {
50338
51716
  if (light.shadow && light.shadow.map) {
50339
51717
  light.shadow.map.dispose();
@@ -50589,7 +51967,125 @@ class RBXRendererScene {
50589
51967
  * @param autoDownload If resulting file should be auto downloaded
50590
51968
  * @returns The GLB (buffer) or GLTF (object)
50591
51969
  */
50592
- async exportGLTF(name = "scene", autoDownload = true) {
51970
+ async exportGLTF(name = "scene", autoDownload = true, options) {
51971
+ const actualOptions = {
51972
+ includeAnimations: false,
51973
+ binary: false
51974
+ };
51975
+ if (options) Object.assign(actualOptions, options);
51976
+ const clips = [];
51977
+ let animator = void 0;
51978
+ let allInstances = [];
51979
+ let rootInstance = void 0;
51980
+ const allRenderedInstances = Array.from(this.renderDescs.keys());
51981
+ let parent = allRenderedInstances[0].parent;
51982
+ while (parent !== void 0) {
51983
+ if (parent.parent === void 0) {
51984
+ rootInstance = parent;
51985
+ allInstances = [parent, ...parent.GetDescendants()];
51986
+ break;
51987
+ }
51988
+ parent = parent.parent;
51989
+ }
51990
+ for (const instance of allInstances) {
51991
+ if (instance.className === "Animator") {
51992
+ animator = instance;
51993
+ break;
51994
+ }
51995
+ }
51996
+ const GLTF_FPS = 30;
51997
+ if (animator && actualOptions.includeAnimations && rootInstance) {
51998
+ const w = animator.w;
51999
+ for (const animationEntryKey of Object.keys(w.data.animationSet)) {
52000
+ let trackIndex = 0;
52001
+ for (const animationEntry of w.data.animationSet[animationEntryKey]) {
52002
+ const track = w._getTrack(animationEntry.id);
52003
+ if (track) {
52004
+ const objectPositions = /* @__PURE__ */ new Map();
52005
+ const objectRotations = /* @__PURE__ */ new Map();
52006
+ const bonePositions = /* @__PURE__ */ new Map();
52007
+ const boneQuaternions = /* @__PURE__ */ new Map();
52008
+ track.weight = 1;
52009
+ const times = [];
52010
+ for (let i = 0; i < Math.max(1, Math.ceil(track.length * GLTF_FPS)); i++) {
52011
+ w.restPose();
52012
+ track.setTime(i / GLTF_FPS);
52013
+ if (w.data.currentMoodAnimationTrack) w.data.currentMoodAnimationTrack.setTime(0);
52014
+ times.push(i / GLTF_FPS);
52015
+ rootInstance.preRender();
52016
+ RBXRenderer.addInstance(rootInstance, new Authentication(), this);
52017
+ for (const instance of allRenderedInstances) {
52018
+ if (instance.className === "Attachment") continue;
52019
+ let isSkinned = false;
52020
+ const renderDesc = this.renderDescs.get(instance);
52021
+ if (renderDesc && renderDesc instanceof ObjectDesc && renderDesc.skeletonDesc) {
52022
+ isSkinned = true;
52023
+ const bones = renderDesc.skeletonDesc.bones;
52024
+ for (const bone of bones) {
52025
+ if (!bonePositions.has(bone)) bonePositions.set(bone, []);
52026
+ if (!boneQuaternions.has(bone)) boneQuaternions.set(bone, []);
52027
+ bonePositions.get(bone).push(bone.position.toArray());
52028
+ boneQuaternions.get(bone).push(bone.quaternion.toArray());
52029
+ }
52030
+ }
52031
+ let partToUse = instance;
52032
+ if (partToUse.className === "Decal" && partToUse.parent) {
52033
+ partToUse = partToUse.parent;
52034
+ }
52035
+ let cf = partToUse.PropOrDefault("CFrame", new CFrame());
52036
+ if (isSkinned) {
52037
+ cf = new CFrame();
52038
+ }
52039
+ if (!objectPositions.has(instance)) objectPositions.set(instance, []);
52040
+ if (!objectRotations.has(instance)) objectRotations.set(instance, []);
52041
+ objectPositions.get(instance).push(cf.Position);
52042
+ objectRotations.get(instance).push([rad(cf.Orientation[0]), rad(cf.Orientation[1]), rad(cf.Orientation[2])]);
52043
+ }
52044
+ }
52045
+ const keyframeTracks = [];
52046
+ for (const instance of allRenderedInstances) {
52047
+ if (instance.className === "Attachment") continue;
52048
+ const thisPositions = objectPositions.get(instance);
52049
+ const thisRotations = objectRotations.get(instance);
52050
+ if (thisPositions && thisRotations) {
52051
+ const instanceName = instance.PropOrDefault("Name", "Mesh") + "_" + instance.id;
52052
+ keyframeTracks.push(new VectorKeyframeTrack(instanceName + ".position", times, thisPositions.flat()));
52053
+ const quaternionValues = [];
52054
+ for (const rotationValue of thisRotations) {
52055
+ const quat = new Quaternion().setFromEuler(new Euler(...rotationValue, "YXZ"));
52056
+ quaternionValues.push(quat.x, quat.y, quat.z, quat.w);
52057
+ }
52058
+ keyframeTracks.push(new QuaternionKeyframeTrack(instanceName + ".quaternion", times, quaternionValues));
52059
+ }
52060
+ const renderDesc = this.renderDescs.get(instance);
52061
+ if (renderDesc && renderDesc instanceof ObjectDesc && renderDesc.skeletonDesc) {
52062
+ const bones = renderDesc.skeletonDesc.bones;
52063
+ for (const bone of bones) {
52064
+ const thisBonePositions = bonePositions.get(bone);
52065
+ const thisBoneQuaternions = boneQuaternions.get(bone);
52066
+ if (thisBonePositions && thisBoneQuaternions) {
52067
+ keyframeTracks.push(new VectorKeyframeTrack(bone.name + ".position", times, thisBonePositions.flat()));
52068
+ keyframeTracks.push(new QuaternionKeyframeTrack(bone.name + ".quaternion", times, thisBoneQuaternions.flat()));
52069
+ }
52070
+ }
52071
+ }
52072
+ }
52073
+ const clip = new AnimationClip(animationEntryKey + "_" + trackIndex, track.length, keyframeTracks);
52074
+ clips.push(clip);
52075
+ console.log(`Generated clip (${clip.name}) with ${clip.tracks.length} tracks and length of ${track.length}`);
52076
+ }
52077
+ trackIndex += 1;
52078
+ }
52079
+ }
52080
+ w.restPose();
52081
+ rootInstance.preRender();
52082
+ RBXRenderer.addInstance(rootInstance, new Authentication(), this);
52083
+ }
52084
+ for (const renderedInstance of allRenderedInstances) {
52085
+ if (this.renderDescs.get(renderedInstance) instanceof EmitterGroupDesc) {
52086
+ RBXRenderer.removeInstance(renderedInstance, this);
52087
+ }
52088
+ }
50593
52089
  return new Promise((resolve, reject) => {
50594
52090
  const exporter = new GLTFExporter();
50595
52091
  exporter.parse(this.scene, (gltf) => {
@@ -50603,6 +52099,9 @@ class RBXRendererScene {
50603
52099
  resolve(gltf);
50604
52100
  }, (error2) => {
50605
52101
  reject(error2);
52102
+ }, {
52103
+ animations: clips,
52104
+ binary: actualOptions.binary
50606
52105
  });
50607
52106
  });
50608
52107
  }
@@ -51060,6 +52559,14 @@ class RBXRenderer {
51060
52559
  RBXRenderer.removeInstance(child, renderScene);
51061
52560
  }
51062
52561
  }
52562
+ static getRenderDescs(instance) {
52563
+ const renderDescs = [];
52564
+ for (const renderScene of RBXRenderer.scenes) {
52565
+ const renderDesc = renderScene.renderDescs.get(instance);
52566
+ if (renderDesc) renderDescs.push(renderDesc);
52567
+ }
52568
+ return renderDescs;
52569
+ }
51063
52570
  static _addRenderDesc(instance, auth, DescClass, renderScene) {
51064
52571
  if (!RBXRenderer.renderer) return;
51065
52572
  const oldDesc = renderScene.renderDescs.get(instance);
@@ -51772,7 +53279,7 @@ async function renderTargetToCanvas(renderTarget) {
51772
53279
  await rbxRenderer.readRenderTargetPixelsAsync(renderTarget, 0, 0, width, height, data);
51773
53280
  return imageDataToCanvas(data, width, height);
51774
53281
  }
51775
- async function generateModelThumbnail(auth, renderScene, model, size = [150, 150], type = "png", quality = 1, gltfAutoDownload = false) {
53282
+ async function generateModelThumbnail(auth, renderScene, model, size = [150, 150], type = "png", quality = 1, gltfAutoDownload = false, includeAnimations = false) {
51776
53283
  return new Promise((resolve) => {
51777
53284
  const cameraCFrame = getThumbnailCameraCFrame(model);
51778
53285
  if (cameraCFrame) {
@@ -51791,11 +53298,14 @@ async function generateModelThumbnail(auth, renderScene, model, size = [150, 150
51791
53298
  });
51792
53299
  async function doExport() {
51793
53300
  onLoadingConnection.Disconnect();
51794
- if (type === "gltf") {
53301
+ if (type === "gltf" || type === "glb") {
51795
53302
  if (!FLAGS.RENDERTARGET_TO_CANVASTEXTURE && FLAGS.USE_RENDERTARGET) {
51796
53303
  warn(true, "FLAGS.RENDERTARGET_TO_CANVASTEXTURE is false, GLTF export cannot export render target textures, consider setting this flag to true");
51797
53304
  }
51798
- resolve(await renderScene.exportGLTF(`result`, gltfAutoDownload));
53305
+ resolve(await renderScene.exportGLTF(`result`, gltfAutoDownload, {
53306
+ includeAnimations,
53307
+ binary: type === "glb"
53308
+ }));
51799
53309
  } else {
51800
53310
  const renderTarget = renderToRenderTarget(...size, renderScene);
51801
53311
  const canvasTarget = await renderTargetToCanvas(renderTarget);
@@ -51809,7 +53319,7 @@ async function generateModelThumbnail(auth, renderScene, model, size = [150, 150
51809
53319
  }
51810
53320
  });
51811
53321
  }
51812
- async function generateOutfitThumbnail(auth, outfit, size = [150, 150], type = "png", quality = 1, gltfAutoDownload = false) {
53322
+ async function generateOutfitThumbnail(auth, outfit, size = [150, 150], type = "png", quality = 1, gltfAutoDownload = false, includeAnimations = false) {
51813
53323
  return new Promise((resolve) => {
51814
53324
  const startTime = performance.now();
51815
53325
  const renderScene = RBXRenderer.addScene();
@@ -51849,7 +53359,7 @@ async function generateOutfitThumbnail(auth, outfit, size = [150, 150], type = "
51849
53359
  onLoadingConnection.Disconnect();
51850
53360
  if (outfitRenderer.currentRig) {
51851
53361
  outfitRenderer.animateOnce(!outfit.containsAssetType("Gear") && outfit.playerAvatarType === AvatarType.R6 ? 0 : 1);
51852
- const thumbnailResult = await generateModelThumbnail(auth, renderScene, outfitRenderer.currentRig, size, type, quality, gltfAutoDownload);
53362
+ const thumbnailResult = await generateModelThumbnail(auth, renderScene, outfitRenderer.currentRig, size, type, quality, gltfAutoDownload, includeAnimations);
51853
53363
  console.log("Generated outfit thumbnail after seconds:", (performance.now() - startTime) / 1e3);
51854
53364
  resolve(thumbnailResult);
51855
53365
  if (outfitRenderer.currentRig) outfitRenderer.currentRig.Destroy();
@@ -51934,6 +53444,7 @@ export {
51934
53444
  CACHE,
51935
53445
  CFrame,
51936
53446
  COREMESH,
53447
+ Cache,
51937
53448
  CatalogBundleTypes,
51938
53449
  CategoryDictionary,
51939
53450
  Color3,