roavatar-renderer 1.5.15 → 1.5.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.d.ts +11 -5
- package/dist/index.js +1308 -27
- package/package.json +1 -1
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 (
|
|
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 (
|
|
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 = [];
|
|
@@ -42738,6 +43869,7 @@ class ModelLayersDesc {
|
|
|
42738
43869
|
targetDeformers;
|
|
42739
43870
|
targetParents;
|
|
42740
43871
|
layers;
|
|
43872
|
+
destroyConnection;
|
|
42741
43873
|
//requires compilation
|
|
42742
43874
|
_targetMeshes;
|
|
42743
43875
|
uvToHits;
|
|
@@ -43017,16 +44149,23 @@ function getModelLayersDesc(model) {
|
|
|
43017
44149
|
if (oldLayerDesc && newLayerDesc.isSame(oldLayerDesc)) {
|
|
43018
44150
|
return oldLayerDesc;
|
|
43019
44151
|
} else {
|
|
44152
|
+
oldLayerDesc?.destroyConnection?.Disconnect();
|
|
43020
44153
|
modelLayers.set(model, newLayerDesc);
|
|
44154
|
+
newLayerDesc.destroyConnection = model.Destroying.Connect(() => {
|
|
44155
|
+
modelLayers.delete(model);
|
|
44156
|
+
newLayerDesc.destroyConnection?.Disconnect();
|
|
44157
|
+
newLayerDesc.destroyConnection = void 0;
|
|
44158
|
+
});
|
|
43021
44159
|
return newLayerDesc;
|
|
43022
44160
|
}
|
|
43023
44161
|
}
|
|
43024
44162
|
const modelHSRDescs = /* @__PURE__ */ new Map();
|
|
43025
|
-
const CACHE_uvToHits =
|
|
44163
|
+
const CACHE_uvToHits = new Cache();
|
|
43026
44164
|
class HSRDesc {
|
|
43027
44165
|
layers;
|
|
43028
44166
|
layerTransparent;
|
|
43029
44167
|
uvsToHits;
|
|
44168
|
+
destroyConnection;
|
|
43030
44169
|
isSame(other) {
|
|
43031
44170
|
if (!this.layers && other.layers || this.layers && !other.layers) {
|
|
43032
44171
|
return false;
|
|
@@ -43212,7 +44351,13 @@ function getModelHSRDesc(model) {
|
|
|
43212
44351
|
if (oldLayerDesc && newHSRDesc.isSame(oldLayerDesc)) {
|
|
43213
44352
|
return oldLayerDesc;
|
|
43214
44353
|
} else {
|
|
44354
|
+
oldLayerDesc?.destroyConnection?.Disconnect();
|
|
43215
44355
|
modelHSRDescs.set(model, newHSRDesc);
|
|
44356
|
+
newHSRDesc.destroyConnection = model.Destroying.Connect(() => {
|
|
44357
|
+
modelHSRDescs.delete(model);
|
|
44358
|
+
newHSRDesc.destroyConnection?.Disconnect();
|
|
44359
|
+
newHSRDesc.destroyConnection = void 0;
|
|
44360
|
+
});
|
|
43216
44361
|
return newHSRDesc;
|
|
43217
44362
|
}
|
|
43218
44363
|
}
|
|
@@ -43266,7 +44411,7 @@ function buildWedge(x, y, z) {
|
|
|
43266
44411
|
mesh.coreMesh.increaseFaces(2 * 5);
|
|
43267
44412
|
let totalVerts = 0;
|
|
43268
44413
|
let totalFaces = 0;
|
|
43269
|
-
totalVerts = addQuad(mesh, totalVerts, totalFaces, [-x, -y, -z], [x, -y, -z], [x, y, z], [-x, y, z], [0, 1,
|
|
44414
|
+
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
44415
|
totalFaces += 2;
|
|
43271
44416
|
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
44417
|
totalFaces += 2;
|
|
@@ -43277,7 +44422,7 @@ function buildWedge(x, y, z) {
|
|
|
43277
44422
|
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
44423
|
return mesh;
|
|
43279
44424
|
}
|
|
43280
|
-
const HSR_CACHE =
|
|
44425
|
+
const HSR_CACHE = new Cache();
|
|
43281
44426
|
function doHSR(totalUvToHits, targetCage, mesh, moveVerts = true, cacheStr) {
|
|
43282
44427
|
let closestVertIndexArr = void 0;
|
|
43283
44428
|
if (cacheStr) {
|
|
@@ -43785,7 +44930,7 @@ class MeshDesc {
|
|
|
43785
44930
|
}
|
|
43786
44931
|
threeMesh.castShadow = true;
|
|
43787
44932
|
threeMesh.geometry = geometry;
|
|
43788
|
-
threeMesh.name = this.instance?.PropOrDefault("Name", "Mesh");
|
|
44933
|
+
threeMesh.name = this.instance?.PropOrDefault("Name", "Mesh") + "_" + this.instance?.id;
|
|
43789
44934
|
threeMesh.scale.set(mesh.size[0], mesh.size[1], mesh.size[2]);
|
|
43790
44935
|
this.compilationTimestamp = Date.now() / 1e3;
|
|
43791
44936
|
return threeMesh;
|
|
@@ -43818,6 +44963,11 @@ class MeshDesc {
|
|
|
43818
44963
|
fromPart(child) {
|
|
43819
44964
|
this.canHaveSkinning = false;
|
|
43820
44965
|
if (child.className === "WedgePart") this.shape = "wedge";
|
|
44966
|
+
switch (child.PropOrDefault("Shape", PartType.Block)) {
|
|
44967
|
+
case PartType.Wedge:
|
|
44968
|
+
this.shape = "wedge";
|
|
44969
|
+
break;
|
|
44970
|
+
}
|
|
43821
44971
|
const specialMesh = child.FindFirstChildOfClass("SpecialMesh");
|
|
43822
44972
|
if (specialMesh) {
|
|
43823
44973
|
switch (specialMesh.Property("MeshType")) {
|
|
@@ -45324,10 +46474,13 @@ const __vite_glob_0_11 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.de
|
|
|
45324
46474
|
function diffCFrame(parent, child) {
|
|
45325
46475
|
return parent.inverse().multiply(child);
|
|
45326
46476
|
}
|
|
46477
|
+
function getBoneName(bone) {
|
|
46478
|
+
return bone.userData.name || bone.name.split("_").pop();
|
|
46479
|
+
}
|
|
45327
46480
|
function boneIsChildOf(bone, parentName) {
|
|
45328
46481
|
let nextParent = bone.parent;
|
|
45329
46482
|
while (nextParent) {
|
|
45330
|
-
if (nextParent
|
|
46483
|
+
if (getBoneName(nextParent) === parentName) {
|
|
45331
46484
|
return true;
|
|
45332
46485
|
}
|
|
45333
46486
|
nextParent = nextParent.parent;
|
|
@@ -45355,13 +46508,15 @@ class SkeletonDesc {
|
|
|
45355
46508
|
const boneArr = [];
|
|
45356
46509
|
for (let i = 0; i < skinning.bones.length; i++) {
|
|
45357
46510
|
const threeBone = new Bone();
|
|
45358
|
-
|
|
45359
|
-
if (
|
|
45360
|
-
|
|
46511
|
+
let boneName = skinning.bones[i].name || "";
|
|
46512
|
+
if (boneName === "HumanoidRootNode") {
|
|
46513
|
+
boneName = "HumanoidRootPart";
|
|
45361
46514
|
}
|
|
45362
|
-
if (
|
|
45363
|
-
|
|
46515
|
+
if (boneName === "root") {
|
|
46516
|
+
boneName = "Root";
|
|
45364
46517
|
}
|
|
46518
|
+
threeBone.name = "Skeleton_" + this.meshDesc.instance?.id + "_" + boneName;
|
|
46519
|
+
threeBone.userData.name = boneName;
|
|
45365
46520
|
boneArr.push(threeBone);
|
|
45366
46521
|
}
|
|
45367
46522
|
this.bones = boneArr;
|
|
@@ -45396,9 +46551,10 @@ class SkeletonDesc {
|
|
|
45396
46551
|
throw new Error("FileMesh has no root bone");
|
|
45397
46552
|
} else {
|
|
45398
46553
|
log(false, rootBone);
|
|
45399
|
-
if (rootBone && rootBone
|
|
46554
|
+
if (rootBone && getBoneName(rootBone) !== "Root") {
|
|
45400
46555
|
const trueRootBone = new Bone();
|
|
45401
|
-
trueRootBone.name = "
|
|
46556
|
+
trueRootBone.name = "Skeleton_" + this.meshDesc.instance?.id + "_Root";
|
|
46557
|
+
trueRootBone.userData.name = "Root";
|
|
45402
46558
|
trueRootBone.position.set(0, 0, 0);
|
|
45403
46559
|
trueRootBone.rotation.set(0, 0, 0, "YXZ");
|
|
45404
46560
|
this.boneSourceParts.unshift(void 0);
|
|
@@ -45426,7 +46582,7 @@ class SkeletonDesc {
|
|
|
45426
46582
|
}
|
|
45427
46583
|
getBoneWithName(name) {
|
|
45428
46584
|
for (const bone of this.bones) {
|
|
45429
|
-
if (bone
|
|
46585
|
+
if (getBoneName(bone) === name) {
|
|
45430
46586
|
return bone;
|
|
45431
46587
|
}
|
|
45432
46588
|
}
|
|
@@ -45475,13 +46631,13 @@ class SkeletonDesc {
|
|
|
45475
46631
|
return sourceNode;
|
|
45476
46632
|
}
|
|
45477
46633
|
getBoneWorldCFrame(bone, assembly, selfInstance, includeTransform) {
|
|
45478
|
-
const node = assembly.getNode(bone
|
|
46634
|
+
const node = assembly.getNode(getBoneName(bone));
|
|
45479
46635
|
const selfNode = selfInstance.w.GetAssemblyNode();
|
|
45480
46636
|
const sourceNode = this.getSourceNode(selfNode, bone, assembly);
|
|
45481
|
-
if (bone
|
|
46637
|
+
if (getBoneName(bone) === "Root") {
|
|
45482
46638
|
return assembly.traverseCFrame(selfNode, includeTransform, true);
|
|
45483
46639
|
} else if (node) {
|
|
45484
|
-
if (this.meshDesc.wasDeformed && !this.meshDesc.wasAutoSkinned && bone
|
|
46640
|
+
if (this.meshDesc.wasDeformed && !this.meshDesc.wasAutoSkinned && getBoneName(bone) === "Head") {
|
|
45485
46641
|
const ogCF = assembly.traverseCFrame(node, includeTransform, true);
|
|
45486
46642
|
const connectorOffset = node.getConnectorOffset(includeTransform).inverse();
|
|
45487
46643
|
connectorOffset.Orientation = [0, 0, 0];
|
|
@@ -45498,7 +46654,7 @@ class SkeletonDesc {
|
|
|
45498
46654
|
return this.meshDesc.fileMesh?.facs?.faceBoneNames.includes(boneName);
|
|
45499
46655
|
}
|
|
45500
46656
|
addFACS(restCF, bone, assembly) {
|
|
45501
|
-
const isFACS = this.isFACS(bone
|
|
46657
|
+
const isFACS = this.isFACS(getBoneName(bone));
|
|
45502
46658
|
if (!isFACS) return restCF;
|
|
45503
46659
|
const facsMesh = this.meshDesc.fileMesh;
|
|
45504
46660
|
const facs = this.meshDesc.fileMesh?.facs;
|
|
@@ -45513,7 +46669,7 @@ class SkeletonDesc {
|
|
|
45513
46669
|
new FaceControlsWrapper(faceControls);
|
|
45514
46670
|
for (let j = 0; j < facs.faceBoneNames.length; j++) {
|
|
45515
46671
|
const boneName = facs.faceBoneNames[j];
|
|
45516
|
-
if (boneName === bone
|
|
46672
|
+
if (boneName === getBoneName(bone)) {
|
|
45517
46673
|
let totalPosition = new Vector32();
|
|
45518
46674
|
let totalRotation = new Vector32();
|
|
45519
46675
|
for (let i = 0; i < facs.faceControlNames.length; i++) {
|
|
@@ -45576,7 +46732,7 @@ class SkeletonDesc {
|
|
|
45576
46732
|
let parentBone = bone.parent;
|
|
45577
46733
|
if (!(parentBone instanceof Bone)) parentBone = null;
|
|
45578
46734
|
if (bone && parentBone) {
|
|
45579
|
-
if ((boneIsChildOf(bone, "DynamicHead") || bone
|
|
46735
|
+
if ((boneIsChildOf(bone, "DynamicHead") || getBoneName(bone) === "DynamicHead") && this.meshDesc.wasDeformed && !this.meshDesc.wasAutoSkinned) {
|
|
45580
46736
|
const parentBoneWorldCFrame = this.getOriginalWorldCFrameNoChange(parentBone);
|
|
45581
46737
|
const boneWorldCFrameNoChange = this.getOriginalWorldCFrameNoChange(bone);
|
|
45582
46738
|
let diffCF = diffCFrame(parentBoneWorldCFrame, boneWorldCFrameNoChange);
|
|
@@ -50589,7 +51745,125 @@ class RBXRendererScene {
|
|
|
50589
51745
|
* @param autoDownload If resulting file should be auto downloaded
|
|
50590
51746
|
* @returns The GLB (buffer) or GLTF (object)
|
|
50591
51747
|
*/
|
|
50592
|
-
async exportGLTF(name = "scene", autoDownload = true) {
|
|
51748
|
+
async exportGLTF(name = "scene", autoDownload = true, options) {
|
|
51749
|
+
const actualOptions = {
|
|
51750
|
+
includeAnimations: false,
|
|
51751
|
+
binary: false
|
|
51752
|
+
};
|
|
51753
|
+
if (options) Object.assign(actualOptions, options);
|
|
51754
|
+
const clips = [];
|
|
51755
|
+
let animator = void 0;
|
|
51756
|
+
let allInstances = [];
|
|
51757
|
+
let rootInstance = void 0;
|
|
51758
|
+
const allRenderedInstances = Array.from(this.renderDescs.keys());
|
|
51759
|
+
let parent = allRenderedInstances[0].parent;
|
|
51760
|
+
while (parent !== void 0) {
|
|
51761
|
+
if (parent.parent === void 0) {
|
|
51762
|
+
rootInstance = parent;
|
|
51763
|
+
allInstances = [parent, ...parent.GetDescendants()];
|
|
51764
|
+
break;
|
|
51765
|
+
}
|
|
51766
|
+
parent = parent.parent;
|
|
51767
|
+
}
|
|
51768
|
+
for (const instance of allInstances) {
|
|
51769
|
+
if (instance.className === "Animator") {
|
|
51770
|
+
animator = instance;
|
|
51771
|
+
break;
|
|
51772
|
+
}
|
|
51773
|
+
}
|
|
51774
|
+
const GLTF_FPS = 30;
|
|
51775
|
+
if (animator && actualOptions.includeAnimations && rootInstance) {
|
|
51776
|
+
const w = animator.w;
|
|
51777
|
+
for (const animationEntryKey of Object.keys(w.data.animationSet)) {
|
|
51778
|
+
let trackIndex = 0;
|
|
51779
|
+
for (const animationEntry of w.data.animationSet[animationEntryKey]) {
|
|
51780
|
+
const track = w._getTrack(animationEntry.id);
|
|
51781
|
+
if (track) {
|
|
51782
|
+
const objectPositions = /* @__PURE__ */ new Map();
|
|
51783
|
+
const objectRotations = /* @__PURE__ */ new Map();
|
|
51784
|
+
const bonePositions = /* @__PURE__ */ new Map();
|
|
51785
|
+
const boneQuaternions = /* @__PURE__ */ new Map();
|
|
51786
|
+
track.weight = 1;
|
|
51787
|
+
const times = [];
|
|
51788
|
+
for (let i = 0; i < Math.max(1, Math.ceil(track.length * GLTF_FPS)); i++) {
|
|
51789
|
+
w.restPose();
|
|
51790
|
+
track.setTime(i / GLTF_FPS);
|
|
51791
|
+
if (w.data.currentMoodAnimationTrack) w.data.currentMoodAnimationTrack.setTime(0);
|
|
51792
|
+
times.push(i / GLTF_FPS);
|
|
51793
|
+
rootInstance.preRender();
|
|
51794
|
+
RBXRenderer.addInstance(rootInstance, new Authentication(), this);
|
|
51795
|
+
for (const instance of allRenderedInstances) {
|
|
51796
|
+
if (instance.className === "Attachment") continue;
|
|
51797
|
+
let isSkinned = false;
|
|
51798
|
+
const renderDesc = this.renderDescs.get(instance);
|
|
51799
|
+
if (renderDesc && renderDesc instanceof ObjectDesc && renderDesc.skeletonDesc) {
|
|
51800
|
+
isSkinned = true;
|
|
51801
|
+
const bones = renderDesc.skeletonDesc.bones;
|
|
51802
|
+
for (const bone of bones) {
|
|
51803
|
+
if (!bonePositions.has(bone)) bonePositions.set(bone, []);
|
|
51804
|
+
if (!boneQuaternions.has(bone)) boneQuaternions.set(bone, []);
|
|
51805
|
+
bonePositions.get(bone).push(bone.position.toArray());
|
|
51806
|
+
boneQuaternions.get(bone).push(bone.quaternion.toArray());
|
|
51807
|
+
}
|
|
51808
|
+
}
|
|
51809
|
+
let partToUse = instance;
|
|
51810
|
+
if (partToUse.className === "Decal" && partToUse.parent) {
|
|
51811
|
+
partToUse = partToUse.parent;
|
|
51812
|
+
}
|
|
51813
|
+
let cf = partToUse.PropOrDefault("CFrame", new CFrame());
|
|
51814
|
+
if (isSkinned) {
|
|
51815
|
+
cf = new CFrame();
|
|
51816
|
+
}
|
|
51817
|
+
if (!objectPositions.has(instance)) objectPositions.set(instance, []);
|
|
51818
|
+
if (!objectRotations.has(instance)) objectRotations.set(instance, []);
|
|
51819
|
+
objectPositions.get(instance).push(cf.Position);
|
|
51820
|
+
objectRotations.get(instance).push([rad(cf.Orientation[0]), rad(cf.Orientation[1]), rad(cf.Orientation[2])]);
|
|
51821
|
+
}
|
|
51822
|
+
}
|
|
51823
|
+
const keyframeTracks = [];
|
|
51824
|
+
for (const instance of allRenderedInstances) {
|
|
51825
|
+
if (instance.className === "Attachment") continue;
|
|
51826
|
+
const thisPositions = objectPositions.get(instance);
|
|
51827
|
+
const thisRotations = objectRotations.get(instance);
|
|
51828
|
+
if (thisPositions && thisRotations) {
|
|
51829
|
+
const instanceName = instance.PropOrDefault("Name", "Mesh") + "_" + instance.id;
|
|
51830
|
+
keyframeTracks.push(new VectorKeyframeTrack(instanceName + ".position", times, thisPositions.flat()));
|
|
51831
|
+
const quaternionValues = [];
|
|
51832
|
+
for (const rotationValue of thisRotations) {
|
|
51833
|
+
const quat = new Quaternion().setFromEuler(new Euler(...rotationValue, "YXZ"));
|
|
51834
|
+
quaternionValues.push(quat.x, quat.y, quat.z, quat.w);
|
|
51835
|
+
}
|
|
51836
|
+
keyframeTracks.push(new QuaternionKeyframeTrack(instanceName + ".quaternion", times, quaternionValues));
|
|
51837
|
+
}
|
|
51838
|
+
const renderDesc = this.renderDescs.get(instance);
|
|
51839
|
+
if (renderDesc && renderDesc instanceof ObjectDesc && renderDesc.skeletonDesc) {
|
|
51840
|
+
const bones = renderDesc.skeletonDesc.bones;
|
|
51841
|
+
for (const bone of bones) {
|
|
51842
|
+
const thisBonePositions = bonePositions.get(bone);
|
|
51843
|
+
const thisBoneQuaternions = boneQuaternions.get(bone);
|
|
51844
|
+
if (thisBonePositions && thisBoneQuaternions) {
|
|
51845
|
+
keyframeTracks.push(new VectorKeyframeTrack(bone.name + ".position", times, thisBonePositions.flat()));
|
|
51846
|
+
keyframeTracks.push(new QuaternionKeyframeTrack(bone.name + ".quaternion", times, thisBoneQuaternions.flat()));
|
|
51847
|
+
}
|
|
51848
|
+
}
|
|
51849
|
+
}
|
|
51850
|
+
}
|
|
51851
|
+
const clip = new AnimationClip(animationEntryKey + "_" + trackIndex, track.length, keyframeTracks);
|
|
51852
|
+
clips.push(clip);
|
|
51853
|
+
console.log(`Generated clip (${clip.name}) with ${clip.tracks.length} tracks and length of ${track.length}`);
|
|
51854
|
+
}
|
|
51855
|
+
trackIndex += 1;
|
|
51856
|
+
}
|
|
51857
|
+
}
|
|
51858
|
+
w.restPose();
|
|
51859
|
+
rootInstance.preRender();
|
|
51860
|
+
RBXRenderer.addInstance(rootInstance, new Authentication(), this);
|
|
51861
|
+
}
|
|
51862
|
+
for (const renderedInstance of allRenderedInstances) {
|
|
51863
|
+
if (this.renderDescs.get(renderedInstance) instanceof EmitterGroupDesc) {
|
|
51864
|
+
RBXRenderer.removeInstance(renderedInstance, this);
|
|
51865
|
+
}
|
|
51866
|
+
}
|
|
50593
51867
|
return new Promise((resolve, reject) => {
|
|
50594
51868
|
const exporter = new GLTFExporter();
|
|
50595
51869
|
exporter.parse(this.scene, (gltf) => {
|
|
@@ -50603,6 +51877,9 @@ class RBXRendererScene {
|
|
|
50603
51877
|
resolve(gltf);
|
|
50604
51878
|
}, (error2) => {
|
|
50605
51879
|
reject(error2);
|
|
51880
|
+
}, {
|
|
51881
|
+
animations: clips,
|
|
51882
|
+
binary: actualOptions.binary
|
|
50606
51883
|
});
|
|
50607
51884
|
});
|
|
50608
51885
|
}
|
|
@@ -51772,7 +53049,7 @@ async function renderTargetToCanvas(renderTarget) {
|
|
|
51772
53049
|
await rbxRenderer.readRenderTargetPixelsAsync(renderTarget, 0, 0, width, height, data);
|
|
51773
53050
|
return imageDataToCanvas(data, width, height);
|
|
51774
53051
|
}
|
|
51775
|
-
async function generateModelThumbnail(auth, renderScene, model, size = [150, 150], type = "png", quality = 1, gltfAutoDownload = false) {
|
|
53052
|
+
async function generateModelThumbnail(auth, renderScene, model, size = [150, 150], type = "png", quality = 1, gltfAutoDownload = false, includeAnimations = false) {
|
|
51776
53053
|
return new Promise((resolve) => {
|
|
51777
53054
|
const cameraCFrame = getThumbnailCameraCFrame(model);
|
|
51778
53055
|
if (cameraCFrame) {
|
|
@@ -51791,11 +53068,14 @@ async function generateModelThumbnail(auth, renderScene, model, size = [150, 150
|
|
|
51791
53068
|
});
|
|
51792
53069
|
async function doExport() {
|
|
51793
53070
|
onLoadingConnection.Disconnect();
|
|
51794
|
-
if (type === "gltf") {
|
|
53071
|
+
if (type === "gltf" || type === "glb") {
|
|
51795
53072
|
if (!FLAGS.RENDERTARGET_TO_CANVASTEXTURE && FLAGS.USE_RENDERTARGET) {
|
|
51796
53073
|
warn(true, "FLAGS.RENDERTARGET_TO_CANVASTEXTURE is false, GLTF export cannot export render target textures, consider setting this flag to true");
|
|
51797
53074
|
}
|
|
51798
|
-
resolve(await renderScene.exportGLTF(`result`, gltfAutoDownload
|
|
53075
|
+
resolve(await renderScene.exportGLTF(`result`, gltfAutoDownload, {
|
|
53076
|
+
includeAnimations,
|
|
53077
|
+
binary: type === "glb"
|
|
53078
|
+
}));
|
|
51799
53079
|
} else {
|
|
51800
53080
|
const renderTarget = renderToRenderTarget(...size, renderScene);
|
|
51801
53081
|
const canvasTarget = await renderTargetToCanvas(renderTarget);
|
|
@@ -51809,7 +53089,7 @@ async function generateModelThumbnail(auth, renderScene, model, size = [150, 150
|
|
|
51809
53089
|
}
|
|
51810
53090
|
});
|
|
51811
53091
|
}
|
|
51812
|
-
async function generateOutfitThumbnail(auth, outfit, size = [150, 150], type = "png", quality = 1, gltfAutoDownload = false) {
|
|
53092
|
+
async function generateOutfitThumbnail(auth, outfit, size = [150, 150], type = "png", quality = 1, gltfAutoDownload = false, includeAnimations = false) {
|
|
51813
53093
|
return new Promise((resolve) => {
|
|
51814
53094
|
const startTime = performance.now();
|
|
51815
53095
|
const renderScene = RBXRenderer.addScene();
|
|
@@ -51849,7 +53129,7 @@ async function generateOutfitThumbnail(auth, outfit, size = [150, 150], type = "
|
|
|
51849
53129
|
onLoadingConnection.Disconnect();
|
|
51850
53130
|
if (outfitRenderer.currentRig) {
|
|
51851
53131
|
outfitRenderer.animateOnce(!outfit.containsAssetType("Gear") && outfit.playerAvatarType === AvatarType.R6 ? 0 : 1);
|
|
51852
|
-
const thumbnailResult = await generateModelThumbnail(auth, renderScene, outfitRenderer.currentRig, size, type, quality, gltfAutoDownload);
|
|
53132
|
+
const thumbnailResult = await generateModelThumbnail(auth, renderScene, outfitRenderer.currentRig, size, type, quality, gltfAutoDownload, includeAnimations);
|
|
51853
53133
|
console.log("Generated outfit thumbnail after seconds:", (performance.now() - startTime) / 1e3);
|
|
51854
53134
|
resolve(thumbnailResult);
|
|
51855
53135
|
if (outfitRenderer.currentRig) outfitRenderer.currentRig.Destroy();
|
|
@@ -51934,6 +53214,7 @@ export {
|
|
|
51934
53214
|
CACHE,
|
|
51935
53215
|
CFrame,
|
|
51936
53216
|
COREMESH,
|
|
53217
|
+
Cache,
|
|
51937
53218
|
CatalogBundleTypes,
|
|
51938
53219
|
CategoryDictionary,
|
|
51939
53220
|
Color3,
|