roavatar-renderer 1.6.0 → 1.6.2
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.d.ts +126 -8
- package/dist/index.js +865 -304
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -30279,6 +30279,16 @@ class RBXSimpleView {
|
|
|
30279
30279
|
}
|
|
30280
30280
|
const magic = "<roblox!";
|
|
30281
30281
|
const xmlMagic = "<roblox ";
|
|
30282
|
+
const CameraType = {
|
|
30283
|
+
"Fixed": 0,
|
|
30284
|
+
"Attach": 1,
|
|
30285
|
+
"Watch": 2,
|
|
30286
|
+
"Track": 3,
|
|
30287
|
+
"Follow": 4,
|
|
30288
|
+
"Custom": 5,
|
|
30289
|
+
"Scriptable": 6,
|
|
30290
|
+
"Orbital": 7
|
|
30291
|
+
};
|
|
30282
30292
|
const ParticleFlipbookLayout = {
|
|
30283
30293
|
"None": 0,
|
|
30284
30294
|
"Grid2x2": 1,
|
|
@@ -30436,6 +30446,24 @@ const BodyPartNameToEnum = {
|
|
|
30436
30446
|
"UpperTorso": BodyPart.Torso,
|
|
30437
30447
|
"LowerTorso": BodyPart.Torso
|
|
30438
30448
|
};
|
|
30449
|
+
const R6BodyPartNames = ["Head", "Torso", "Left Arm", "Right Arm", "Left Leg", "Right Leg"];
|
|
30450
|
+
const R15BodyPartNames = [
|
|
30451
|
+
"Head",
|
|
30452
|
+
"UpperTorso",
|
|
30453
|
+
"LowerTorso",
|
|
30454
|
+
"LeftUpperArm",
|
|
30455
|
+
"LeftLowerArm",
|
|
30456
|
+
"LeftHand",
|
|
30457
|
+
"RightUpperArm",
|
|
30458
|
+
"RightLowerArm",
|
|
30459
|
+
"RightHand",
|
|
30460
|
+
"LeftUpperLeg",
|
|
30461
|
+
"LeftLowerLeg",
|
|
30462
|
+
"LeftFoot",
|
|
30463
|
+
"RightUpperLeg",
|
|
30464
|
+
"RightLowerLeg",
|
|
30465
|
+
"RightFoot"
|
|
30466
|
+
];
|
|
30439
30467
|
const BodyPartEnumToNames = {
|
|
30440
30468
|
[BodyPart.Head]: ["Head"],
|
|
30441
30469
|
[BodyPart.Torso]: ["Torso", "UpperTorso", "LowerTorso"],
|
|
@@ -32744,6 +32772,9 @@ class InstanceWrapper {
|
|
|
32744
32772
|
}
|
|
32745
32773
|
}
|
|
32746
32774
|
}
|
|
32775
|
+
addProp(name, type, value) {
|
|
32776
|
+
if (!this.instance.HasProperty(name)) this.instance.addProperty(new Property(name, type), value);
|
|
32777
|
+
}
|
|
32747
32778
|
setup() {
|
|
32748
32779
|
throw new Error("Virtual method setup() called");
|
|
32749
32780
|
}
|
|
@@ -32783,7 +32814,7 @@ class InstanceWrapper {
|
|
|
32783
32814
|
preRender() {
|
|
32784
32815
|
}
|
|
32785
32816
|
}
|
|
32786
|
-
const
|
|
32817
|
+
const __vite_glob_0_14 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
32787
32818
|
__proto__: null,
|
|
32788
32819
|
GetWrapperForInstance,
|
|
32789
32820
|
InstanceWrapper
|
|
@@ -32899,6 +32930,13 @@ class Vector3 {
|
|
|
32899
32930
|
isSame(other) {
|
|
32900
32931
|
return isSameFloat(this.X, other.X) && isSameFloat(this.Y, other.Y) && isSameFloat(this.Z, other.Z);
|
|
32901
32932
|
}
|
|
32933
|
+
lerp(other, t) {
|
|
32934
|
+
return new Vector3(
|
|
32935
|
+
lerp(this.X, other.X, t),
|
|
32936
|
+
lerp(this.Y, other.Y, t),
|
|
32937
|
+
lerp(this.Z, other.Z, t)
|
|
32938
|
+
);
|
|
32939
|
+
}
|
|
32902
32940
|
static new(X, Y, Z) {
|
|
32903
32941
|
return new Vector3(X, Y, Z);
|
|
32904
32942
|
}
|
|
@@ -33128,6 +33166,11 @@ class CFrame {
|
|
|
33128
33166
|
constructor(x = 0, y = 0, z = 0) {
|
|
33129
33167
|
this.Position = [x, y, z];
|
|
33130
33168
|
}
|
|
33169
|
+
static Angles(x, y, z) {
|
|
33170
|
+
const cf = new CFrame();
|
|
33171
|
+
cf.Orientation = [x, y, z];
|
|
33172
|
+
return cf;
|
|
33173
|
+
}
|
|
33131
33174
|
clone() {
|
|
33132
33175
|
const cloneCF = new CFrame(this.Position[0], this.Position[1], this.Position[2]);
|
|
33133
33176
|
cloneCF.Orientation = [this.Orientation[0], this.Orientation[1], this.Orientation[2]];
|
|
@@ -33198,6 +33241,17 @@ class CFrame {
|
|
|
33198
33241
|
const matrix = new Matrix4().makeRotationFromEuler(new Euler(rx, ry, rz, order));
|
|
33199
33242
|
return new CFrame().fromMatrix(matrix.elements);
|
|
33200
33243
|
}
|
|
33244
|
+
rotationOnly() {
|
|
33245
|
+
const copy = this.clone();
|
|
33246
|
+
copy.Position = [0, 0, 0];
|
|
33247
|
+
return copy;
|
|
33248
|
+
}
|
|
33249
|
+
toEulerAngles(order = "XYZ") {
|
|
33250
|
+
const [rx, ry, rz] = this.Orientation;
|
|
33251
|
+
let euler = new Euler(rad(rx), rad(ry), rad(rz), "YXZ");
|
|
33252
|
+
euler = euler.reorder(order);
|
|
33253
|
+
return euler.toArray();
|
|
33254
|
+
}
|
|
33201
33255
|
inverse() {
|
|
33202
33256
|
const thisM = new Matrix4().fromArray(this.getMatrix());
|
|
33203
33257
|
const inverse = thisM.clone();
|
|
@@ -33211,6 +33265,26 @@ class CFrame {
|
|
|
33211
33265
|
const newCf = new CFrame().fromMatrix(newM.elements);
|
|
33212
33266
|
return newCf;
|
|
33213
33267
|
}
|
|
33268
|
+
multiplyVector(vector) {
|
|
33269
|
+
const vectorCF = new CFrame(...vector.toVec3());
|
|
33270
|
+
const resultCF = this.multiply(vectorCF);
|
|
33271
|
+
const resultVector = new Vector3(...resultCF.Position);
|
|
33272
|
+
return resultVector;
|
|
33273
|
+
}
|
|
33274
|
+
removeNaN(newValue = 0) {
|
|
33275
|
+
const newCF = new CFrame();
|
|
33276
|
+
newCF.Position = [
|
|
33277
|
+
isNaN(this.Position[0]) ? newValue : this.Position[0],
|
|
33278
|
+
isNaN(this.Position[1]) ? newValue : this.Position[1],
|
|
33279
|
+
isNaN(this.Position[2]) ? newValue : this.Position[2]
|
|
33280
|
+
];
|
|
33281
|
+
newCF.Orientation = [
|
|
33282
|
+
isNaN(this.Orientation[0]) ? newValue : this.Orientation[0],
|
|
33283
|
+
isNaN(this.Orientation[1]) ? newValue : this.Orientation[1],
|
|
33284
|
+
isNaN(this.Orientation[2]) ? newValue : this.Orientation[2]
|
|
33285
|
+
];
|
|
33286
|
+
return newCF;
|
|
33287
|
+
}
|
|
33214
33288
|
isSame(other) {
|
|
33215
33289
|
return isSameFloat(this.Position[0], other.Position[0]) && isSameFloat(this.Position[1], other.Position[1]) && isSameFloat(this.Position[2], other.Position[2]) && isSameFloat(this.Orientation[0], other.Orientation[0]) && isSameFloat(this.Orientation[1], other.Orientation[1]) && isSameFloat(this.Orientation[2], other.Orientation[2]);
|
|
33216
33290
|
}
|
|
@@ -36917,8 +36991,10 @@ class LocalOutfit {
|
|
|
36917
36991
|
this.bg = data.bg || 0;
|
|
36918
36992
|
return this;
|
|
36919
36993
|
}
|
|
36920
|
-
update(
|
|
36994
|
+
update(outfitModel) {
|
|
36995
|
+
const outfit = outfitModel instanceof OutfitModel ? outfitModel.outfit : outfitModel;
|
|
36921
36996
|
this.buffer = arrayBufferToBase64(outfit.toBuffer());
|
|
36997
|
+
if (outfitModel instanceof OutfitModel) this.bg = outfitModel.background?.id || 0;
|
|
36922
36998
|
this.image = void 0;
|
|
36923
36999
|
}
|
|
36924
37000
|
/**
|
|
@@ -39122,8 +39198,15 @@ const API = {
|
|
|
39122
39198
|
return response;
|
|
39123
39199
|
}
|
|
39124
39200
|
},
|
|
39201
|
+
GetUserAvatarModel: async function(userId) {
|
|
39202
|
+
const response = await RBLXGet(`https://avatar.roblox.com/v4/avatar/users/${userId}?selectionTypes=0&selectionTypes=1&selectionTypes=2&selectionTypes=3&selectionTypes=4&selectionTypes=5&selectionTypes=6`);
|
|
39203
|
+
if (response.status !== 200) return response;
|
|
39204
|
+
const body = await response.json();
|
|
39205
|
+
const outfitModel = new OutfitModel().fromJson(body);
|
|
39206
|
+
return outfitModel;
|
|
39207
|
+
},
|
|
39125
39208
|
GetAvatarModel: async function() {
|
|
39126
|
-
const response = await RBLXGet("https://avatar.roblox.com/v4/avatar?selectionTypes=0&selectionTypes=1&selectionTypes=2&selectionTypes=3&selectionTypes=4&selectionTypes=5");
|
|
39209
|
+
const response = await RBLXGet("https://avatar.roblox.com/v4/avatar?selectionTypes=0&selectionTypes=1&selectionTypes=2&selectionTypes=3&selectionTypes=4&selectionTypes=5&selectionTypes=6");
|
|
39127
39210
|
if (response.status !== 200) return response;
|
|
39128
39211
|
const body = await response.json();
|
|
39129
39212
|
const outfitModel = new OutfitModel().fromJson(body);
|
|
@@ -43484,7 +43567,7 @@ class ConstraintWrapper extends InstanceWrapper {
|
|
|
43484
43567
|
if (!this.instance.HasProperty("Attachment1")) this.instance.addProperty(new Property("Attachment1", DataType.Referent), void 0);
|
|
43485
43568
|
}
|
|
43486
43569
|
}
|
|
43487
|
-
const
|
|
43570
|
+
const __vite_glob_0_10 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
43488
43571
|
__proto__: null,
|
|
43489
43572
|
ConstraintWrapper
|
|
43490
43573
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -45902,7 +45985,7 @@ class MeshDesc {
|
|
|
45902
45985
|
const wrapTarget = child.parent?.parent?.FindFirstChildOfClass("WrapTarget");
|
|
45903
45986
|
if (wrapTarget) {
|
|
45904
45987
|
this.wrapTextureTarget = wrapTarget.Prop("CageMeshId");
|
|
45905
|
-
this.wrapTextureTargetOrigin = wrapTarget.Prop("CageOrigin");
|
|
45988
|
+
this.wrapTextureTargetOrigin = wrapTarget.Prop("CageOrigin").removeNaN();
|
|
45906
45989
|
}
|
|
45907
45990
|
}
|
|
45908
45991
|
}
|
|
@@ -47330,7 +47413,7 @@ class FaceControlsWrapper extends InstanceWrapper {
|
|
|
47330
47413
|
}
|
|
47331
47414
|
}
|
|
47332
47415
|
}
|
|
47333
|
-
const
|
|
47416
|
+
const __vite_glob_0_12 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
47334
47417
|
__proto__: null,
|
|
47335
47418
|
FaceControlsWrapper
|
|
47336
47419
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -47778,51 +47861,54 @@ class ObjectDesc extends RenderDesc {
|
|
|
47778
47861
|
async compileResults(renderer, scene) {
|
|
47779
47862
|
const loadingLabel = this.instance ? this.instance.GetFullName() : "unknown";
|
|
47780
47863
|
API.Misc.startCurrentlyLoadingAssets(loadingLabel);
|
|
47781
|
-
|
|
47782
|
-
|
|
47783
|
-
|
|
47784
|
-
|
|
47785
|
-
|
|
47786
|
-
|
|
47787
|
-
|
|
47788
|
-
|
|
47789
|
-
|
|
47790
|
-
|
|
47791
|
-
|
|
47864
|
+
try {
|
|
47865
|
+
const originalResult = this.results;
|
|
47866
|
+
const originalSkeletonDesc = this.skeletonDesc;
|
|
47867
|
+
this.results = void 0;
|
|
47868
|
+
this.skeletonDesc = void 0;
|
|
47869
|
+
const promises = [
|
|
47870
|
+
this.meshDesc.compileMesh(),
|
|
47871
|
+
this.materialDesc.compileMaterial(this.meshDesc)
|
|
47872
|
+
];
|
|
47873
|
+
const [threeMesh, threeMaterial] = await Promise.all(promises);
|
|
47874
|
+
if (!(threeMesh instanceof Mesh)) {
|
|
47875
|
+
warn(true, "Failed to get mesh for objectDesc", this.instance ? this.instance.GetFullName() : "unknown");
|
|
47876
|
+
API.Misc.stopCurrentlyLoadingAssets(loadingLabel);
|
|
47877
|
+
return threeMesh;
|
|
47878
|
+
}
|
|
47879
|
+
if (threeMesh instanceof SkinnedMesh) {
|
|
47880
|
+
threeMaterial.skinning = true;
|
|
47881
|
+
this.isSkinned = true;
|
|
47882
|
+
}
|
|
47883
|
+
threeMesh.material = threeMaterial;
|
|
47884
|
+
threeMesh.receiveShadow = true;
|
|
47885
|
+
threeMaterial.needsUpdate = true;
|
|
47886
|
+
threeMesh.visible = threeMaterial.visible;
|
|
47887
|
+
this.results = [threeMesh];
|
|
47888
|
+
this.originalScale = threeMesh.scale.clone();
|
|
47889
|
+
if (!this.meshDesc.scaleIsRelative) {
|
|
47890
|
+
threeMesh.scale.set(this.size.X, this.size.Y, this.size.Z);
|
|
47891
|
+
} else {
|
|
47892
|
+
const oldSize = this.originalScale;
|
|
47893
|
+
threeMesh.scale.set(this.size.X / oldSize.x, this.size.Y / oldSize.y, this.size.Z / oldSize.z);
|
|
47894
|
+
}
|
|
47895
|
+
if (SkeletonDesc.descNeedsSkeleton(this.meshDesc)) {
|
|
47896
|
+
this.skeletonDesc = new SkeletonDesc(this, this.meshDesc, scene);
|
|
47897
|
+
} else {
|
|
47898
|
+
this.meshDesc.fileMesh = void 0;
|
|
47899
|
+
}
|
|
47900
|
+
if (originalResult) {
|
|
47901
|
+
this.disposeMeshes(scene, originalResult);
|
|
47902
|
+
}
|
|
47903
|
+
if (originalSkeletonDesc) {
|
|
47904
|
+
this.disposeSkeleton(scene, originalSkeletonDesc);
|
|
47905
|
+
}
|
|
47906
|
+
if (originalResult) {
|
|
47907
|
+
this.disposeRenderLists(renderer);
|
|
47908
|
+
}
|
|
47909
|
+
} finally {
|
|
47792
47910
|
API.Misc.stopCurrentlyLoadingAssets(loadingLabel);
|
|
47793
|
-
return threeMesh;
|
|
47794
|
-
}
|
|
47795
|
-
if (threeMesh instanceof SkinnedMesh) {
|
|
47796
|
-
threeMaterial.skinning = true;
|
|
47797
|
-
this.isSkinned = true;
|
|
47798
|
-
}
|
|
47799
|
-
threeMesh.material = threeMaterial;
|
|
47800
|
-
threeMesh.receiveShadow = true;
|
|
47801
|
-
threeMaterial.needsUpdate = true;
|
|
47802
|
-
threeMesh.visible = threeMaterial.visible;
|
|
47803
|
-
this.results = [threeMesh];
|
|
47804
|
-
this.originalScale = threeMesh.scale.clone();
|
|
47805
|
-
if (!this.meshDesc.scaleIsRelative) {
|
|
47806
|
-
threeMesh.scale.set(this.size.X, this.size.Y, this.size.Z);
|
|
47807
|
-
} else {
|
|
47808
|
-
const oldSize = this.originalScale;
|
|
47809
|
-
threeMesh.scale.set(this.size.X / oldSize.x, this.size.Y / oldSize.y, this.size.Z / oldSize.z);
|
|
47810
|
-
}
|
|
47811
|
-
if (SkeletonDesc.descNeedsSkeleton(this.meshDesc)) {
|
|
47812
|
-
this.skeletonDesc = new SkeletonDesc(this, this.meshDesc, scene);
|
|
47813
|
-
} else {
|
|
47814
|
-
this.meshDesc.fileMesh = void 0;
|
|
47815
|
-
}
|
|
47816
|
-
if (originalResult) {
|
|
47817
|
-
this.disposeMeshes(scene, originalResult);
|
|
47818
|
-
}
|
|
47819
|
-
if (originalSkeletonDesc) {
|
|
47820
|
-
this.disposeSkeleton(scene, originalSkeletonDesc);
|
|
47821
|
-
}
|
|
47822
|
-
if (originalResult) {
|
|
47823
|
-
this.disposeRenderLists(renderer);
|
|
47824
47911
|
}
|
|
47825
|
-
API.Misc.stopCurrentlyLoadingAssets(loadingLabel);
|
|
47826
47912
|
return this.results;
|
|
47827
47913
|
}
|
|
47828
47914
|
getScale() {
|
|
@@ -48746,7 +48832,7 @@ class AnimationTrack {
|
|
|
48746
48832
|
tick(deltaTime = 1 / 60) {
|
|
48747
48833
|
const addTime = deltaTime * this.pSpeed;
|
|
48748
48834
|
this.pFadedTime += addTime;
|
|
48749
|
-
const newWeight = lerp(this.pOriginalWeight, this.pTargetWeight, specialClamp(this.pFadedTime / this.pFadeTime, 0, 1));
|
|
48835
|
+
const newWeight = this.pFadeTime === 0 ? this.pTargetWeight : lerp(this.pOriginalWeight, this.pTargetWeight, specialClamp(this.pFadedTime / this.pFadeTime, 0, 1));
|
|
48750
48836
|
this.weight = newWeight;
|
|
48751
48837
|
const ogTime = this.timePosition;
|
|
48752
48838
|
if (this.weight >= 0.01) {
|
|
@@ -48769,6 +48855,7 @@ class AnimatorWrapperData {
|
|
|
48769
48855
|
toolTracks = [];
|
|
48770
48856
|
toolAddedConnection;
|
|
48771
48857
|
toolRemovedConnection;
|
|
48858
|
+
forceTransitionTime;
|
|
48772
48859
|
}
|
|
48773
48860
|
class AnimatorWrapper extends InstanceWrapper {
|
|
48774
48861
|
static className = "Animator";
|
|
@@ -48838,7 +48925,7 @@ class AnimatorWrapper extends InstanceWrapper {
|
|
|
48838
48925
|
const realId = BigInt(API.Misc.idFromStr(id));
|
|
48839
48926
|
return this.data.animationTracks.get(realId);
|
|
48840
48927
|
}
|
|
48841
|
-
_switchAnimation(name) {
|
|
48928
|
+
_switchAnimation(name, subAnimSpecifier) {
|
|
48842
48929
|
let transitionTime = 0.2;
|
|
48843
48930
|
if (name === this.data.currentAnimation) {
|
|
48844
48931
|
transitionTime = 0.15;
|
|
@@ -48851,7 +48938,8 @@ class AnimatorWrapper extends InstanceWrapper {
|
|
|
48851
48938
|
if (!name.startsWith("emote.") && !name.startsWith("id.")) {
|
|
48852
48939
|
const entries = this.data.animationSet[name];
|
|
48853
48940
|
if (entries && entries.length > 0) {
|
|
48854
|
-
const
|
|
48941
|
+
const isSpecificSub = subAnimSpecifier !== void 0 && subAnimSpecifier >= 0;
|
|
48942
|
+
const entry = (isSpecificSub ? entries[subAnimSpecifier] : this._pickRandom(entries)) || entries[0];
|
|
48855
48943
|
if (entry) {
|
|
48856
48944
|
toPlayTrack = this._getTrack(entry.id);
|
|
48857
48945
|
}
|
|
@@ -48877,7 +48965,7 @@ class AnimatorWrapper extends InstanceWrapper {
|
|
|
48877
48965
|
this.data.currentAnimationTrack = void 0;
|
|
48878
48966
|
this.data.currentAnimationTrack = toPlayTrack;
|
|
48879
48967
|
if (toPlayTrack) {
|
|
48880
|
-
toPlayTrack.Play(transitionTime);
|
|
48968
|
+
toPlayTrack.Play(this.data.forceTransitionTime === void 0 ? transitionTime : this.data.forceTransitionTime);
|
|
48881
48969
|
}
|
|
48882
48970
|
}
|
|
48883
48971
|
}
|
|
@@ -48915,7 +49003,7 @@ class AnimatorWrapper extends InstanceWrapper {
|
|
|
48915
49003
|
this.data.moodTracks.push(toPlayTrack);
|
|
48916
49004
|
}
|
|
48917
49005
|
this.data.currentMoodAnimationTrack = toPlayTrack;
|
|
48918
|
-
toPlayTrack.Play(transitionTime);
|
|
49006
|
+
toPlayTrack.Play(this.data.forceTransitionTime === void 0 ? transitionTime : this.data.forceTransitionTime);
|
|
48919
49007
|
}
|
|
48920
49008
|
}
|
|
48921
49009
|
return !!toPlayTrack;
|
|
@@ -48952,7 +49040,7 @@ class AnimatorWrapper extends InstanceWrapper {
|
|
|
48952
49040
|
this.data.toolTracks.push(toPlayTrack);
|
|
48953
49041
|
}
|
|
48954
49042
|
this.data.currentToolAnimationTrack = toPlayTrack;
|
|
48955
|
-
toPlayTrack.Play(transitionTime);
|
|
49043
|
+
toPlayTrack.Play(this.data.forceTransitionTime === void 0 ? transitionTime : this.data.forceTransitionTime);
|
|
48956
49044
|
}
|
|
48957
49045
|
}
|
|
48958
49046
|
return !!toPlayTrack;
|
|
@@ -49158,27 +49246,20 @@ class AnimatorWrapper extends InstanceWrapper {
|
|
|
49158
49246
|
if (subAnimIdStr.length > 0) {
|
|
49159
49247
|
const subAnimId = BigInt(API.Misc.idFromStr(subAnimIdStr));
|
|
49160
49248
|
const foundAnimTrack = this.data.animationTracks.get(subAnimId);
|
|
49249
|
+
if (!this.data.animationSet[animName]) {
|
|
49250
|
+
this.data.animationSet[animName] = [];
|
|
49251
|
+
}
|
|
49252
|
+
this.data.animationSet[animName].push({
|
|
49253
|
+
id: `rbxassetid://${subAnimId}`,
|
|
49254
|
+
weight: subWeight
|
|
49255
|
+
});
|
|
49161
49256
|
if (foundAnimTrack) {
|
|
49162
49257
|
if (forceLoop) {
|
|
49163
49258
|
foundAnimTrack.looped = true;
|
|
49164
49259
|
}
|
|
49165
|
-
if (!this.data.animationSet[animName]) {
|
|
49166
|
-
this.data.animationSet[animName] = [];
|
|
49167
|
-
}
|
|
49168
|
-
this.data.animationSet[animName].push({
|
|
49169
|
-
id: `rbxassetid://${subAnimId}`,
|
|
49170
|
-
weight: subWeight
|
|
49171
|
-
});
|
|
49172
49260
|
} else {
|
|
49173
49261
|
promises.push(new Promise((resolve) => {
|
|
49174
49262
|
this.loadAnimation(subAnimId, forceLoop).then((result) => {
|
|
49175
|
-
if (!this.data.animationSet[animName]) {
|
|
49176
|
-
this.data.animationSet[animName] = [];
|
|
49177
|
-
}
|
|
49178
|
-
this.data.animationSet[animName].push({
|
|
49179
|
-
id: `rbxassetid://${subAnimId}`,
|
|
49180
|
-
weight: subWeight
|
|
49181
|
-
});
|
|
49182
49263
|
resolve(result instanceof Response ? result : void 0);
|
|
49183
49264
|
});
|
|
49184
49265
|
}));
|
|
@@ -49217,7 +49298,7 @@ class AnimatorWrapper extends InstanceWrapper {
|
|
|
49217
49298
|
}
|
|
49218
49299
|
/**
|
|
49219
49300
|
* Switches to new animation
|
|
49220
|
-
* @param name Animation name, such as "idle", "walk", "emote.1234" or "id.1234"
|
|
49301
|
+
* @param name Animation name, such as "idle", "walk", "emote.1234" or "id.1234", can also specify sub animation like "idle:0"
|
|
49221
49302
|
* @param type
|
|
49222
49303
|
* @returns If animation sucessfully played
|
|
49223
49304
|
*/
|
|
@@ -49234,16 +49315,23 @@ class AnimatorWrapper extends InstanceWrapper {
|
|
|
49234
49315
|
this.restPose(false, true);
|
|
49235
49316
|
}
|
|
49236
49317
|
}
|
|
49318
|
+
let subAnimSpecifier = -1;
|
|
49319
|
+
if (name.includes(":")) {
|
|
49320
|
+
const splitName = name.split(":");
|
|
49321
|
+
name = splitName[0];
|
|
49322
|
+
subAnimSpecifier = Number(splitName[1]);
|
|
49323
|
+
}
|
|
49237
49324
|
switch (type) {
|
|
49238
49325
|
case "main":
|
|
49239
|
-
if (this.data.currentAnimation !== name) {
|
|
49326
|
+
if (this.data.currentAnimation !== name || subAnimSpecifier !== -1) {
|
|
49240
49327
|
if (!name.startsWith("emote.") || staticFacialAnimation) {
|
|
49241
49328
|
this.playAnimation("mood", "mood");
|
|
49242
49329
|
} else {
|
|
49243
49330
|
this.stopMoodAnimation();
|
|
49244
49331
|
}
|
|
49245
49332
|
log(false, "playing", name);
|
|
49246
|
-
|
|
49333
|
+
log(false, this.data.forceTransitionTime);
|
|
49334
|
+
return this._switchAnimation(name, subAnimSpecifier);
|
|
49247
49335
|
} else {
|
|
49248
49336
|
return true;
|
|
49249
49337
|
}
|
|
@@ -49392,6 +49480,25 @@ const __vite_glob_0_8 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def
|
|
|
49392
49480
|
__proto__: null,
|
|
49393
49481
|
BoneWrapper
|
|
49394
49482
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
49483
|
+
class CameraWrapper extends InstanceWrapper {
|
|
49484
|
+
static className = "Camera";
|
|
49485
|
+
static requiredProperties = [
|
|
49486
|
+
"Name",
|
|
49487
|
+
"CFrame",
|
|
49488
|
+
"CameraType",
|
|
49489
|
+
"FieldOfView"
|
|
49490
|
+
];
|
|
49491
|
+
setup() {
|
|
49492
|
+
this.addProp("Name", DataType.String, this.instance.className);
|
|
49493
|
+
this.addProp("CFrame", DataType.CFrame, new CFrame());
|
|
49494
|
+
this.addProp("CameraType", DataType.Enum, CameraType.Fixed);
|
|
49495
|
+
this.addProp("FieldOfView", DataType.Float32, 70);
|
|
49496
|
+
}
|
|
49497
|
+
}
|
|
49498
|
+
const __vite_glob_0_9 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
49499
|
+
__proto__: null,
|
|
49500
|
+
CameraWrapper
|
|
49501
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
49395
49502
|
class DecalWrapper extends InstanceWrapper {
|
|
49396
49503
|
static className = "Decal";
|
|
49397
49504
|
static requiredProperties = [
|
|
@@ -49413,7 +49520,7 @@ class DecalWrapper extends InstanceWrapper {
|
|
|
49413
49520
|
if (!this.instance.HasProperty("UVScale")) this.instance.addProperty(new Property("UVScale", DataType.Vector2), new Vector2());
|
|
49414
49521
|
}
|
|
49415
49522
|
}
|
|
49416
|
-
const
|
|
49523
|
+
const __vite_glob_0_11 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
49417
49524
|
__proto__: null,
|
|
49418
49525
|
DecalWrapper
|
|
49419
49526
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -49557,7 +49664,7 @@ class MakeupDescriptionWrapper extends InstanceWrapper {
|
|
|
49557
49664
|
if (!this.instance.HasProperty("Instance")) this.instance.addProperty(new Property("Instance", DataType.Referent), void 0);
|
|
49558
49665
|
}
|
|
49559
49666
|
}
|
|
49560
|
-
const
|
|
49667
|
+
const __vite_glob_0_16 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
49561
49668
|
__proto__: null,
|
|
49562
49669
|
MakeupDescriptionWrapper
|
|
49563
49670
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -50762,18 +50869,13 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
|
|
|
50762
50869
|
if (animationSetEntries) {
|
|
50763
50870
|
for (const subAnim of animationSetEntries) {
|
|
50764
50871
|
const subAnimId = BigInt(API.Misc.idFromStr(subAnim.id));
|
|
50872
|
+
animatorW.data.animationSet[animName].push(subAnim);
|
|
50765
50873
|
if (!animatorW.data.animationTracks.has(subAnimId)) {
|
|
50766
50874
|
promises.push(new Promise((resolve) => {
|
|
50767
50875
|
animatorW.loadAnimation(subAnimId, true).then((result) => {
|
|
50768
|
-
if (!animatorW.data.animationSet[animName]) {
|
|
50769
|
-
animatorW.data.animationSet[animName] = [];
|
|
50770
|
-
}
|
|
50771
|
-
animatorW.data.animationSet[animName].push(subAnim);
|
|
50772
50876
|
resolve(result instanceof Response ? result : void 0);
|
|
50773
50877
|
});
|
|
50774
50878
|
}));
|
|
50775
|
-
} else {
|
|
50776
|
-
animatorW.data.animationSet[animName].push(subAnim);
|
|
50777
50879
|
}
|
|
50778
50880
|
}
|
|
50779
50881
|
} else {
|
|
@@ -50795,12 +50897,16 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
|
|
|
50795
50897
|
if (this.instance.PropOrDefault(animationProp, 0n) > 0n && avatarType === AvatarType.R15) {
|
|
50796
50898
|
const id = this.instance.Prop(animationProp);
|
|
50797
50899
|
promises.push(new Promise((resolve) => {
|
|
50900
|
+
if (animationProp === "IdleAnimation") {
|
|
50901
|
+
delete animatorW.data.animationSet["pose"];
|
|
50902
|
+
}
|
|
50798
50903
|
animatorW.loadAvatarAnimation(id, false, true).then((result) => {
|
|
50799
50904
|
resolve(result);
|
|
50800
50905
|
});
|
|
50801
50906
|
}));
|
|
50802
50907
|
} else {
|
|
50803
50908
|
this._loadDefaultAnimation(animationProp, avatarType, animatorW, promises);
|
|
50909
|
+
if (animationProp === "IdleAnimation" && !toChange.includes("pose")) this._loadDefaultAnimation("pose", avatarType, animatorW, promises);
|
|
50804
50910
|
}
|
|
50805
50911
|
}
|
|
50806
50912
|
const values = await Promise.all(promises);
|
|
@@ -50935,7 +51041,7 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
|
|
|
50935
51041
|
return this.instance;
|
|
50936
51042
|
}
|
|
50937
51043
|
}
|
|
50938
|
-
const
|
|
51044
|
+
const __vite_glob_0_13 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
50939
51045
|
__proto__: null,
|
|
50940
51046
|
HumanoidDescriptionWrapper
|
|
50941
51047
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -51070,14 +51176,14 @@ class JointInstanceWrapper extends InstanceWrapper {
|
|
|
51070
51176
|
}
|
|
51071
51177
|
}
|
|
51072
51178
|
}
|
|
51073
|
-
const
|
|
51179
|
+
const __vite_glob_0_15 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
51074
51180
|
__proto__: null,
|
|
51075
51181
|
JointInstanceWrapper
|
|
51076
51182
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
51077
51183
|
class ManualWeldWrapper extends JointInstanceWrapper {
|
|
51078
51184
|
static className = "ManualWeld";
|
|
51079
51185
|
}
|
|
51080
|
-
const
|
|
51186
|
+
const __vite_glob_0_17 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
51081
51187
|
__proto__: null,
|
|
51082
51188
|
ManualWeldWrapper
|
|
51083
51189
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -51092,7 +51198,7 @@ class MeshPartWrapper extends BasePartWrapper {
|
|
|
51092
51198
|
if (!this.instance.HasProperty("DoubleSided")) this.instance.addProperty(new Property("DoubleSided", DataType.Bool), false);
|
|
51093
51199
|
}
|
|
51094
51200
|
}
|
|
51095
|
-
const
|
|
51201
|
+
const __vite_glob_0_18 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
51096
51202
|
__proto__: null,
|
|
51097
51203
|
MeshPartWrapper
|
|
51098
51204
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -51111,7 +51217,7 @@ class ModelWrapper extends InstanceWrapper {
|
|
|
51111
51217
|
throw new Error("Model has no PrimaryPart");
|
|
51112
51218
|
}
|
|
51113
51219
|
}
|
|
51114
|
-
const
|
|
51220
|
+
const __vite_glob_0_19 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
51115
51221
|
__proto__: null,
|
|
51116
51222
|
ModelWrapper
|
|
51117
51223
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -51126,7 +51232,7 @@ class Motor6DWrapper extends JointInstanceWrapper {
|
|
|
51126
51232
|
if (!this.instance.HasProperty("Transform")) this.instance.addProperty(new Property("Transform", DataType.CFrame), new CFrame());
|
|
51127
51233
|
}
|
|
51128
51234
|
}
|
|
51129
|
-
const
|
|
51235
|
+
const __vite_glob_0_20 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
51130
51236
|
__proto__: null,
|
|
51131
51237
|
Motor6DWrapper
|
|
51132
51238
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -51141,7 +51247,7 @@ class PartWrapper extends BasePartWrapper {
|
|
|
51141
51247
|
if (!this.instance.HasProperty("shape")) this.instance.addProperty(new Property("shape", DataType.Enum), PartType.Block);
|
|
51142
51248
|
}
|
|
51143
51249
|
}
|
|
51144
|
-
const
|
|
51250
|
+
const __vite_glob_0_21 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
51145
51251
|
__proto__: null,
|
|
51146
51252
|
PartWrapper
|
|
51147
51253
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -52066,7 +52172,7 @@ class ParticleEmitterWrapper extends InstanceWrapper {
|
|
|
52066
52172
|
}
|
|
52067
52173
|
}
|
|
52068
52174
|
}
|
|
52069
|
-
const
|
|
52175
|
+
const __vite_glob_0_22 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
52070
52176
|
__proto__: null,
|
|
52071
52177
|
ParticleEmitterWrapper
|
|
52072
52178
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -52172,7 +52278,7 @@ class SoundWrapper extends InstanceWrapper {
|
|
|
52172
52278
|
}
|
|
52173
52279
|
}
|
|
52174
52280
|
}
|
|
52175
|
-
const
|
|
52281
|
+
const __vite_glob_0_24 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
52176
52282
|
__proto__: null,
|
|
52177
52283
|
SoundWrapper
|
|
52178
52284
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -52426,7 +52532,7 @@ class ScriptWrapper extends InstanceWrapper {
|
|
|
52426
52532
|
}
|
|
52427
52533
|
}
|
|
52428
52534
|
}
|
|
52429
|
-
const
|
|
52535
|
+
const __vite_glob_0_23 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
52430
52536
|
__proto__: null,
|
|
52431
52537
|
ScriptWrapper
|
|
52432
52538
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -52483,25 +52589,25 @@ class ToolWrapper extends InstanceWrapper {
|
|
|
52483
52589
|
}
|
|
52484
52590
|
}
|
|
52485
52591
|
}
|
|
52486
|
-
const
|
|
52592
|
+
const __vite_glob_0_25 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
52487
52593
|
__proto__: null,
|
|
52488
52594
|
ToolWrapper
|
|
52489
52595
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
52490
52596
|
class WedgePartWrapper extends BasePartWrapper {
|
|
52491
52597
|
static className = "WedgePart";
|
|
52492
52598
|
}
|
|
52493
|
-
const
|
|
52599
|
+
const __vite_glob_0_26 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
52494
52600
|
__proto__: null,
|
|
52495
52601
|
WedgePartWrapper
|
|
52496
52602
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
52497
52603
|
class WeldWrapper extends JointInstanceWrapper {
|
|
52498
52604
|
static className = "Weld";
|
|
52499
52605
|
}
|
|
52500
|
-
const
|
|
52606
|
+
const __vite_glob_0_27 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
52501
52607
|
__proto__: null,
|
|
52502
52608
|
WeldWrapper
|
|
52503
52609
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
52504
|
-
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/
|
|
52610
|
+
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/Camera.ts": __vite_glob_0_9, "./instance/Constraint.ts": __vite_glob_0_10, "./instance/Decal.ts": __vite_glob_0_11, "./instance/FaceControls.ts": __vite_glob_0_12, "./instance/HumanoidDescription.ts": __vite_glob_0_13, "./instance/InstanceWrapper.ts": __vite_glob_0_14, "./instance/JointInstance.ts": __vite_glob_0_15, "./instance/MakeupDescription.ts": __vite_glob_0_16, "./instance/ManualWeld.ts": __vite_glob_0_17, "./instance/MeshPart.ts": __vite_glob_0_18, "./instance/Model.ts": __vite_glob_0_19, "./instance/Motor6D.ts": __vite_glob_0_20, "./instance/Part.ts": __vite_glob_0_21, "./instance/ParticleEmitter.ts": __vite_glob_0_22, "./instance/Script.ts": __vite_glob_0_23, "./instance/Sound.ts": __vite_glob_0_24, "./instance/Tool.ts": __vite_glob_0_25, "./instance/WedgePart.ts": __vite_glob_0_26, "./instance/Weld.ts": __vite_glob_0_27 });
|
|
52505
52611
|
function RegisterWrappers() {
|
|
52506
52612
|
for (const module of Object.values(modules$1)) {
|
|
52507
52613
|
for (const exprt of Object.values(module)) {
|
|
@@ -57584,7 +57690,7 @@ class RBXRenderer {
|
|
|
57584
57690
|
if (RBXRenderer.renderer) RBXRenderer.renderer.setClearColor(new Color(0, 0, 0), 0);
|
|
57585
57691
|
RBXRenderer.renderer.outputColorSpace = SRGBColorSpace;
|
|
57586
57692
|
RBXRenderer.renderer.shadowMap.enabled = true;
|
|
57587
|
-
RBXRenderer.renderer.shadowMap.type =
|
|
57693
|
+
RBXRenderer.renderer.shadowMap.type = PCFShadowMap;
|
|
57588
57694
|
RBXRenderer.renderer.setPixelRatio(globalThis.devicePixelRatio * 1 || 1);
|
|
57589
57695
|
RBXRenderer.renderer.setSize(...RBXRenderer.resolution);
|
|
57590
57696
|
if (FLAGS.USE_POST_PROCESSING && FLAGS.POST_PROCESSING_IS_DOUBLE_SIZE) {
|
|
@@ -58114,6 +58220,579 @@ class HSR {
|
|
|
58114
58220
|
}
|
|
58115
58221
|
}
|
|
58116
58222
|
}
|
|
58223
|
+
function getHeadAttachments(rig) {
|
|
58224
|
+
const headAttachments = /* @__PURE__ */ new Map();
|
|
58225
|
+
const head = rig.Child("Head");
|
|
58226
|
+
if (head) {
|
|
58227
|
+
for (const child of head.GetDescendants()) {
|
|
58228
|
+
if (child.IsA("Attachment")) {
|
|
58229
|
+
headAttachments.set(child.Prop("Name"), true);
|
|
58230
|
+
}
|
|
58231
|
+
}
|
|
58232
|
+
}
|
|
58233
|
+
return headAttachments;
|
|
58234
|
+
}
|
|
58235
|
+
function makeRotatedCorner(x, y, z, halfSize, cFrame) {
|
|
58236
|
+
const corner = Vector3.new(x * halfSize.X, y * halfSize.Y, z * halfSize.Z);
|
|
58237
|
+
const newCF = cFrame.multiply(new CFrame(...corner.toVec3()));
|
|
58238
|
+
return Vector3.new(...newCF.Position);
|
|
58239
|
+
}
|
|
58240
|
+
function growExtentsToIncludePoint(minExtent, maxExtent, point) {
|
|
58241
|
+
minExtent = Vector3.new(Math.min(point.X, minExtent.X), Math.min(point.Y, minExtent.Y), Math.min(point.Z, minExtent.Z));
|
|
58242
|
+
maxExtent = Vector3.new(Math.max(point.X, maxExtent.X), Math.max(point.Y, maxExtent.Y), Math.max(point.Z, maxExtent.Z));
|
|
58243
|
+
return [minExtent, maxExtent];
|
|
58244
|
+
}
|
|
58245
|
+
function growExtentsToInclude(minExtent, maxExtent, part, cInverse, optYMinCFrame, optYMin) {
|
|
58246
|
+
const size = part.Prop("Size").divide(new Vector3(2, 2, 2));
|
|
58247
|
+
for (let x = -1; x <= 1; x += 2) {
|
|
58248
|
+
for (let y = -1; y <= 1; y += 2) {
|
|
58249
|
+
for (let z = -1; z <= 1; z += 2) {
|
|
58250
|
+
let corner = makeRotatedCorner(x, y, z, size, part.Prop("CFrame"));
|
|
58251
|
+
if (optYMinCFrame && optYMin !== void 0) {
|
|
58252
|
+
const transformedCorner = new Vector3(...optYMinCFrame.inverse().multiply(new CFrame(...corner.toVec3())).Position);
|
|
58253
|
+
const clampedTransformedCorner = Vector3.new(transformedCorner.X, Math.max(optYMin, transformedCorner.Y), transformedCorner.Z);
|
|
58254
|
+
corner = new Vector3(...optYMinCFrame.multiply(new CFrame(...clampedTransformedCorner.toVec3())).Position);
|
|
58255
|
+
}
|
|
58256
|
+
corner = new Vector3(...cInverse.multiply(new CFrame(...corner.toVec3())).Position);
|
|
58257
|
+
[minExtent, maxExtent] = growExtentsToIncludePoint(minExtent, maxExtent, corner);
|
|
58258
|
+
}
|
|
58259
|
+
}
|
|
58260
|
+
}
|
|
58261
|
+
return [minExtent, maxExtent];
|
|
58262
|
+
}
|
|
58263
|
+
function initExtents() {
|
|
58264
|
+
const minExtent = Vector3.new(Infinity, Infinity, Infinity);
|
|
58265
|
+
const maxExtent = Vector3.new(-Infinity, -Infinity, -Infinity);
|
|
58266
|
+
return [minExtent, maxExtent];
|
|
58267
|
+
}
|
|
58268
|
+
function recursiveCalculateExtents(minExtent, maxExtent, instance, cInverse, indent) {
|
|
58269
|
+
for (const child of instance.GetChildren()) {
|
|
58270
|
+
if (child.IsA("BasePart")) {
|
|
58271
|
+
[minExtent, maxExtent] = growExtentsToInclude(minExtent, maxExtent, child, cInverse);
|
|
58272
|
+
}
|
|
58273
|
+
[minExtent, maxExtent] = recursiveCalculateExtents(minExtent, maxExtent, child, cInverse);
|
|
58274
|
+
}
|
|
58275
|
+
return [minExtent, maxExtent];
|
|
58276
|
+
}
|
|
58277
|
+
function calculateModelExtents(model, targetCFrame) {
|
|
58278
|
+
let [minExtent, maxExtent] = initExtents();
|
|
58279
|
+
const cInverse = targetCFrame.inverse();
|
|
58280
|
+
[minExtent, maxExtent] = recursiveCalculateExtents(minExtent, maxExtent, model, cInverse);
|
|
58281
|
+
return [minExtent, maxExtent];
|
|
58282
|
+
}
|
|
58283
|
+
function calculateHeadExtents(character, targetCFrame) {
|
|
58284
|
+
let [minExtent, maxExtent] = initExtents();
|
|
58285
|
+
const head = character.FindFirstChild("Head");
|
|
58286
|
+
if (!head) {
|
|
58287
|
+
return [minExtent, maxExtent];
|
|
58288
|
+
}
|
|
58289
|
+
const cInverse = targetCFrame.inverse();
|
|
58290
|
+
const untransformedHeadYMin = -head.Prop("Size").Y / 2;
|
|
58291
|
+
[minExtent, maxExtent] = growExtentsToInclude(minExtent, maxExtent, head, cInverse);
|
|
58292
|
+
const headAttachments = getHeadAttachments(character);
|
|
58293
|
+
for (const child of character.GetChildren()) {
|
|
58294
|
+
if (child.IsA("Accessory")) {
|
|
58295
|
+
const handle = child.FindFirstChild("Handle");
|
|
58296
|
+
if (handle) {
|
|
58297
|
+
const attachment = handle.FindFirstChildOfClass("Attachment");
|
|
58298
|
+
if (!attachment || headAttachments.has(attachment.Prop("Name"))) {
|
|
58299
|
+
[minExtent, maxExtent] = growExtentsToInclude(minExtent, maxExtent, handle, cInverse, head.Prop("CFrame"), untransformedHeadYMin);
|
|
58300
|
+
}
|
|
58301
|
+
}
|
|
58302
|
+
}
|
|
58303
|
+
}
|
|
58304
|
+
return [minExtent, maxExtent];
|
|
58305
|
+
}
|
|
58306
|
+
function calculateBodyPartsExtents(targetCFrame, bodyParts) {
|
|
58307
|
+
let [minExtent, maxExtent] = initExtents();
|
|
58308
|
+
const cInverse = targetCFrame.inverse();
|
|
58309
|
+
for (const part of bodyParts) {
|
|
58310
|
+
[minExtent, maxExtent] = growExtentsToInclude(minExtent, maxExtent, part, cInverse, targetCFrame);
|
|
58311
|
+
}
|
|
58312
|
+
return [minExtent, maxExtent];
|
|
58313
|
+
}
|
|
58314
|
+
function calculateTargetCFrame(baseCFrame) {
|
|
58315
|
+
let targetLookVector = new Vector3();
|
|
58316
|
+
if (Math.abs(baseCFrame.lookVector()[1]) > 0.9) {
|
|
58317
|
+
targetLookVector = new Vector3().fromVec3(baseCFrame.upVector());
|
|
58318
|
+
} else {
|
|
58319
|
+
targetLookVector = new Vector3().fromVec3(baseCFrame.lookVector());
|
|
58320
|
+
}
|
|
58321
|
+
targetLookVector = Vector3.new(targetLookVector.X, 0, targetLookVector.Z).normalize();
|
|
58322
|
+
return CFrame.lookAt(baseCFrame.Position, new Vector3().fromVec3(baseCFrame.Position).add(targetLookVector).toVec3());
|
|
58323
|
+
}
|
|
58324
|
+
function adjustTargetCFrameWithExtents(targetCFrame, minExtent, maxExtent) {
|
|
58325
|
+
let adjustment = minExtent.add(maxExtent).divide(new Vector3(2, 2, 2));
|
|
58326
|
+
const tmpCFrame = targetCFrame.rotationOnly();
|
|
58327
|
+
adjustment = tmpCFrame.multiplyVector(adjustment);
|
|
58328
|
+
targetCFrame.Position = add(targetCFrame.Position, adjustment.toVec3());
|
|
58329
|
+
return targetCFrame;
|
|
58330
|
+
}
|
|
58331
|
+
function vector3FromXYRotPlusDistance(xAngleDeg, yAngleDeg, radius) {
|
|
58332
|
+
const cFrame = CFrame.fromEulerAngles(rad(xAngleDeg), rad(yAngleDeg), 0, "XYZ");
|
|
58333
|
+
return new Vector3(...cFrame.lookVector()).multiply(new Vector3(radius, radius, radius));
|
|
58334
|
+
}
|
|
58335
|
+
const CONSTANTS_CameraUtility = {
|
|
58336
|
+
//When generating a head thumbnail, how much 'margin' around extent of head + accoutrements?
|
|
58337
|
+
DefaultHeadMarginScale: 1.1,
|
|
58338
|
+
//When generating a full body thumbnail, how much 'margin' around whole body?
|
|
58339
|
+
DefaultBodyMarginScale: 1.1,
|
|
58340
|
+
//Amount of margin around a body part in a generated thumbnail
|
|
58341
|
+
DefaultBodyPartMarginScale: 1.2,
|
|
58342
|
+
XRotForFullBody: 15,
|
|
58343
|
+
XRotForCloseup: 0,
|
|
58344
|
+
DistanceScaleForFullBody: 1
|
|
58345
|
+
};
|
|
58346
|
+
const HEAD_MARGIN_SCALE = 1.1;
|
|
58347
|
+
const HEAD_X_ROTATION_RAD = rad(15);
|
|
58348
|
+
const HEAD_Y_ROTATION_RAD = rad(30);
|
|
58349
|
+
const FACE_LEFT_CFRAME = CFrame.fromEulerAngles(rad(-20), rad(20), 0, "YXZ");
|
|
58350
|
+
const FACE_RIGHT_CFRAME = CFrame.fromEulerAngles(rad(-20), rad(-20), 0, "YXZ");
|
|
58351
|
+
const HEAD_BODYPART_FIELD_OF_VIEW_DEG = 30;
|
|
58352
|
+
const ACCESSORY_DEFAULT_CFRAME = CFrame.Angles(rad(25), rad(25), rad(0));
|
|
58353
|
+
const ACCESSORY_FIELD_OF_VIEW_DEG = 20;
|
|
58354
|
+
const ACCESSORY_EXTENT_SCALE = 1.1;
|
|
58355
|
+
const LEFT_SHOE_CFRAME = CFrame.Angles(rad(0), rad(90), rad(0));
|
|
58356
|
+
const RIGHT_SHOE_CFRAME = CFrame.Angles(rad(0), rad(-90), rad(0));
|
|
58357
|
+
function getCameraCFrame(targetCFrame, relativePos) {
|
|
58358
|
+
const cameraPos = targetCFrame.multiplyVector(relativePos);
|
|
58359
|
+
return CFrame.lookAt(cameraPos.toVec3(), targetCFrame.Position);
|
|
58360
|
+
}
|
|
58361
|
+
function createThumbnailCamera() {
|
|
58362
|
+
const camera = new Instance("Camera");
|
|
58363
|
+
camera.setProperty("Name", "ThumbnailCamera");
|
|
58364
|
+
camera.setProperty("CameraType", CameraType.Scriptable);
|
|
58365
|
+
return camera;
|
|
58366
|
+
}
|
|
58367
|
+
function calculateBaseDistanceToCamera(fieldOfViewRad, minExtent, maxExtent, marginScale) {
|
|
58368
|
+
const offsetFromCenter = Math.max((maxExtent.X - minExtent.X) / 2, (maxExtent.Y - minExtent.Y) / 2);
|
|
58369
|
+
const t = Math.tan(fieldOfViewRad / 2);
|
|
58370
|
+
return offsetFromCenter * marginScale / t;
|
|
58371
|
+
}
|
|
58372
|
+
function setupCamera(camera, cameraOptions) {
|
|
58373
|
+
if (cameraOptions.optFieldOfView) {
|
|
58374
|
+
camera.setProperty("FieldOfView", cameraOptions.optFieldOfView);
|
|
58375
|
+
}
|
|
58376
|
+
const fieldOfViewForDistanceScale = cameraOptions.optFieldOfViewForDistanceScale || camera.Prop("FieldOfView");
|
|
58377
|
+
let distanceToCamera = calculateBaseDistanceToCamera(
|
|
58378
|
+
rad(fieldOfViewForDistanceScale),
|
|
58379
|
+
cameraOptions.minExtent,
|
|
58380
|
+
cameraOptions.maxExtent,
|
|
58381
|
+
cameraOptions.extentScale
|
|
58382
|
+
);
|
|
58383
|
+
if (cameraOptions.optCameraDistanceScale) {
|
|
58384
|
+
distanceToCamera = distanceToCamera * cameraOptions.optCameraDistanceScale;
|
|
58385
|
+
}
|
|
58386
|
+
const finalTargetCFrame = adjustTargetCFrameWithExtents(
|
|
58387
|
+
cameraOptions.targetCFrame,
|
|
58388
|
+
cameraOptions.minExtent,
|
|
58389
|
+
cameraOptions.maxExtent
|
|
58390
|
+
);
|
|
58391
|
+
const cameraXRotDeg = cameraOptions.optCameraXRot || 0;
|
|
58392
|
+
const cameraYRotDeg = cameraOptions.optCameraYRot || 0;
|
|
58393
|
+
const cPos = vector3FromXYRotPlusDistance(cameraXRotDeg, cameraYRotDeg, distanceToCamera);
|
|
58394
|
+
camera.setProperty("CFrame", getCameraCFrame(finalTargetCFrame, cPos));
|
|
58395
|
+
}
|
|
58396
|
+
function setupBodyPartCamera(mannequin, faceRight, focusPartNames, camera) {
|
|
58397
|
+
const mannequinFocusParts = [];
|
|
58398
|
+
for (const focusPartName of focusPartNames) {
|
|
58399
|
+
const focusPart = mannequin.FindFirstDescendant(focusPartName);
|
|
58400
|
+
if (focusPart) {
|
|
58401
|
+
mannequinFocusParts.push(focusPart);
|
|
58402
|
+
}
|
|
58403
|
+
}
|
|
58404
|
+
const humanoidRootPart = mannequin.FindFirstChild("HumanoidRootPart");
|
|
58405
|
+
if (humanoidRootPart) {
|
|
58406
|
+
let mannequinTargetCFrame = humanoidRootPart.Prop("CFrame");
|
|
58407
|
+
const adjustment = faceRight ? FACE_RIGHT_CFRAME : FACE_LEFT_CFRAME;
|
|
58408
|
+
mannequinTargetCFrame = adjustment.multiply(mannequinTargetCFrame);
|
|
58409
|
+
const [minPartsExtent, maxPartsExtent] = calculateBodyPartsExtents(mannequinTargetCFrame, mannequinFocusParts);
|
|
58410
|
+
const cameraOptions = {
|
|
58411
|
+
optFieldOfView: HEAD_BODYPART_FIELD_OF_VIEW_DEG,
|
|
58412
|
+
targetCFrame: mannequinTargetCFrame,
|
|
58413
|
+
minExtent: minPartsExtent,
|
|
58414
|
+
maxExtent: maxPartsExtent,
|
|
58415
|
+
extentScale: CONSTANTS_CameraUtility.DefaultBodyPartMarginScale
|
|
58416
|
+
};
|
|
58417
|
+
setupCamera(camera, cameraOptions);
|
|
58418
|
+
}
|
|
58419
|
+
}
|
|
58420
|
+
function setupHeadCamera(headModel, camera) {
|
|
58421
|
+
const head = headModel.FindFirstChild("Head");
|
|
58422
|
+
if (head) {
|
|
58423
|
+
let headTargetCFrame = calculateTargetCFrame(head.Prop("CFrame"));
|
|
58424
|
+
const adjustment = CFrame.fromEulerAngles(HEAD_X_ROTATION_RAD, HEAD_Y_ROTATION_RAD, 0, "YXZ");
|
|
58425
|
+
headTargetCFrame = adjustment.multiply(headTargetCFrame);
|
|
58426
|
+
const [minHeadExtent, maxHeadExtent] = calculateHeadExtents(headModel, headTargetCFrame);
|
|
58427
|
+
const cameraOptions = {
|
|
58428
|
+
optFieldOfView: HEAD_BODYPART_FIELD_OF_VIEW_DEG,
|
|
58429
|
+
targetCFrame: headTargetCFrame,
|
|
58430
|
+
minExtent: minHeadExtent,
|
|
58431
|
+
maxExtent: maxHeadExtent,
|
|
58432
|
+
extentScale: HEAD_MARGIN_SCALE
|
|
58433
|
+
};
|
|
58434
|
+
setupCamera(camera, cameraOptions);
|
|
58435
|
+
}
|
|
58436
|
+
}
|
|
58437
|
+
function isLeftShoe(acc) {
|
|
58438
|
+
const handle = acc.FindFirstChildOfClass("MeshPart");
|
|
58439
|
+
if (!handle) {
|
|
58440
|
+
return false;
|
|
58441
|
+
}
|
|
58442
|
+
return void 0 !== handle.FindFirstChild("LeftFootAttachment");
|
|
58443
|
+
}
|
|
58444
|
+
function isRightShoe(acc) {
|
|
58445
|
+
const handle = acc.FindFirstChildOfClass("MeshPart");
|
|
58446
|
+
if (!handle) {
|
|
58447
|
+
return false;
|
|
58448
|
+
}
|
|
58449
|
+
return void 0 !== handle.FindFirstChild("RightFootAttachment");
|
|
58450
|
+
}
|
|
58451
|
+
function getAccessoryAngle(acc) {
|
|
58452
|
+
if (isLeftShoe(acc)) {
|
|
58453
|
+
return LEFT_SHOE_CFRAME;
|
|
58454
|
+
} else if (isRightShoe(acc)) {
|
|
58455
|
+
return RIGHT_SHOE_CFRAME;
|
|
58456
|
+
}
|
|
58457
|
+
return ACCESSORY_DEFAULT_CFRAME;
|
|
58458
|
+
}
|
|
58459
|
+
function setupAccessoryCamera(accessoryModel, camera) {
|
|
58460
|
+
const modelChildren = accessoryModel.GetChildren();
|
|
58461
|
+
const accoutrement = modelChildren[0];
|
|
58462
|
+
const handle = accoutrement.FindFirstChild("Handle");
|
|
58463
|
+
if (handle) {
|
|
58464
|
+
handle.setProperty("CFrame", new CFrame());
|
|
58465
|
+
const targetCFrame = handle.Prop("CFrame").multiply(getAccessoryAngle(accoutrement));
|
|
58466
|
+
const [minPartsExtent, maxPartsExtent] = calculateModelExtents(accessoryModel, targetCFrame);
|
|
58467
|
+
const cameraOptions = {
|
|
58468
|
+
optFieldOfView: ACCESSORY_FIELD_OF_VIEW_DEG,
|
|
58469
|
+
targetCFrame,
|
|
58470
|
+
minExtent: minPartsExtent,
|
|
58471
|
+
maxExtent: maxPartsExtent,
|
|
58472
|
+
extentScale: ACCESSORY_EXTENT_SCALE
|
|
58473
|
+
};
|
|
58474
|
+
setupCamera(camera, cameraOptions);
|
|
58475
|
+
}
|
|
58476
|
+
}
|
|
58477
|
+
const FIntCameraPresetHeadshotExtentScaleHundredths = 110;
|
|
58478
|
+
const CONSTANTS_CameraPresetsUtility = {
|
|
58479
|
+
GOLDEN_RATIO: 600 / 1e3,
|
|
58480
|
+
//game:DefineFastInt("AvatarGoldenRatio", 618) / 1000 -- = 0.618
|
|
58481
|
+
UPVECTOR_ORENTATION_TRESHOLD: -60 / 100,
|
|
58482
|
+
//game:DefineFastInt("UpVectorOrentationThreshold1", -60) / 100 // = -0.6
|
|
58483
|
+
AVATAR_ROTATION_DEGREE: 15
|
|
58484
|
+
//game:DefineFastInt("LookAvatarRotationDegree1", 23)
|
|
58485
|
+
};
|
|
58486
|
+
function getTorsoOrUpperTorso(character) {
|
|
58487
|
+
return character.FindFirstChild("Torso") || character.FindFirstChild("UpperTorso");
|
|
58488
|
+
}
|
|
58489
|
+
function getMannequinBodyParts(character, humanoid) {
|
|
58490
|
+
const bodyParts = [];
|
|
58491
|
+
if (humanoid.Prop("RigType") === HumanoidRigType.R6) {
|
|
58492
|
+
for (const partName of R6BodyPartNames) {
|
|
58493
|
+
const bodyPart = character.FindFirstChild(partName);
|
|
58494
|
+
if (bodyPart) bodyParts.push(bodyPart);
|
|
58495
|
+
}
|
|
58496
|
+
} else if (humanoid.Prop("RigType") === HumanoidRigType.R15) {
|
|
58497
|
+
for (const partName of R15BodyPartNames) {
|
|
58498
|
+
const bodyPart = character.FindFirstChild(partName);
|
|
58499
|
+
if (bodyPart) bodyParts.push(bodyPart);
|
|
58500
|
+
}
|
|
58501
|
+
}
|
|
58502
|
+
return bodyParts;
|
|
58503
|
+
}
|
|
58504
|
+
function getCharacterTorsoCFrame(character) {
|
|
58505
|
+
const torso = getTorsoOrUpperTorso(character);
|
|
58506
|
+
return torso ? torso.Prop("CFrame") : new CFrame();
|
|
58507
|
+
}
|
|
58508
|
+
function getFullBodyCameraCFrame(character, applyEmote, isFallbackEmoteApplied = true, fieldOfViewDeg, characterInitialCFrame, autoZoom = true) {
|
|
58509
|
+
const fovAngle = fieldOfViewDeg || 56;
|
|
58510
|
+
const characterInitialPivotTo = characterInitialCFrame || getCharacterTorsoCFrame(character);
|
|
58511
|
+
const characterInitialLookVector = characterInitialPivotTo.lookVector();
|
|
58512
|
+
if (applyEmote) {
|
|
58513
|
+
applyEmote();
|
|
58514
|
+
}
|
|
58515
|
+
const humanoid = character.FindFirstChildOfClass("Humanoid");
|
|
58516
|
+
if (!humanoid) {
|
|
58517
|
+
return;
|
|
58518
|
+
}
|
|
58519
|
+
const bodyParts = getMannequinBodyParts(character, humanoid);
|
|
58520
|
+
const characterPivotToAuxiliaryCFrame = getCharacterTorsoCFrame(character);
|
|
58521
|
+
const characterAuxiliaryUpVector = characterPivotToAuxiliaryCFrame.upVector();
|
|
58522
|
+
const head = character.FindFirstChild("Head");
|
|
58523
|
+
if (!head) return;
|
|
58524
|
+
const [characterHeadRotationX, characterHeadRotationY, characterHeadRotationZ] = head.Prop("CFrame").toEulerAngles("XYZ");
|
|
58525
|
+
if (isFallbackEmoteApplied) {
|
|
58526
|
+
const rootAssembly = head.w.GetAssembly();
|
|
58527
|
+
const rootPart = rootAssembly.rootNode.part;
|
|
58528
|
+
rootPart.setProperty("CFrame", rootPart.Prop("CFrame").multiply(CFrame.Angles(0, rad(CONSTANTS_CameraPresetsUtility.AVATAR_ROTATION_DEGREE * -1), 0)));
|
|
58529
|
+
rootAssembly.traverseTree();
|
|
58530
|
+
}
|
|
58531
|
+
const [minPartsExtent, maxPartsExtent] = calculateBodyPartsExtents(characterPivotToAuxiliaryCFrame, bodyParts);
|
|
58532
|
+
const tanAlpha = Math.tan(rad(fovAngle / 2));
|
|
58533
|
+
const goldPositionOfExtent = minPartsExtent.lerp(maxPartsExtent, CONSTANTS_CameraPresetsUtility.GOLDEN_RATIO);
|
|
58534
|
+
const centerPositionOfExtent = minPartsExtent.lerp(maxPartsExtent, 0.5);
|
|
58535
|
+
const goldPosition = new Vector3(centerPositionOfExtent.X, goldPositionOfExtent.Y, centerPositionOfExtent.Z);
|
|
58536
|
+
const goldPositionWorldSpace = characterPivotToAuxiliaryCFrame.multiplyVector(goldPosition);
|
|
58537
|
+
let characterGoldenRatioPivotTo = characterPivotToAuxiliaryCFrame.rotationOnly();
|
|
58538
|
+
characterGoldenRatioPivotTo.Position = add(characterGoldenRatioPivotTo.Position, goldPositionWorldSpace.toVec3());
|
|
58539
|
+
if (!isFallbackEmoteApplied) {
|
|
58540
|
+
const headPivotTo = CFrame.fromEulerAngles(characterHeadRotationX, characterHeadRotationY, characterHeadRotationZ, "XYZ");
|
|
58541
|
+
characterGoldenRatioPivotTo = headPivotTo.rotationOnly();
|
|
58542
|
+
characterGoldenRatioPivotTo.Position = add(characterGoldenRatioPivotTo.Position, goldPositionWorldSpace.toVec3());
|
|
58543
|
+
}
|
|
58544
|
+
const distanceToLowerExtents = Math.max(goldPosition.X - minPartsExtent.X, goldPosition.Y - minPartsExtent.Y);
|
|
58545
|
+
const distanceToUpperExtents = Math.max(maxPartsExtent.X - goldPosition.X, maxPartsExtent.Y - goldPosition.Y);
|
|
58546
|
+
const dc1 = distanceToLowerExtents * CONSTANTS_CameraUtility.DefaultBodyMarginScale / tanAlpha;
|
|
58547
|
+
const dc1Option = distanceToUpperExtents * CONSTANTS_CameraUtility.DefaultBodyMarginScale / tanAlpha;
|
|
58548
|
+
let distanceToCameraOption = dc1;
|
|
58549
|
+
const isUpsideDown = characterAuxiliaryUpVector[1] < CONSTANTS_CameraPresetsUtility.UPVECTOR_ORENTATION_TRESHOLD;
|
|
58550
|
+
const isUpsideRight = characterAuxiliaryUpVector[0] < CONSTANTS_CameraPresetsUtility.UPVECTOR_ORENTATION_TRESHOLD;
|
|
58551
|
+
if (isUpsideDown || isUpsideRight) {
|
|
58552
|
+
distanceToCameraOption = Math.max(dc1, dc1Option);
|
|
58553
|
+
}
|
|
58554
|
+
let distanceToCamera = distanceToCameraOption * CONSTANTS_CameraUtility.DistanceScaleForFullBody;
|
|
58555
|
+
if (autoZoom) {
|
|
58556
|
+
const [minExtentWithAccessories, maxExtentWithAccessories] = calculateModelExtents(character, characterPivotToAuxiliaryCFrame);
|
|
58557
|
+
const dc2 = Math.max(maxExtentWithAccessories.X - minExtentWithAccessories.X, maxExtentWithAccessories.Y - minExtentWithAccessories.Y) * CONSTANTS_CameraUtility.DefaultBodyMarginScale / 2 / tanAlpha;
|
|
58558
|
+
distanceToCamera = Math.max(dc1, dc1Option) * Math.max(Math.min(dc2 / Math.max(dc1, dc1Option), 1.5), 1.1);
|
|
58559
|
+
}
|
|
58560
|
+
const relativePositionToCamera = new Vector3().fromVec3(multiply(characterInitialLookVector, [distanceToCamera, distanceToCamera, distanceToCamera]));
|
|
58561
|
+
return getCameraCFrame(characterGoldenRatioPivotTo, relativePositionToCamera);
|
|
58562
|
+
}
|
|
58563
|
+
function getHeadshotCameraCFrame(character, applyEmote, isFallbackEmoteApplied, fieldOfViewDeg, cameraOptionsOverride) {
|
|
58564
|
+
const fovAngle = fieldOfViewDeg || 30;
|
|
58565
|
+
if (applyEmote) {
|
|
58566
|
+
applyEmote();
|
|
58567
|
+
}
|
|
58568
|
+
const characterHead = character.FindFirstChild("Head");
|
|
58569
|
+
if (!characterHead) {
|
|
58570
|
+
return;
|
|
58571
|
+
}
|
|
58572
|
+
let targetCFrame = characterHead.Prop("CFrame");
|
|
58573
|
+
const faceFrontAttachment = characterHead.FindFirstChild("FaceFrontAttachment");
|
|
58574
|
+
if (faceFrontAttachment) {
|
|
58575
|
+
const faceFrontAttachmentW = faceFrontAttachment.w;
|
|
58576
|
+
if (faceFrontAttachmentW) {
|
|
58577
|
+
targetCFrame = faceFrontAttachmentW.getWorldCFrame();
|
|
58578
|
+
}
|
|
58579
|
+
}
|
|
58580
|
+
const headTargetCFrame = calculateTargetCFrame(targetCFrame);
|
|
58581
|
+
const [minHeadExtent, maxHeadExtent] = calculateHeadExtents(character, headTargetCFrame);
|
|
58582
|
+
const camera = createThumbnailCamera();
|
|
58583
|
+
const cameraOptions = {
|
|
58584
|
+
extentScale: FIntCameraPresetHeadshotExtentScaleHundredths / 100,
|
|
58585
|
+
maxExtent: maxHeadExtent,
|
|
58586
|
+
minExtent: minHeadExtent,
|
|
58587
|
+
optCameraXRot: CONSTANTS_CameraUtility.XRotForCloseup,
|
|
58588
|
+
optFieldOfView: fovAngle,
|
|
58589
|
+
targetCFrame: headTargetCFrame
|
|
58590
|
+
};
|
|
58591
|
+
Object.assign(cameraOptions, cameraOptionsOverride);
|
|
58592
|
+
setupCamera(camera, cameraOptions);
|
|
58593
|
+
return camera;
|
|
58594
|
+
}
|
|
58595
|
+
function getAvatarCameraCFrame(character, applyEmote, isFallbackEmoteApplied, fieldOfViewDeg, cameraOptionsOverride) {
|
|
58596
|
+
const fovAngle = fieldOfViewDeg || 30;
|
|
58597
|
+
if (applyEmote) {
|
|
58598
|
+
applyEmote();
|
|
58599
|
+
}
|
|
58600
|
+
const characterHead = character.FindFirstChild("Head");
|
|
58601
|
+
if (!characterHead) {
|
|
58602
|
+
return;
|
|
58603
|
+
}
|
|
58604
|
+
let targetCFrame = characterHead.Prop("CFrame");
|
|
58605
|
+
const faceFrontAttachment = characterHead.FindFirstChild("FaceFrontAttachment");
|
|
58606
|
+
if (faceFrontAttachment) {
|
|
58607
|
+
const faceFrontAttachmentW = faceFrontAttachment.w;
|
|
58608
|
+
if (faceFrontAttachmentW) {
|
|
58609
|
+
targetCFrame = faceFrontAttachmentW.getWorldCFrame();
|
|
58610
|
+
}
|
|
58611
|
+
}
|
|
58612
|
+
const torsoCFrame = getCharacterTorsoCFrame(character);
|
|
58613
|
+
targetCFrame.Position = torsoCFrame.Position;
|
|
58614
|
+
const headTargetCFrame = calculateTargetCFrame(targetCFrame);
|
|
58615
|
+
const [minHeadExtent, maxHeadExtent] = calculateModelExtents(character, headTargetCFrame);
|
|
58616
|
+
const camera = createThumbnailCamera();
|
|
58617
|
+
const cameraOptions = {
|
|
58618
|
+
extentScale: FIntCameraPresetHeadshotExtentScaleHundredths / 100,
|
|
58619
|
+
maxExtent: maxHeadExtent,
|
|
58620
|
+
minExtent: minHeadExtent,
|
|
58621
|
+
optCameraXRot: CONSTANTS_CameraUtility.XRotForFullBody,
|
|
58622
|
+
optFieldOfView: fovAngle,
|
|
58623
|
+
targetCFrame: headTargetCFrame
|
|
58624
|
+
};
|
|
58625
|
+
Object.assign(cameraOptions, cameraOptionsOverride);
|
|
58626
|
+
setupCamera(camera, cameraOptions);
|
|
58627
|
+
return camera;
|
|
58628
|
+
}
|
|
58629
|
+
function getCorners(cframe, size) {
|
|
58630
|
+
const halfX = size.X / 2;
|
|
58631
|
+
const halfY = size.Y / 2;
|
|
58632
|
+
const halfZ = size.Z / 2;
|
|
58633
|
+
return [
|
|
58634
|
+
cframe.multiply(new CFrame(halfX, halfY, halfZ)),
|
|
58635
|
+
cframe.multiply(new CFrame(halfX, halfY, -halfZ)),
|
|
58636
|
+
cframe.multiply(new CFrame(-halfX, halfY, halfZ)),
|
|
58637
|
+
cframe.multiply(new CFrame(-halfX, halfY, -halfZ)),
|
|
58638
|
+
cframe.multiply(new CFrame(halfX, -halfY, halfZ)),
|
|
58639
|
+
cframe.multiply(new CFrame(halfX, -halfY, -halfZ)),
|
|
58640
|
+
cframe.multiply(new CFrame(-halfX, -halfY, halfZ)),
|
|
58641
|
+
cframe.multiply(new CFrame(-halfX, -halfY, -halfZ))
|
|
58642
|
+
];
|
|
58643
|
+
}
|
|
58644
|
+
function getLower(a, b) {
|
|
58645
|
+
return new Vector3(
|
|
58646
|
+
a.X < b.X ? a.X : b.X,
|
|
58647
|
+
a.Y < b.Y ? a.Y : b.Y,
|
|
58648
|
+
a.Z < b.Z ? a.Z : b.Z
|
|
58649
|
+
);
|
|
58650
|
+
}
|
|
58651
|
+
function getHigher(a, b) {
|
|
58652
|
+
return new Vector3(
|
|
58653
|
+
a.X > b.X ? a.X : b.X,
|
|
58654
|
+
a.Y > b.Y ? a.Y : b.Y,
|
|
58655
|
+
a.Z > b.Z ? a.Z : b.Z
|
|
58656
|
+
);
|
|
58657
|
+
}
|
|
58658
|
+
function getExtentsForParts(parts, includeTransform) {
|
|
58659
|
+
let lowerExtents = new Vector3(0, 0, 0);
|
|
58660
|
+
let higherExtents = new Vector3(0, 0, 0);
|
|
58661
|
+
for (const child of parts) {
|
|
58662
|
+
if (child.createWrapper()?.IsA("BasePart")) {
|
|
58663
|
+
const cframe = traverseRigCFrame(child, includeTransform, true);
|
|
58664
|
+
const size = child.Prop("Size");
|
|
58665
|
+
const corners = getCorners(cframe, size);
|
|
58666
|
+
for (const corner of corners) {
|
|
58667
|
+
lowerExtents = getLower(lowerExtents, new Vector3().fromVec3(corner.Position));
|
|
58668
|
+
higherExtents = getHigher(higherExtents, new Vector3().fromVec3(corner.Position));
|
|
58669
|
+
}
|
|
58670
|
+
}
|
|
58671
|
+
}
|
|
58672
|
+
return [lowerExtents, higherExtents];
|
|
58673
|
+
}
|
|
58674
|
+
function getExtents(cframe, parts) {
|
|
58675
|
+
const inverseCF = cframe.inverse();
|
|
58676
|
+
let lowerExtents = new Vector3(0, 0, 0);
|
|
58677
|
+
let higherExtents = new Vector3(0, 0, 0);
|
|
58678
|
+
for (const child of parts) {
|
|
58679
|
+
if (child.createWrapper()?.IsA("BasePart")) {
|
|
58680
|
+
const partCF = child.Prop("CFrame");
|
|
58681
|
+
const partSize = child.Prop("Size");
|
|
58682
|
+
const corners = getCorners(inverseCF.multiply(partCF), partSize);
|
|
58683
|
+
for (const corner of corners) {
|
|
58684
|
+
lowerExtents = getLower(lowerExtents, new Vector3().fromVec3(corner.Position));
|
|
58685
|
+
higherExtents = getHigher(higherExtents, new Vector3().fromVec3(corner.Position));
|
|
58686
|
+
}
|
|
58687
|
+
}
|
|
58688
|
+
}
|
|
58689
|
+
return [lowerExtents, higherExtents];
|
|
58690
|
+
}
|
|
58691
|
+
function getExtentsWorld(rig) {
|
|
58692
|
+
const rigParts = [];
|
|
58693
|
+
for (const child of rig.GetDescendants()) {
|
|
58694
|
+
if (child.createWrapper()?.IsA("BasePart")) {
|
|
58695
|
+
rigParts.push(child);
|
|
58696
|
+
}
|
|
58697
|
+
}
|
|
58698
|
+
const extents = getExtents(new CFrame(), rigParts);
|
|
58699
|
+
return extents;
|
|
58700
|
+
}
|
|
58701
|
+
function getExtentsCenter(extents) {
|
|
58702
|
+
return extents[1].minus(extents[0]).divide(new Vector3(2, 2, 2)).add(extents[0]);
|
|
58703
|
+
}
|
|
58704
|
+
function zoomExtents(cameraCFrame, modelCFrame, modelSize, targetFOV, distanceScale, sizeType = "calculate") {
|
|
58705
|
+
let largestSize = Math.max(modelSize.X, modelSize.Y, modelSize.Z);
|
|
58706
|
+
if (sizeType === "calculate") {
|
|
58707
|
+
largestSize = modelSize.magnitude() / 2 / Math.sin(rad(targetFOV / 2));
|
|
58708
|
+
}
|
|
58709
|
+
const fovMultiplier = sizeType === "largestAxis" ? 70 / targetFOV : 1;
|
|
58710
|
+
const lookDir = multiply(normalize(minus(cameraCFrame.Position, modelCFrame.Position)), [distanceScale, distanceScale, distanceScale]);
|
|
58711
|
+
cameraCFrame.Position = add(modelCFrame.Position, multiply(multiply(lookDir, [largestSize, largestSize, largestSize]), [fovMultiplier, fovMultiplier, fovMultiplier]));
|
|
58712
|
+
}
|
|
58713
|
+
function getCameraOffset(fov2, extentsSize) {
|
|
58714
|
+
const halfSize = extentsSize.magnitude() / 2;
|
|
58715
|
+
const fovDivisor = Math.tan(rad(fov2 / 2));
|
|
58716
|
+
return halfSize / fovDivisor;
|
|
58717
|
+
}
|
|
58718
|
+
function zoomToExtents(cameraCFrame, modelCFrame, modelSize, fov2 = 70) {
|
|
58719
|
+
const cameraOffset = getCameraOffset(fov2, modelSize);
|
|
58720
|
+
const cameraRotation = new CFrame();
|
|
58721
|
+
cameraRotation.Orientation = cameraCFrame.Orientation;
|
|
58722
|
+
const instancePosition = modelCFrame.Position;
|
|
58723
|
+
cameraCFrame.Position = add(instancePosition, multiply(minus([0, 0, 0], cameraRotation.lookVector()), [cameraOffset, cameraOffset, cameraOffset]));
|
|
58724
|
+
}
|
|
58725
|
+
function getHeadExtents(rig) {
|
|
58726
|
+
const head = rig.FindFirstChild("Head");
|
|
58727
|
+
if (!head) return;
|
|
58728
|
+
const headParts = [];
|
|
58729
|
+
for (const child of rig.GetDescendants()) {
|
|
58730
|
+
if (child === head) {
|
|
58731
|
+
headParts.push(head);
|
|
58732
|
+
} else {
|
|
58733
|
+
const weld = child.FindFirstChildOfClass("Weld");
|
|
58734
|
+
if (weld && child.parent && child.parent.className === "Accessory") {
|
|
58735
|
+
if (weld.Prop("Part0") === head || weld.Prop("Part1") === head) {
|
|
58736
|
+
headParts.push(child);
|
|
58737
|
+
}
|
|
58738
|
+
}
|
|
58739
|
+
}
|
|
58740
|
+
}
|
|
58741
|
+
const extents = getExtents(head.Prop("CFrame"), headParts);
|
|
58742
|
+
return extents;
|
|
58743
|
+
}
|
|
58744
|
+
function getCameraCFrameForHeadshotCustomized(rig, fov2, yRot, distance2) {
|
|
58745
|
+
const camera = getHeadshotCameraCFrame(rig, void 0, void 0, fov2, {
|
|
58746
|
+
optCameraYRot: yRot,
|
|
58747
|
+
optCameraDistanceScale: distance2,
|
|
58748
|
+
extentScale: 1.1
|
|
58749
|
+
});
|
|
58750
|
+
if (camera) {
|
|
58751
|
+
const cameraCF = camera.Prop("CFrame");
|
|
58752
|
+
camera.Destroy();
|
|
58753
|
+
return cameraCF;
|
|
58754
|
+
}
|
|
58755
|
+
}
|
|
58756
|
+
function getCameraCFrameForAvatarCustomized(rig, fov2, yRot) {
|
|
58757
|
+
const camera = getAvatarCameraCFrame(rig, void 0, void 0, fov2, {
|
|
58758
|
+
optCameraYRot: yRot,
|
|
58759
|
+
optCameraDistanceScale: 1,
|
|
58760
|
+
extentScale: 1.1
|
|
58761
|
+
});
|
|
58762
|
+
if (camera) {
|
|
58763
|
+
const cameraCF = camera.Prop("CFrame");
|
|
58764
|
+
camera.Destroy();
|
|
58765
|
+
return cameraCF;
|
|
58766
|
+
}
|
|
58767
|
+
}
|
|
58768
|
+
function getCameraCFrameForAvatarNonCustomized(rig) {
|
|
58769
|
+
const thumbnailCamera = rig.FindFirstChildOfClass("Camera");
|
|
58770
|
+
if (thumbnailCamera) return thumbnailCamera.PropOrDefault("CFrame", new CFrame());
|
|
58771
|
+
let rootPart = rig.PropOrDefault("PrimaryPart", void 0);
|
|
58772
|
+
if (!rootPart) rootPart = rig.FindFirstChildOfClass("Part");
|
|
58773
|
+
if (!rootPart) rootPart = rig.FindFirstChildOfClass("MeshPart");
|
|
58774
|
+
if (!rootPart) return;
|
|
58775
|
+
const rootPartCF = rootPart.PropOrDefault("CFrame", new CFrame()).clone();
|
|
58776
|
+
const worldExtents = getExtentsWorld(rig);
|
|
58777
|
+
if (!worldExtents) return;
|
|
58778
|
+
const extentsSize = worldExtents[1].minus(worldExtents[0]);
|
|
58779
|
+
rootPartCF.Position = getExtentsCenter(worldExtents).toVec3();
|
|
58780
|
+
let lookVector = rootPartCF.lookVector();
|
|
58781
|
+
if (Math.abs(lookVector[1]) > 0.95) {
|
|
58782
|
+
lookVector = [0, 0, -1];
|
|
58783
|
+
} else {
|
|
58784
|
+
lookVector[1] = 0;
|
|
58785
|
+
lookVector = normalize(lookVector);
|
|
58786
|
+
}
|
|
58787
|
+
let lookCF = CFrame.lookAt([0, 0, 0], lookVector);
|
|
58788
|
+
lookCF = lookCF.multiply(CFrame.fromEulerAngles(25 * Math.PI / 180, 27.5 * Math.PI / 180, 0, "ZXY"));
|
|
58789
|
+
lookVector = lookCF.lookVector();
|
|
58790
|
+
lookCF.Position = add(rootPartCF.Position, multiply([10, 10, 10], lookVector));
|
|
58791
|
+
lookCF = CFrame.lookAt(lookCF.Position, rootPartCF.Position);
|
|
58792
|
+
const cameraCF = lookCF.clone();
|
|
58793
|
+
zoomExtents(cameraCF, rootPartCF, extentsSize, 70, 1);
|
|
58794
|
+
return cameraCF;
|
|
58795
|
+
}
|
|
58117
58796
|
class BackgroundRenderer {
|
|
58118
58797
|
auth;
|
|
58119
58798
|
avatarCyclorama;
|
|
@@ -58318,7 +58997,7 @@ class OutfitRenderer {
|
|
|
58318
58997
|
doCameraUpdate = false;
|
|
58319
58998
|
/**Does camera update every frame */
|
|
58320
58999
|
doAddInstance = true;
|
|
58321
|
-
/**If outfitRenderer should call RBXRenderer.addInstance() */
|
|
59000
|
+
/**If outfitRenderer should call RBXRenderer.addInstance(), setting this to false will make OutfitRenderer return success early */
|
|
58322
59001
|
forceAnimationLoop = true;
|
|
58323
59002
|
/**If future loaded animations should be set to loop */
|
|
58324
59003
|
backgroundRenderer;
|
|
@@ -58360,6 +59039,16 @@ class OutfitRenderer {
|
|
|
58360
59039
|
* @returns void
|
|
58361
59040
|
*/
|
|
58362
59041
|
onRenderError = new Event();
|
|
59042
|
+
get humanoid() {
|
|
59043
|
+
return this.currentRig?.FindFirstChildOfClass("Humanoid");
|
|
59044
|
+
}
|
|
59045
|
+
get animator() {
|
|
59046
|
+
return this.humanoid?.FindFirstChildOfClass("Animator");
|
|
59047
|
+
}
|
|
59048
|
+
get animatorW() {
|
|
59049
|
+
const animator = this.animator;
|
|
59050
|
+
if (animator) return new AnimatorWrapper(animator);
|
|
59051
|
+
}
|
|
58363
59052
|
/**
|
|
58364
59053
|
* Creates a new OutfitRenderer which makes it easy to render outfits
|
|
58365
59054
|
* @param auth The authentication object, you should have one you use for everything
|
|
@@ -58551,9 +59240,30 @@ class OutfitRenderer {
|
|
|
58551
59240
|
this.animationInterval = void 0;
|
|
58552
59241
|
}
|
|
58553
59242
|
}
|
|
59243
|
+
/**
|
|
59244
|
+
* Checks if the provided animation set is loaded
|
|
59245
|
+
* @param name The name of the animation, for example "idle", "run", but NOT "emote.1234" or "id.1234" as they are not in the animation set
|
|
59246
|
+
* @returns If the animation is loaded
|
|
59247
|
+
*/
|
|
59248
|
+
hasAnimationSetAnimation(name) {
|
|
59249
|
+
if (this.currentRig) {
|
|
59250
|
+
const humanoid = this.currentRig.FindFirstChildOfClass("Humanoid");
|
|
59251
|
+
if (humanoid) {
|
|
59252
|
+
const animator = humanoid.FindFirstChildOfClass("Animator");
|
|
59253
|
+
if (animator) {
|
|
59254
|
+
const animatorW = new AnimatorWrapper(animator);
|
|
59255
|
+
const entries = animatorW.data.animationSet[name];
|
|
59256
|
+
if (entries) {
|
|
59257
|
+
return entries.length > 0;
|
|
59258
|
+
}
|
|
59259
|
+
}
|
|
59260
|
+
}
|
|
59261
|
+
}
|
|
59262
|
+
return false;
|
|
59263
|
+
}
|
|
58554
59264
|
/**
|
|
58555
59265
|
* Sets the current animation being played
|
|
58556
|
-
* @param name The name of the animation, for example "idle", "run", "emote.1234" or "
|
|
59266
|
+
* @param name The name of the animation, for example "idle", "run", "emote.1234" or "id.1234"
|
|
58557
59267
|
* @returns If the animation started playing, it may start playing later if it has been queued despite returning false
|
|
58558
59268
|
*/
|
|
58559
59269
|
setMainAnimation(name) {
|
|
@@ -58622,16 +59332,28 @@ class OutfitRenderer {
|
|
|
58622
59332
|
}
|
|
58623
59333
|
async _prepareForThumbnail() {
|
|
58624
59334
|
this.doAddInstance = false;
|
|
59335
|
+
this.backgroundRenderer.affectSceneAppearance = false;
|
|
59336
|
+
this.backgroundRenderer.cameraAffectsTransparency = false;
|
|
58625
59337
|
if (this.outfit.playerAvatarType === AvatarType.R6) this.deltaTimeMultiplier = 0;
|
|
58626
59338
|
await new Promise((resolve) => {
|
|
58627
59339
|
this.onSuccess.Connect(() => {
|
|
59340
|
+
const animatorW = this.animatorW;
|
|
59341
|
+
if (animatorW) {
|
|
59342
|
+
animatorW.data.forceTransitionTime = 0;
|
|
59343
|
+
}
|
|
58628
59344
|
if (!this.outfit.containsAssetType("Gear")) {
|
|
58629
59345
|
if (this.outfit.playerAvatarType === AvatarType.R15) {
|
|
58630
|
-
this.
|
|
58631
|
-
|
|
58632
|
-
|
|
59346
|
+
if (this.hasAnimationSetAnimation("pose")) {
|
|
59347
|
+
this.setMainAnimation("pose").then(() => {
|
|
59348
|
+
resolve(void 0);
|
|
59349
|
+
});
|
|
59350
|
+
} else {
|
|
59351
|
+
this.setMainAnimation("idle:0").then(() => {
|
|
59352
|
+
resolve(void 0);
|
|
59353
|
+
});
|
|
59354
|
+
}
|
|
58633
59355
|
} else {
|
|
58634
|
-
this.setMainAnimation("idle").then(() => {
|
|
59356
|
+
this.setMainAnimation("idle:0").then(() => {
|
|
58635
59357
|
resolve(void 0);
|
|
58636
59358
|
});
|
|
58637
59359
|
}
|
|
@@ -58642,8 +59364,10 @@ class OutfitRenderer {
|
|
|
58642
59364
|
}
|
|
58643
59365
|
});
|
|
58644
59366
|
});
|
|
58645
|
-
this.animateOnce(
|
|
59367
|
+
this.animateOnce(0);
|
|
59368
|
+
if (this.outfit.playerAvatarType !== AvatarType.R6 && this.animatorW?.data.currentAnimation === "idle") this.animateOnce((this.animatorW?.data.currentAnimationTrack?.length || 0) / 2);
|
|
58646
59369
|
if (this.currentRig) RBXRenderer.addInstance(this.currentRig, this.auth, this.renderScene);
|
|
59370
|
+
this.hasFiredFullyRendered = false;
|
|
58647
59371
|
await new Promise((resolve) => {
|
|
58648
59372
|
const connection = this.onRenderSuccess.Connect(() => {
|
|
58649
59373
|
resolve(void 0);
|
|
@@ -58727,102 +59451,6 @@ async function modelThumbnailClick(renderScene, format, options) {
|
|
|
58727
59451
|
binary: format === "glb"
|
|
58728
59452
|
});
|
|
58729
59453
|
}
|
|
58730
|
-
function getCorners(cframe, size) {
|
|
58731
|
-
const halfX = size.X / 2;
|
|
58732
|
-
const halfY = size.Y / 2;
|
|
58733
|
-
const halfZ = size.Z / 2;
|
|
58734
|
-
return [
|
|
58735
|
-
cframe.multiply(new CFrame(halfX, halfY, halfZ)),
|
|
58736
|
-
cframe.multiply(new CFrame(halfX, halfY, -halfZ)),
|
|
58737
|
-
cframe.multiply(new CFrame(-halfX, halfY, halfZ)),
|
|
58738
|
-
cframe.multiply(new CFrame(-halfX, halfY, -halfZ)),
|
|
58739
|
-
cframe.multiply(new CFrame(halfX, -halfY, halfZ)),
|
|
58740
|
-
cframe.multiply(new CFrame(halfX, -halfY, -halfZ)),
|
|
58741
|
-
cframe.multiply(new CFrame(-halfX, -halfY, halfZ)),
|
|
58742
|
-
cframe.multiply(new CFrame(-halfX, -halfY, -halfZ))
|
|
58743
|
-
];
|
|
58744
|
-
}
|
|
58745
|
-
function getLower(a, b) {
|
|
58746
|
-
return new Vector3(
|
|
58747
|
-
a.X < b.X ? a.X : b.X,
|
|
58748
|
-
a.Y < b.Y ? a.Y : b.Y,
|
|
58749
|
-
a.Z < b.Z ? a.Z : b.Z
|
|
58750
|
-
);
|
|
58751
|
-
}
|
|
58752
|
-
function getHigher(a, b) {
|
|
58753
|
-
return new Vector3(
|
|
58754
|
-
a.X > b.X ? a.X : b.X,
|
|
58755
|
-
a.Y > b.Y ? a.Y : b.Y,
|
|
58756
|
-
a.Z > b.Z ? a.Z : b.Z
|
|
58757
|
-
);
|
|
58758
|
-
}
|
|
58759
|
-
function getExtentsForParts(parts, includeTransform) {
|
|
58760
|
-
let lowerExtents = new Vector3(0, 0, 0);
|
|
58761
|
-
let higherExtents = new Vector3(0, 0, 0);
|
|
58762
|
-
for (const child of parts) {
|
|
58763
|
-
if (child.createWrapper()?.IsA("BasePart")) {
|
|
58764
|
-
const cframe = traverseRigCFrame(child, includeTransform, true);
|
|
58765
|
-
const size = child.Prop("Size");
|
|
58766
|
-
const corners = getCorners(cframe, size);
|
|
58767
|
-
for (const corner of corners) {
|
|
58768
|
-
lowerExtents = getLower(lowerExtents, new Vector3().fromVec3(corner.Position));
|
|
58769
|
-
higherExtents = getHigher(higherExtents, new Vector3().fromVec3(corner.Position));
|
|
58770
|
-
}
|
|
58771
|
-
}
|
|
58772
|
-
}
|
|
58773
|
-
return [lowerExtents, higherExtents];
|
|
58774
|
-
}
|
|
58775
|
-
function getExtents(cframe, parts) {
|
|
58776
|
-
const inverseCF = cframe.inverse();
|
|
58777
|
-
let lowerExtents = new Vector3(0, 0, 0);
|
|
58778
|
-
let higherExtents = new Vector3(0, 0, 0);
|
|
58779
|
-
for (const child of parts) {
|
|
58780
|
-
if (child.createWrapper()?.IsA("BasePart")) {
|
|
58781
|
-
const partCF = child.Prop("CFrame");
|
|
58782
|
-
const partSize = child.Prop("Size");
|
|
58783
|
-
const corners = getCorners(inverseCF.multiply(partCF), partSize);
|
|
58784
|
-
for (const corner of corners) {
|
|
58785
|
-
lowerExtents = getLower(lowerExtents, new Vector3().fromVec3(corner.Position));
|
|
58786
|
-
higherExtents = getHigher(higherExtents, new Vector3().fromVec3(corner.Position));
|
|
58787
|
-
}
|
|
58788
|
-
}
|
|
58789
|
-
}
|
|
58790
|
-
return [lowerExtents, higherExtents];
|
|
58791
|
-
}
|
|
58792
|
-
function getExtentsWorld(rig) {
|
|
58793
|
-
const rigParts = [];
|
|
58794
|
-
for (const child of rig.GetDescendants()) {
|
|
58795
|
-
if (child.createWrapper()?.IsA("BasePart")) {
|
|
58796
|
-
rigParts.push(child);
|
|
58797
|
-
}
|
|
58798
|
-
}
|
|
58799
|
-
const extents = getExtents(new CFrame(), rigParts);
|
|
58800
|
-
return extents;
|
|
58801
|
-
}
|
|
58802
|
-
function getExtentsCenter(extents) {
|
|
58803
|
-
return extents[1].minus(extents[0]).divide(new Vector3(2, 2, 2)).add(extents[0]);
|
|
58804
|
-
}
|
|
58805
|
-
function zoomExtents(cameraCFrame, modelCFrame, modelSize, targetFOV, distanceScale, sizeType = "calculate") {
|
|
58806
|
-
let largestSize = Math.max(modelSize.X, modelSize.Y, modelSize.Z);
|
|
58807
|
-
if (sizeType === "calculate") {
|
|
58808
|
-
largestSize = modelSize.magnitude() / 2 / Math.sin(rad(targetFOV / 2));
|
|
58809
|
-
}
|
|
58810
|
-
const fovMultiplier = sizeType === "largestAxis" ? 70 / targetFOV : 1;
|
|
58811
|
-
const lookDir = multiply(normalize(minus(cameraCFrame.Position, modelCFrame.Position)), [distanceScale, distanceScale, distanceScale]);
|
|
58812
|
-
cameraCFrame.Position = add(modelCFrame.Position, multiply(multiply(lookDir, [largestSize, largestSize, largestSize]), [fovMultiplier, fovMultiplier, fovMultiplier]));
|
|
58813
|
-
}
|
|
58814
|
-
function getCameraOffset(fov2, extentsSize) {
|
|
58815
|
-
const halfSize = extentsSize.magnitude() / 2;
|
|
58816
|
-
const fovDivisor = Math.tan(rad(fov2 / 2));
|
|
58817
|
-
return halfSize / fovDivisor;
|
|
58818
|
-
}
|
|
58819
|
-
function zoomToExtents(cameraCFrame, modelCFrame, modelSize, fov2 = 70) {
|
|
58820
|
-
const cameraOffset = getCameraOffset(fov2, modelSize);
|
|
58821
|
-
const cameraRotation = new CFrame();
|
|
58822
|
-
cameraRotation.Orientation = cameraCFrame.Orientation;
|
|
58823
|
-
const instancePosition = modelCFrame.Position;
|
|
58824
|
-
cameraCFrame.Position = add(instancePosition, multiply(minus([0, 0, 0], cameraRotation.lookVector()), [cameraOffset, cameraOffset, cameraOffset]));
|
|
58825
|
-
}
|
|
58826
59454
|
function getThumbnailCameraCFrame(model, fov2, forceAngle) {
|
|
58827
59455
|
const thumbnailCamera = model.FindFirstChildOfClass("Camera");
|
|
58828
59456
|
if (thumbnailCamera) return thumbnailCamera.PropOrDefault("CFrame", new CFrame());
|
|
@@ -58869,7 +59497,7 @@ function setupThumbnailScene(renderScene) {
|
|
|
58869
59497
|
if (renderScene.shadowPlane) renderScene.scene.remove(renderScene.shadowPlane);
|
|
58870
59498
|
renderScene.scene.background = null;
|
|
58871
59499
|
}
|
|
58872
|
-
async function generateOutfitThumbnail(auth, outfit, size = [150, 150], type = "png", quality = 1, gltfAutoDownload = false, includeAnimations = false, renderSceneParam) {
|
|
59500
|
+
async function generateOutfitThumbnail(auth, outfit, size = [150, 150], type = "png", quality = 1, gltfAutoDownload = false, includeAnimations = false, renderSceneParam, thumbnailCameraType = "default") {
|
|
58873
59501
|
const renderScene = renderSceneParam || RBXRenderer.addScene();
|
|
58874
59502
|
if (renderScene !== renderSceneParam) {
|
|
58875
59503
|
setupThumbnailScene(renderScene);
|
|
@@ -58882,9 +59510,25 @@ async function generateOutfitThumbnail(auth, outfit, size = [150, 150], type = "
|
|
|
58882
59510
|
return void 0;
|
|
58883
59511
|
}
|
|
58884
59512
|
if (outfitRenderer.currentRig) {
|
|
58885
|
-
|
|
59513
|
+
let cameraCFrame = new CFrame();
|
|
59514
|
+
switch (thumbnailCameraType) {
|
|
59515
|
+
case "default":
|
|
59516
|
+
cameraCFrame = getThumbnailCameraCFrame(outfitRenderer.currentRig, renderScene.camera.fov) || cameraCFrame;
|
|
59517
|
+
break;
|
|
59518
|
+
case "avatarHeadshot":
|
|
59519
|
+
cameraCFrame = getCameraCFrameForHeadshotCustomized(outfitRenderer.currentRig, 28, 0, 1) || cameraCFrame;
|
|
59520
|
+
break;
|
|
59521
|
+
case "avatarFullbody":
|
|
59522
|
+
cameraCFrame = getCameraCFrameForAvatarCustomized(outfitRenderer.currentRig, 28, 0) || cameraCFrame;
|
|
59523
|
+
break;
|
|
59524
|
+
case "fullbody":
|
|
59525
|
+
cameraCFrame = getFullBodyCameraCFrame(outfitRenderer.currentRig) || cameraCFrame;
|
|
59526
|
+
break;
|
|
59527
|
+
}
|
|
58886
59528
|
if (cameraCFrame) {
|
|
58887
59529
|
RBXRenderer.setCameraCFrame(cameraCFrame, renderScene);
|
|
59530
|
+
RBXRenderer.setCameraFov(thumbnailCameraType === "default" ? 70 : thumbnailCameraType === "fullbody" ? 56 : 28, renderScene);
|
|
59531
|
+
renderScene.camera.updateProjectionMatrix();
|
|
58888
59532
|
}
|
|
58889
59533
|
outfitRenderer.updateParticleMatrix();
|
|
58890
59534
|
const result = type === "gltf" || type === "glb" ? await modelThumbnailClick(renderScene, type, {
|
|
@@ -58917,37 +59561,7 @@ async function generateOutfitModelThumbnail(auth, outfitModel, options) {
|
|
|
58917
59561
|
includeAnimations: false
|
|
58918
59562
|
};
|
|
58919
59563
|
Object.assign(defaultOptions, options);
|
|
58920
|
-
|
|
58921
|
-
setupThumbnailScene(renderScene);
|
|
58922
|
-
if (outfitModel.background?.id) {
|
|
58923
|
-
const avatarCycloramaRBX = await API.Asset.GetRBX("roavatar://AvatarCyclorama.rbxm");
|
|
58924
|
-
if (avatarCycloramaRBX instanceof Response) return void 0;
|
|
58925
|
-
const avatarCycloramaRoot = avatarCycloramaRBX.generateTree();
|
|
58926
|
-
const avatarCyclorama = avatarCycloramaRoot.GetChildren()[0];
|
|
58927
|
-
if (avatarCyclorama) {
|
|
58928
|
-
const backgroundDataRBX = await API.Asset.GetRBX("rbxassetid://" + outfitModel.background.id);
|
|
58929
|
-
if (backgroundDataRBX instanceof Response) return void 0;
|
|
58930
|
-
const backgroundDataRoot = backgroundDataRBX.generateTree();
|
|
58931
|
-
const backgroundData = backgroundDataRoot.GetChildren()[0];
|
|
58932
|
-
if (backgroundData) {
|
|
58933
|
-
if (backgroundData) {
|
|
58934
|
-
const colorValue = backgroundData.Child("Color");
|
|
58935
|
-
const imageIdValue = backgroundData.Child("ImageId");
|
|
58936
|
-
if (colorValue && imageIdValue) {
|
|
58937
|
-
const color2 = colorValue.Prop("Value");
|
|
58938
|
-
const imageId = imageIdValue.Prop("Value");
|
|
58939
|
-
avatarCyclorama.Child("color_mesh").setProperty("Color", color2.toColor3uint8());
|
|
58940
|
-
avatarCyclorama.Child("texture_mesh").setProperty("TextureID", `rbxassetid://${imageId}`);
|
|
58941
|
-
avatarCyclorama.preRender();
|
|
58942
|
-
RBXRenderer.addInstance(avatarCyclorama, auth, renderScene);
|
|
58943
|
-
renderScene.camera.fov = 30;
|
|
58944
|
-
renderScene.camera.updateProjectionMatrix();
|
|
58945
|
-
}
|
|
58946
|
-
}
|
|
58947
|
-
}
|
|
58948
|
-
}
|
|
58949
|
-
}
|
|
58950
|
-
return generateOutfitThumbnail(auth, outfitModel.outfit, defaultOptions.size, defaultOptions.type, defaultOptions.quality, defaultOptions.gltfAutoDownload, defaultOptions.includeAnimations, renderScene);
|
|
59564
|
+
return generateOutfitThumbnail(auth, outfitModel, defaultOptions.size, defaultOptions.type, defaultOptions.quality, defaultOptions.gltfAutoDownload, defaultOptions.includeAnimations);
|
|
58951
59565
|
}
|
|
58952
59566
|
function renderToRenderTarget(width, height, renderScene) {
|
|
58953
59567
|
const renderTarget = new WebGLRenderTarget(width, height, {
|
|
@@ -59030,79 +59644,6 @@ function exposeThumbnailGenerator() {
|
|
|
59030
59644
|
globalThis.setupThumbnailScene = setupThumbnailScene;
|
|
59031
59645
|
globalThis.getThumbnailCameraCFrame = getThumbnailCameraCFrame;
|
|
59032
59646
|
}
|
|
59033
|
-
function getHeadExtents(rig) {
|
|
59034
|
-
const head = rig.FindFirstChild("Head");
|
|
59035
|
-
if (!head) return;
|
|
59036
|
-
const headParts = [];
|
|
59037
|
-
for (const child of rig.GetDescendants()) {
|
|
59038
|
-
if (child === head) {
|
|
59039
|
-
headParts.push(head);
|
|
59040
|
-
} else {
|
|
59041
|
-
const weld = child.FindFirstChildOfClass("Weld");
|
|
59042
|
-
if (weld && child.parent && child.parent.className === "Accessory") {
|
|
59043
|
-
if (weld.Prop("Part0") === head || weld.Prop("Part1") === head) {
|
|
59044
|
-
headParts.push(child);
|
|
59045
|
-
}
|
|
59046
|
-
}
|
|
59047
|
-
}
|
|
59048
|
-
}
|
|
59049
|
-
const extents = getExtents(head.Prop("CFrame"), headParts);
|
|
59050
|
-
return extents;
|
|
59051
|
-
}
|
|
59052
|
-
function getCameraCFrameForHeadshotCustomized(rig, fov2, yRot, distance2) {
|
|
59053
|
-
const head = rig.FindFirstChild("Head");
|
|
59054
|
-
if (!head) return;
|
|
59055
|
-
const headCF = head.PropOrDefault("CFrame", new CFrame());
|
|
59056
|
-
const headLocalExtents = getHeadExtents(rig);
|
|
59057
|
-
if (!headLocalExtents) return;
|
|
59058
|
-
const headCenterPosLocal = headLocalExtents[0].add(headLocalExtents[1].minus(headLocalExtents[0]).divide(new Vector3(2, 2, 2)));
|
|
59059
|
-
const headCenterPos = new Vector3().fromVec3(headCF.multiply(new CFrame(...headCenterPosLocal.toVec3())).Position);
|
|
59060
|
-
const headCenterCF = new CFrame(...headCenterPos.toVec3());
|
|
59061
|
-
let lookVector = headCF.lookVector();
|
|
59062
|
-
if (Math.abs(lookVector[1]) > 0.95) {
|
|
59063
|
-
lookVector = [0, 0, -1];
|
|
59064
|
-
} else {
|
|
59065
|
-
lookVector[1] = 0;
|
|
59066
|
-
lookVector = normalize(lookVector);
|
|
59067
|
-
}
|
|
59068
|
-
let lookCF = CFrame.lookAt([0, 0, 0], lookVector);
|
|
59069
|
-
lookCF = lookCF.multiply(CFrame.fromEulerAngles(0, rad(yRot), 0, "ZXY"));
|
|
59070
|
-
lookVector = lookCF.lookVector();
|
|
59071
|
-
const fovMultiplier = 70 / fov2;
|
|
59072
|
-
lookCF.Position = add(headCenterCF.Position, multiply(multiply([10, 10, 10], lookVector), [fovMultiplier, fovMultiplier, fovMultiplier]));
|
|
59073
|
-
lookCF = CFrame.lookAt(lookCF.Position, headCenterCF.Position);
|
|
59074
|
-
const cameraCF = lookCF.clone();
|
|
59075
|
-
zoomExtents(cameraCF, headCenterCF, headLocalExtents[1].minus(headLocalExtents[0]), fov2, distance2, "largestAxis");
|
|
59076
|
-
return cameraCF;
|
|
59077
|
-
}
|
|
59078
|
-
function getCameraCFrameForAvatarNonCustomized(rig) {
|
|
59079
|
-
const thumbnailCamera = rig.FindFirstChildOfClass("Camera");
|
|
59080
|
-
if (thumbnailCamera) return thumbnailCamera.PropOrDefault("CFrame", new CFrame());
|
|
59081
|
-
let rootPart = rig.PropOrDefault("PrimaryPart", void 0);
|
|
59082
|
-
if (!rootPart) rootPart = rig.FindFirstChildOfClass("Part");
|
|
59083
|
-
if (!rootPart) rootPart = rig.FindFirstChildOfClass("MeshPart");
|
|
59084
|
-
if (!rootPart) return;
|
|
59085
|
-
const rootPartCF = rootPart.PropOrDefault("CFrame", new CFrame()).clone();
|
|
59086
|
-
const worldExtents = getExtentsWorld(rig);
|
|
59087
|
-
if (!worldExtents) return;
|
|
59088
|
-
const extentsSize = worldExtents[1].minus(worldExtents[0]);
|
|
59089
|
-
rootPartCF.Position = getExtentsCenter(worldExtents).toVec3();
|
|
59090
|
-
let lookVector = rootPartCF.lookVector();
|
|
59091
|
-
if (Math.abs(lookVector[1]) > 0.95) {
|
|
59092
|
-
lookVector = [0, 0, -1];
|
|
59093
|
-
} else {
|
|
59094
|
-
lookVector[1] = 0;
|
|
59095
|
-
lookVector = normalize(lookVector);
|
|
59096
|
-
}
|
|
59097
|
-
let lookCF = CFrame.lookAt([0, 0, 0], lookVector);
|
|
59098
|
-
lookCF = lookCF.multiply(CFrame.fromEulerAngles(25 * Math.PI / 180, 27.5 * Math.PI / 180, 0, "ZXY"));
|
|
59099
|
-
lookVector = lookCF.lookVector();
|
|
59100
|
-
lookCF.Position = add(rootPartCF.Position, multiply([10, 10, 10], lookVector));
|
|
59101
|
-
lookCF = CFrame.lookAt(lookCF.Position, rootPartCF.Position);
|
|
59102
|
-
const cameraCF = lookCF.clone();
|
|
59103
|
-
zoomExtents(cameraCF, rootPartCF, extentsSize, 70, 1);
|
|
59104
|
-
return cameraCF;
|
|
59105
|
-
}
|
|
59106
59647
|
export {
|
|
59107
59648
|
API,
|
|
59108
59649
|
AbbreviationToFaceControlProperty,
|
|
@@ -59138,6 +59679,7 @@ export {
|
|
|
59138
59679
|
AttachmentWrapper,
|
|
59139
59680
|
Authentication,
|
|
59140
59681
|
AvatarType,
|
|
59682
|
+
BackgroundRenderer,
|
|
59141
59683
|
BasePartWrapper,
|
|
59142
59684
|
BodyColor3s,
|
|
59143
59685
|
BodyColors,
|
|
@@ -59152,8 +59694,12 @@ export {
|
|
|
59152
59694
|
BundleTypes,
|
|
59153
59695
|
CACHE,
|
|
59154
59696
|
CFrame,
|
|
59697
|
+
CONSTANTS_CameraPresetsUtility,
|
|
59698
|
+
CONSTANTS_CameraUtility,
|
|
59155
59699
|
COREMESH,
|
|
59156
59700
|
Cache,
|
|
59701
|
+
CameraType,
|
|
59702
|
+
CameraWrapper,
|
|
59157
59703
|
CatalogBundleTypes,
|
|
59158
59704
|
CategoryDictionary,
|
|
59159
59705
|
Color3,
|
|
@@ -59217,11 +59763,14 @@ export {
|
|
|
59217
59763
|
PartType,
|
|
59218
59764
|
PartWrapper,
|
|
59219
59765
|
ParticleEmitterShapeInOut,
|
|
59766
|
+
ParticleEmitterWrapper,
|
|
59220
59767
|
ParticleFlipbookLayout,
|
|
59221
59768
|
ParticleFlipbookMode,
|
|
59222
59769
|
ParticleOrientation,
|
|
59223
59770
|
Property,
|
|
59224
59771
|
PropertyTypeInfo,
|
|
59772
|
+
R15BodyPartNames,
|
|
59773
|
+
R6BodyPartNames,
|
|
59225
59774
|
RBFDeformerPatch,
|
|
59226
59775
|
RBX,
|
|
59227
59776
|
RBXRenderer,
|
|
@@ -59275,6 +59824,7 @@ export {
|
|
|
59275
59824
|
browserSendMessage,
|
|
59276
59825
|
buildFaceKD,
|
|
59277
59826
|
buildVertKD,
|
|
59827
|
+
calculateBaseDistanceToCamera,
|
|
59278
59828
|
calculateMagnitude3D,
|
|
59279
59829
|
calculateMotor6Doffset,
|
|
59280
59830
|
clamp,
|
|
@@ -59283,6 +59833,7 @@ export {
|
|
|
59283
59833
|
cloneSearch_Payload,
|
|
59284
59834
|
closestPointTriangle,
|
|
59285
59835
|
createContentMap,
|
|
59836
|
+
createThumbnailCamera,
|
|
59286
59837
|
createWeightsForMeshChunked,
|
|
59287
59838
|
cross,
|
|
59288
59839
|
defaultPantAssetIds,
|
|
@@ -59307,14 +59858,20 @@ export {
|
|
|
59307
59858
|
generateOutfitModelThumbnail,
|
|
59308
59859
|
generateOutfitThumbnail,
|
|
59309
59860
|
generateUUIDv4,
|
|
59861
|
+
getAvatarCameraCFrame,
|
|
59862
|
+
getCameraCFrame,
|
|
59863
|
+
getCameraCFrameForAvatarCustomized,
|
|
59310
59864
|
getCameraCFrameForAvatarNonCustomized,
|
|
59311
59865
|
getCameraCFrameForHeadshotCustomized,
|
|
59866
|
+
getCharacterTorsoCFrame,
|
|
59312
59867
|
getDistIndexArray,
|
|
59313
59868
|
getExtents,
|
|
59314
59869
|
getExtentsCenter,
|
|
59315
59870
|
getExtentsForParts,
|
|
59316
59871
|
getExtentsWorld,
|
|
59872
|
+
getFullBodyCameraCFrame,
|
|
59317
59873
|
getHeadExtents,
|
|
59874
|
+
getHeadshotCameraCFrame,
|
|
59318
59875
|
getOffsetArray,
|
|
59319
59876
|
getOriginalAttachmentOrientation,
|
|
59320
59877
|
getOriginalAttachmentPosition,
|
|
@@ -59369,6 +59926,10 @@ export {
|
|
|
59369
59926
|
rotationMatrixToEulerAngles,
|
|
59370
59927
|
saveByteArray,
|
|
59371
59928
|
scaleMesh,
|
|
59929
|
+
setupAccessoryCamera,
|
|
59930
|
+
setupBodyPartCamera,
|
|
59931
|
+
setupCamera,
|
|
59932
|
+
setupHeadCamera,
|
|
59372
59933
|
setupThumbnailScene,
|
|
59373
59934
|
snapToNumber,
|
|
59374
59935
|
specialClamp,
|