roavatar-renderer 1.6.0 → 1.6.1
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 +855 -282
- 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);
|
|
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;
|
|
@@ -49217,7 +49305,7 @@ class AnimatorWrapper extends InstanceWrapper {
|
|
|
49217
49305
|
}
|
|
49218
49306
|
/**
|
|
49219
49307
|
* Switches to new animation
|
|
49220
|
-
* @param name Animation name, such as "idle", "walk", "emote.1234" or "id.1234"
|
|
49308
|
+
* @param name Animation name, such as "idle", "walk", "emote.1234" or "id.1234", can also specify sub animation like "idle:0"
|
|
49221
49309
|
* @param type
|
|
49222
49310
|
* @returns If animation sucessfully played
|
|
49223
49311
|
*/
|
|
@@ -49234,6 +49322,12 @@ class AnimatorWrapper extends InstanceWrapper {
|
|
|
49234
49322
|
this.restPose(false, true);
|
|
49235
49323
|
}
|
|
49236
49324
|
}
|
|
49325
|
+
let subAnimSpecifier = -1;
|
|
49326
|
+
if (name.includes(":")) {
|
|
49327
|
+
const splitName = name.split(":");
|
|
49328
|
+
name = splitName[0];
|
|
49329
|
+
subAnimSpecifier = Number(splitName[1]);
|
|
49330
|
+
}
|
|
49237
49331
|
switch (type) {
|
|
49238
49332
|
case "main":
|
|
49239
49333
|
if (this.data.currentAnimation !== name) {
|
|
@@ -49243,7 +49337,8 @@ class AnimatorWrapper extends InstanceWrapper {
|
|
|
49243
49337
|
this.stopMoodAnimation();
|
|
49244
49338
|
}
|
|
49245
49339
|
log(false, "playing", name);
|
|
49246
|
-
|
|
49340
|
+
log(false, this.data.forceTransitionTime);
|
|
49341
|
+
return this._switchAnimation(name, subAnimSpecifier);
|
|
49247
49342
|
} else {
|
|
49248
49343
|
return true;
|
|
49249
49344
|
}
|
|
@@ -49392,6 +49487,25 @@ const __vite_glob_0_8 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def
|
|
|
49392
49487
|
__proto__: null,
|
|
49393
49488
|
BoneWrapper
|
|
49394
49489
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
49490
|
+
class CameraWrapper extends InstanceWrapper {
|
|
49491
|
+
static className = "Camera";
|
|
49492
|
+
static requiredProperties = [
|
|
49493
|
+
"Name",
|
|
49494
|
+
"CFrame",
|
|
49495
|
+
"CameraType",
|
|
49496
|
+
"FieldOfView"
|
|
49497
|
+
];
|
|
49498
|
+
setup() {
|
|
49499
|
+
this.addProp("Name", DataType.String, this.instance.className);
|
|
49500
|
+
this.addProp("CFrame", DataType.CFrame, new CFrame());
|
|
49501
|
+
this.addProp("CameraType", DataType.Enum, CameraType.Fixed);
|
|
49502
|
+
this.addProp("FieldOfView", DataType.Float32, 70);
|
|
49503
|
+
}
|
|
49504
|
+
}
|
|
49505
|
+
const __vite_glob_0_9 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
49506
|
+
__proto__: null,
|
|
49507
|
+
CameraWrapper
|
|
49508
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
49395
49509
|
class DecalWrapper extends InstanceWrapper {
|
|
49396
49510
|
static className = "Decal";
|
|
49397
49511
|
static requiredProperties = [
|
|
@@ -49413,7 +49527,7 @@ class DecalWrapper extends InstanceWrapper {
|
|
|
49413
49527
|
if (!this.instance.HasProperty("UVScale")) this.instance.addProperty(new Property("UVScale", DataType.Vector2), new Vector2());
|
|
49414
49528
|
}
|
|
49415
49529
|
}
|
|
49416
|
-
const
|
|
49530
|
+
const __vite_glob_0_11 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
49417
49531
|
__proto__: null,
|
|
49418
49532
|
DecalWrapper
|
|
49419
49533
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -49557,7 +49671,7 @@ class MakeupDescriptionWrapper extends InstanceWrapper {
|
|
|
49557
49671
|
if (!this.instance.HasProperty("Instance")) this.instance.addProperty(new Property("Instance", DataType.Referent), void 0);
|
|
49558
49672
|
}
|
|
49559
49673
|
}
|
|
49560
|
-
const
|
|
49674
|
+
const __vite_glob_0_16 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
49561
49675
|
__proto__: null,
|
|
49562
49676
|
MakeupDescriptionWrapper
|
|
49563
49677
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -50795,12 +50909,16 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
|
|
|
50795
50909
|
if (this.instance.PropOrDefault(animationProp, 0n) > 0n && avatarType === AvatarType.R15) {
|
|
50796
50910
|
const id = this.instance.Prop(animationProp);
|
|
50797
50911
|
promises.push(new Promise((resolve) => {
|
|
50912
|
+
if (animationProp === "IdleAnimation") {
|
|
50913
|
+
delete animatorW.data.animationSet["pose"];
|
|
50914
|
+
}
|
|
50798
50915
|
animatorW.loadAvatarAnimation(id, false, true).then((result) => {
|
|
50799
50916
|
resolve(result);
|
|
50800
50917
|
});
|
|
50801
50918
|
}));
|
|
50802
50919
|
} else {
|
|
50803
50920
|
this._loadDefaultAnimation(animationProp, avatarType, animatorW, promises);
|
|
50921
|
+
if (animationProp === "IdleAnimation" && !toChange.includes("pose")) this._loadDefaultAnimation("pose", avatarType, animatorW, promises);
|
|
50804
50922
|
}
|
|
50805
50923
|
}
|
|
50806
50924
|
const values = await Promise.all(promises);
|
|
@@ -50935,7 +51053,7 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
|
|
|
50935
51053
|
return this.instance;
|
|
50936
51054
|
}
|
|
50937
51055
|
}
|
|
50938
|
-
const
|
|
51056
|
+
const __vite_glob_0_13 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
50939
51057
|
__proto__: null,
|
|
50940
51058
|
HumanoidDescriptionWrapper
|
|
50941
51059
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -51070,14 +51188,14 @@ class JointInstanceWrapper extends InstanceWrapper {
|
|
|
51070
51188
|
}
|
|
51071
51189
|
}
|
|
51072
51190
|
}
|
|
51073
|
-
const
|
|
51191
|
+
const __vite_glob_0_15 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
51074
51192
|
__proto__: null,
|
|
51075
51193
|
JointInstanceWrapper
|
|
51076
51194
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
51077
51195
|
class ManualWeldWrapper extends JointInstanceWrapper {
|
|
51078
51196
|
static className = "ManualWeld";
|
|
51079
51197
|
}
|
|
51080
|
-
const
|
|
51198
|
+
const __vite_glob_0_17 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
51081
51199
|
__proto__: null,
|
|
51082
51200
|
ManualWeldWrapper
|
|
51083
51201
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -51092,7 +51210,7 @@ class MeshPartWrapper extends BasePartWrapper {
|
|
|
51092
51210
|
if (!this.instance.HasProperty("DoubleSided")) this.instance.addProperty(new Property("DoubleSided", DataType.Bool), false);
|
|
51093
51211
|
}
|
|
51094
51212
|
}
|
|
51095
|
-
const
|
|
51213
|
+
const __vite_glob_0_18 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
51096
51214
|
__proto__: null,
|
|
51097
51215
|
MeshPartWrapper
|
|
51098
51216
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -51111,7 +51229,7 @@ class ModelWrapper extends InstanceWrapper {
|
|
|
51111
51229
|
throw new Error("Model has no PrimaryPart");
|
|
51112
51230
|
}
|
|
51113
51231
|
}
|
|
51114
|
-
const
|
|
51232
|
+
const __vite_glob_0_19 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
51115
51233
|
__proto__: null,
|
|
51116
51234
|
ModelWrapper
|
|
51117
51235
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -51126,7 +51244,7 @@ class Motor6DWrapper extends JointInstanceWrapper {
|
|
|
51126
51244
|
if (!this.instance.HasProperty("Transform")) this.instance.addProperty(new Property("Transform", DataType.CFrame), new CFrame());
|
|
51127
51245
|
}
|
|
51128
51246
|
}
|
|
51129
|
-
const
|
|
51247
|
+
const __vite_glob_0_20 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
51130
51248
|
__proto__: null,
|
|
51131
51249
|
Motor6DWrapper
|
|
51132
51250
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -51141,7 +51259,7 @@ class PartWrapper extends BasePartWrapper {
|
|
|
51141
51259
|
if (!this.instance.HasProperty("shape")) this.instance.addProperty(new Property("shape", DataType.Enum), PartType.Block);
|
|
51142
51260
|
}
|
|
51143
51261
|
}
|
|
51144
|
-
const
|
|
51262
|
+
const __vite_glob_0_21 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
51145
51263
|
__proto__: null,
|
|
51146
51264
|
PartWrapper
|
|
51147
51265
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -52066,7 +52184,7 @@ class ParticleEmitterWrapper extends InstanceWrapper {
|
|
|
52066
52184
|
}
|
|
52067
52185
|
}
|
|
52068
52186
|
}
|
|
52069
|
-
const
|
|
52187
|
+
const __vite_glob_0_22 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
52070
52188
|
__proto__: null,
|
|
52071
52189
|
ParticleEmitterWrapper
|
|
52072
52190
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -52172,7 +52290,7 @@ class SoundWrapper extends InstanceWrapper {
|
|
|
52172
52290
|
}
|
|
52173
52291
|
}
|
|
52174
52292
|
}
|
|
52175
|
-
const
|
|
52293
|
+
const __vite_glob_0_24 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
52176
52294
|
__proto__: null,
|
|
52177
52295
|
SoundWrapper
|
|
52178
52296
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -52426,7 +52544,7 @@ class ScriptWrapper extends InstanceWrapper {
|
|
|
52426
52544
|
}
|
|
52427
52545
|
}
|
|
52428
52546
|
}
|
|
52429
|
-
const
|
|
52547
|
+
const __vite_glob_0_23 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
52430
52548
|
__proto__: null,
|
|
52431
52549
|
ScriptWrapper
|
|
52432
52550
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -52483,25 +52601,25 @@ class ToolWrapper extends InstanceWrapper {
|
|
|
52483
52601
|
}
|
|
52484
52602
|
}
|
|
52485
52603
|
}
|
|
52486
|
-
const
|
|
52604
|
+
const __vite_glob_0_25 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
52487
52605
|
__proto__: null,
|
|
52488
52606
|
ToolWrapper
|
|
52489
52607
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
52490
52608
|
class WedgePartWrapper extends BasePartWrapper {
|
|
52491
52609
|
static className = "WedgePart";
|
|
52492
52610
|
}
|
|
52493
|
-
const
|
|
52611
|
+
const __vite_glob_0_26 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
52494
52612
|
__proto__: null,
|
|
52495
52613
|
WedgePartWrapper
|
|
52496
52614
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
52497
52615
|
class WeldWrapper extends JointInstanceWrapper {
|
|
52498
52616
|
static className = "Weld";
|
|
52499
52617
|
}
|
|
52500
|
-
const
|
|
52618
|
+
const __vite_glob_0_27 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
52501
52619
|
__proto__: null,
|
|
52502
52620
|
WeldWrapper
|
|
52503
52621
|
}, 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/
|
|
52622
|
+
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
52623
|
function RegisterWrappers() {
|
|
52506
52624
|
for (const module of Object.values(modules$1)) {
|
|
52507
52625
|
for (const exprt of Object.values(module)) {
|
|
@@ -58114,6 +58232,579 @@ class HSR {
|
|
|
58114
58232
|
}
|
|
58115
58233
|
}
|
|
58116
58234
|
}
|
|
58235
|
+
function getHeadAttachments(rig) {
|
|
58236
|
+
const headAttachments = /* @__PURE__ */ new Map();
|
|
58237
|
+
const head = rig.Child("Head");
|
|
58238
|
+
if (head) {
|
|
58239
|
+
for (const child of head.GetDescendants()) {
|
|
58240
|
+
if (child.IsA("Attachment")) {
|
|
58241
|
+
headAttachments.set(child.Prop("Name"), true);
|
|
58242
|
+
}
|
|
58243
|
+
}
|
|
58244
|
+
}
|
|
58245
|
+
return headAttachments;
|
|
58246
|
+
}
|
|
58247
|
+
function makeRotatedCorner(x, y, z, halfSize, cFrame) {
|
|
58248
|
+
const corner = Vector3.new(x * halfSize.X, y * halfSize.Y, z * halfSize.Z);
|
|
58249
|
+
const newCF = cFrame.multiply(new CFrame(...corner.toVec3()));
|
|
58250
|
+
return Vector3.new(...newCF.Position);
|
|
58251
|
+
}
|
|
58252
|
+
function growExtentsToIncludePoint(minExtent, maxExtent, point) {
|
|
58253
|
+
minExtent = Vector3.new(Math.min(point.X, minExtent.X), Math.min(point.Y, minExtent.Y), Math.min(point.Z, minExtent.Z));
|
|
58254
|
+
maxExtent = Vector3.new(Math.max(point.X, maxExtent.X), Math.max(point.Y, maxExtent.Y), Math.max(point.Z, maxExtent.Z));
|
|
58255
|
+
return [minExtent, maxExtent];
|
|
58256
|
+
}
|
|
58257
|
+
function growExtentsToInclude(minExtent, maxExtent, part, cInverse, optYMinCFrame, optYMin) {
|
|
58258
|
+
const size = part.Prop("Size").divide(new Vector3(2, 2, 2));
|
|
58259
|
+
for (let x = -1; x <= 1; x += 2) {
|
|
58260
|
+
for (let y = -1; y <= 1; y += 2) {
|
|
58261
|
+
for (let z = -1; z <= 1; z += 2) {
|
|
58262
|
+
let corner = makeRotatedCorner(x, y, z, size, part.Prop("CFrame"));
|
|
58263
|
+
if (optYMinCFrame && optYMin !== void 0) {
|
|
58264
|
+
const transformedCorner = new Vector3(...optYMinCFrame.inverse().multiply(new CFrame(...corner.toVec3())).Position);
|
|
58265
|
+
const clampedTransformedCorner = Vector3.new(transformedCorner.X, Math.max(optYMin, transformedCorner.Y), transformedCorner.Z);
|
|
58266
|
+
corner = new Vector3(...optYMinCFrame.multiply(new CFrame(...clampedTransformedCorner.toVec3())).Position);
|
|
58267
|
+
}
|
|
58268
|
+
corner = new Vector3(...cInverse.multiply(new CFrame(...corner.toVec3())).Position);
|
|
58269
|
+
[minExtent, maxExtent] = growExtentsToIncludePoint(minExtent, maxExtent, corner);
|
|
58270
|
+
}
|
|
58271
|
+
}
|
|
58272
|
+
}
|
|
58273
|
+
return [minExtent, maxExtent];
|
|
58274
|
+
}
|
|
58275
|
+
function initExtents() {
|
|
58276
|
+
const minExtent = Vector3.new(Infinity, Infinity, Infinity);
|
|
58277
|
+
const maxExtent = Vector3.new(-Infinity, -Infinity, -Infinity);
|
|
58278
|
+
return [minExtent, maxExtent];
|
|
58279
|
+
}
|
|
58280
|
+
function recursiveCalculateExtents(minExtent, maxExtent, instance, cInverse, indent) {
|
|
58281
|
+
for (const child of instance.GetChildren()) {
|
|
58282
|
+
if (child.IsA("BasePart")) {
|
|
58283
|
+
[minExtent, maxExtent] = growExtentsToInclude(minExtent, maxExtent, child, cInverse);
|
|
58284
|
+
}
|
|
58285
|
+
[minExtent, maxExtent] = recursiveCalculateExtents(minExtent, maxExtent, child, cInverse);
|
|
58286
|
+
}
|
|
58287
|
+
return [minExtent, maxExtent];
|
|
58288
|
+
}
|
|
58289
|
+
function calculateModelExtents(model, targetCFrame) {
|
|
58290
|
+
let [minExtent, maxExtent] = initExtents();
|
|
58291
|
+
const cInverse = targetCFrame.inverse();
|
|
58292
|
+
[minExtent, maxExtent] = recursiveCalculateExtents(minExtent, maxExtent, model, cInverse);
|
|
58293
|
+
return [minExtent, maxExtent];
|
|
58294
|
+
}
|
|
58295
|
+
function calculateHeadExtents(character, targetCFrame) {
|
|
58296
|
+
let [minExtent, maxExtent] = initExtents();
|
|
58297
|
+
const head = character.FindFirstChild("Head");
|
|
58298
|
+
if (!head) {
|
|
58299
|
+
return [minExtent, maxExtent];
|
|
58300
|
+
}
|
|
58301
|
+
const cInverse = targetCFrame.inverse();
|
|
58302
|
+
const untransformedHeadYMin = -head.Prop("Size").Y / 2;
|
|
58303
|
+
[minExtent, maxExtent] = growExtentsToInclude(minExtent, maxExtent, head, cInverse);
|
|
58304
|
+
const headAttachments = getHeadAttachments(character);
|
|
58305
|
+
for (const child of character.GetChildren()) {
|
|
58306
|
+
if (child.IsA("Accessory")) {
|
|
58307
|
+
const handle = child.FindFirstChild("Handle");
|
|
58308
|
+
if (handle) {
|
|
58309
|
+
const attachment = handle.FindFirstChildOfClass("Attachment");
|
|
58310
|
+
if (!attachment || headAttachments.has(attachment.Prop("Name"))) {
|
|
58311
|
+
[minExtent, maxExtent] = growExtentsToInclude(minExtent, maxExtent, handle, cInverse, head.Prop("CFrame"), untransformedHeadYMin);
|
|
58312
|
+
}
|
|
58313
|
+
}
|
|
58314
|
+
}
|
|
58315
|
+
}
|
|
58316
|
+
return [minExtent, maxExtent];
|
|
58317
|
+
}
|
|
58318
|
+
function calculateBodyPartsExtents(targetCFrame, bodyParts) {
|
|
58319
|
+
let [minExtent, maxExtent] = initExtents();
|
|
58320
|
+
const cInverse = targetCFrame.inverse();
|
|
58321
|
+
for (const part of bodyParts) {
|
|
58322
|
+
[minExtent, maxExtent] = growExtentsToInclude(minExtent, maxExtent, part, cInverse, targetCFrame);
|
|
58323
|
+
}
|
|
58324
|
+
return [minExtent, maxExtent];
|
|
58325
|
+
}
|
|
58326
|
+
function calculateTargetCFrame(baseCFrame) {
|
|
58327
|
+
let targetLookVector = new Vector3();
|
|
58328
|
+
if (Math.abs(baseCFrame.lookVector()[1]) > 0.9) {
|
|
58329
|
+
targetLookVector = new Vector3().fromVec3(baseCFrame.upVector());
|
|
58330
|
+
} else {
|
|
58331
|
+
targetLookVector = new Vector3().fromVec3(baseCFrame.lookVector());
|
|
58332
|
+
}
|
|
58333
|
+
targetLookVector = Vector3.new(targetLookVector.X, 0, targetLookVector.Z).normalize();
|
|
58334
|
+
return CFrame.lookAt(baseCFrame.Position, new Vector3().fromVec3(baseCFrame.Position).add(targetLookVector).toVec3());
|
|
58335
|
+
}
|
|
58336
|
+
function adjustTargetCFrameWithExtents(targetCFrame, minExtent, maxExtent) {
|
|
58337
|
+
let adjustment = minExtent.add(maxExtent).divide(new Vector3(2, 2, 2));
|
|
58338
|
+
const tmpCFrame = targetCFrame.rotationOnly();
|
|
58339
|
+
adjustment = tmpCFrame.multiplyVector(adjustment);
|
|
58340
|
+
targetCFrame.Position = add(targetCFrame.Position, adjustment.toVec3());
|
|
58341
|
+
return targetCFrame;
|
|
58342
|
+
}
|
|
58343
|
+
function vector3FromXYRotPlusDistance(xAngleDeg, yAngleDeg, radius) {
|
|
58344
|
+
const cFrame = CFrame.fromEulerAngles(rad(xAngleDeg), rad(yAngleDeg), 0, "XYZ");
|
|
58345
|
+
return new Vector3(...cFrame.lookVector()).multiply(new Vector3(radius, radius, radius));
|
|
58346
|
+
}
|
|
58347
|
+
const CONSTANTS_CameraUtility = {
|
|
58348
|
+
//When generating a head thumbnail, how much 'margin' around extent of head + accoutrements?
|
|
58349
|
+
DefaultHeadMarginScale: 1.1,
|
|
58350
|
+
//When generating a full body thumbnail, how much 'margin' around whole body?
|
|
58351
|
+
DefaultBodyMarginScale: 1.1,
|
|
58352
|
+
//Amount of margin around a body part in a generated thumbnail
|
|
58353
|
+
DefaultBodyPartMarginScale: 1.2,
|
|
58354
|
+
XRotForFullBody: 15,
|
|
58355
|
+
XRotForCloseup: 0,
|
|
58356
|
+
DistanceScaleForFullBody: 1
|
|
58357
|
+
};
|
|
58358
|
+
const HEAD_MARGIN_SCALE = 1.1;
|
|
58359
|
+
const HEAD_X_ROTATION_RAD = rad(15);
|
|
58360
|
+
const HEAD_Y_ROTATION_RAD = rad(30);
|
|
58361
|
+
const FACE_LEFT_CFRAME = CFrame.fromEulerAngles(rad(-20), rad(20), 0, "YXZ");
|
|
58362
|
+
const FACE_RIGHT_CFRAME = CFrame.fromEulerAngles(rad(-20), rad(-20), 0, "YXZ");
|
|
58363
|
+
const HEAD_BODYPART_FIELD_OF_VIEW_DEG = 30;
|
|
58364
|
+
const ACCESSORY_DEFAULT_CFRAME = CFrame.Angles(rad(25), rad(25), rad(0));
|
|
58365
|
+
const ACCESSORY_FIELD_OF_VIEW_DEG = 20;
|
|
58366
|
+
const ACCESSORY_EXTENT_SCALE = 1.1;
|
|
58367
|
+
const LEFT_SHOE_CFRAME = CFrame.Angles(rad(0), rad(90), rad(0));
|
|
58368
|
+
const RIGHT_SHOE_CFRAME = CFrame.Angles(rad(0), rad(-90), rad(0));
|
|
58369
|
+
function getCameraCFrame(targetCFrame, relativePos) {
|
|
58370
|
+
const cameraPos = targetCFrame.multiplyVector(relativePos);
|
|
58371
|
+
return CFrame.lookAt(cameraPos.toVec3(), targetCFrame.Position);
|
|
58372
|
+
}
|
|
58373
|
+
function createThumbnailCamera() {
|
|
58374
|
+
const camera = new Instance("Camera");
|
|
58375
|
+
camera.setProperty("Name", "ThumbnailCamera");
|
|
58376
|
+
camera.setProperty("CameraType", CameraType.Scriptable);
|
|
58377
|
+
return camera;
|
|
58378
|
+
}
|
|
58379
|
+
function calculateBaseDistanceToCamera(fieldOfViewRad, minExtent, maxExtent, marginScale) {
|
|
58380
|
+
const offsetFromCenter = Math.max((maxExtent.X - minExtent.X) / 2, (maxExtent.Y - minExtent.Y) / 2);
|
|
58381
|
+
const t = Math.tan(fieldOfViewRad / 2);
|
|
58382
|
+
return offsetFromCenter * marginScale / t;
|
|
58383
|
+
}
|
|
58384
|
+
function setupCamera(camera, cameraOptions) {
|
|
58385
|
+
if (cameraOptions.optFieldOfView) {
|
|
58386
|
+
camera.setProperty("FieldOfView", cameraOptions.optFieldOfView);
|
|
58387
|
+
}
|
|
58388
|
+
const fieldOfViewForDistanceScale = cameraOptions.optFieldOfViewForDistanceScale || camera.Prop("FieldOfView");
|
|
58389
|
+
let distanceToCamera = calculateBaseDistanceToCamera(
|
|
58390
|
+
rad(fieldOfViewForDistanceScale),
|
|
58391
|
+
cameraOptions.minExtent,
|
|
58392
|
+
cameraOptions.maxExtent,
|
|
58393
|
+
cameraOptions.extentScale
|
|
58394
|
+
);
|
|
58395
|
+
if (cameraOptions.optCameraDistanceScale) {
|
|
58396
|
+
distanceToCamera = distanceToCamera * cameraOptions.optCameraDistanceScale;
|
|
58397
|
+
}
|
|
58398
|
+
const finalTargetCFrame = adjustTargetCFrameWithExtents(
|
|
58399
|
+
cameraOptions.targetCFrame,
|
|
58400
|
+
cameraOptions.minExtent,
|
|
58401
|
+
cameraOptions.maxExtent
|
|
58402
|
+
);
|
|
58403
|
+
const cameraXRotDeg = cameraOptions.optCameraXRot || 0;
|
|
58404
|
+
const cameraYRotDeg = cameraOptions.optCameraYRot || 0;
|
|
58405
|
+
const cPos = vector3FromXYRotPlusDistance(cameraXRotDeg, cameraYRotDeg, distanceToCamera);
|
|
58406
|
+
camera.setProperty("CFrame", getCameraCFrame(finalTargetCFrame, cPos));
|
|
58407
|
+
}
|
|
58408
|
+
function setupBodyPartCamera(mannequin, faceRight, focusPartNames, camera) {
|
|
58409
|
+
const mannequinFocusParts = [];
|
|
58410
|
+
for (const focusPartName of focusPartNames) {
|
|
58411
|
+
const focusPart = mannequin.FindFirstDescendant(focusPartName);
|
|
58412
|
+
if (focusPart) {
|
|
58413
|
+
mannequinFocusParts.push(focusPart);
|
|
58414
|
+
}
|
|
58415
|
+
}
|
|
58416
|
+
const humanoidRootPart = mannequin.FindFirstChild("HumanoidRootPart");
|
|
58417
|
+
if (humanoidRootPart) {
|
|
58418
|
+
let mannequinTargetCFrame = humanoidRootPart.Prop("CFrame");
|
|
58419
|
+
const adjustment = faceRight ? FACE_RIGHT_CFRAME : FACE_LEFT_CFRAME;
|
|
58420
|
+
mannequinTargetCFrame = adjustment.multiply(mannequinTargetCFrame);
|
|
58421
|
+
const [minPartsExtent, maxPartsExtent] = calculateBodyPartsExtents(mannequinTargetCFrame, mannequinFocusParts);
|
|
58422
|
+
const cameraOptions = {
|
|
58423
|
+
optFieldOfView: HEAD_BODYPART_FIELD_OF_VIEW_DEG,
|
|
58424
|
+
targetCFrame: mannequinTargetCFrame,
|
|
58425
|
+
minExtent: minPartsExtent,
|
|
58426
|
+
maxExtent: maxPartsExtent,
|
|
58427
|
+
extentScale: CONSTANTS_CameraUtility.DefaultBodyPartMarginScale
|
|
58428
|
+
};
|
|
58429
|
+
setupCamera(camera, cameraOptions);
|
|
58430
|
+
}
|
|
58431
|
+
}
|
|
58432
|
+
function setupHeadCamera(headModel, camera) {
|
|
58433
|
+
const head = headModel.FindFirstChild("Head");
|
|
58434
|
+
if (head) {
|
|
58435
|
+
let headTargetCFrame = calculateTargetCFrame(head.Prop("CFrame"));
|
|
58436
|
+
const adjustment = CFrame.fromEulerAngles(HEAD_X_ROTATION_RAD, HEAD_Y_ROTATION_RAD, 0, "YXZ");
|
|
58437
|
+
headTargetCFrame = adjustment.multiply(headTargetCFrame);
|
|
58438
|
+
const [minHeadExtent, maxHeadExtent] = calculateHeadExtents(headModel, headTargetCFrame);
|
|
58439
|
+
const cameraOptions = {
|
|
58440
|
+
optFieldOfView: HEAD_BODYPART_FIELD_OF_VIEW_DEG,
|
|
58441
|
+
targetCFrame: headTargetCFrame,
|
|
58442
|
+
minExtent: minHeadExtent,
|
|
58443
|
+
maxExtent: maxHeadExtent,
|
|
58444
|
+
extentScale: HEAD_MARGIN_SCALE
|
|
58445
|
+
};
|
|
58446
|
+
setupCamera(camera, cameraOptions);
|
|
58447
|
+
}
|
|
58448
|
+
}
|
|
58449
|
+
function isLeftShoe(acc) {
|
|
58450
|
+
const handle = acc.FindFirstChildOfClass("MeshPart");
|
|
58451
|
+
if (!handle) {
|
|
58452
|
+
return false;
|
|
58453
|
+
}
|
|
58454
|
+
return void 0 !== handle.FindFirstChild("LeftFootAttachment");
|
|
58455
|
+
}
|
|
58456
|
+
function isRightShoe(acc) {
|
|
58457
|
+
const handle = acc.FindFirstChildOfClass("MeshPart");
|
|
58458
|
+
if (!handle) {
|
|
58459
|
+
return false;
|
|
58460
|
+
}
|
|
58461
|
+
return void 0 !== handle.FindFirstChild("RightFootAttachment");
|
|
58462
|
+
}
|
|
58463
|
+
function getAccessoryAngle(acc) {
|
|
58464
|
+
if (isLeftShoe(acc)) {
|
|
58465
|
+
return LEFT_SHOE_CFRAME;
|
|
58466
|
+
} else if (isRightShoe(acc)) {
|
|
58467
|
+
return RIGHT_SHOE_CFRAME;
|
|
58468
|
+
}
|
|
58469
|
+
return ACCESSORY_DEFAULT_CFRAME;
|
|
58470
|
+
}
|
|
58471
|
+
function setupAccessoryCamera(accessoryModel, camera) {
|
|
58472
|
+
const modelChildren = accessoryModel.GetChildren();
|
|
58473
|
+
const accoutrement = modelChildren[0];
|
|
58474
|
+
const handle = accoutrement.FindFirstChild("Handle");
|
|
58475
|
+
if (handle) {
|
|
58476
|
+
handle.setProperty("CFrame", new CFrame());
|
|
58477
|
+
const targetCFrame = handle.Prop("CFrame").multiply(getAccessoryAngle(accoutrement));
|
|
58478
|
+
const [minPartsExtent, maxPartsExtent] = calculateModelExtents(accessoryModel, targetCFrame);
|
|
58479
|
+
const cameraOptions = {
|
|
58480
|
+
optFieldOfView: ACCESSORY_FIELD_OF_VIEW_DEG,
|
|
58481
|
+
targetCFrame,
|
|
58482
|
+
minExtent: minPartsExtent,
|
|
58483
|
+
maxExtent: maxPartsExtent,
|
|
58484
|
+
extentScale: ACCESSORY_EXTENT_SCALE
|
|
58485
|
+
};
|
|
58486
|
+
setupCamera(camera, cameraOptions);
|
|
58487
|
+
}
|
|
58488
|
+
}
|
|
58489
|
+
const FIntCameraPresetHeadshotExtentScaleHundredths = 110;
|
|
58490
|
+
const CONSTANTS_CameraPresetsUtility = {
|
|
58491
|
+
GOLDEN_RATIO: 600 / 1e3,
|
|
58492
|
+
//game:DefineFastInt("AvatarGoldenRatio", 618) / 1000 -- = 0.618
|
|
58493
|
+
UPVECTOR_ORENTATION_TRESHOLD: -60 / 100,
|
|
58494
|
+
//game:DefineFastInt("UpVectorOrentationThreshold1", -60) / 100 // = -0.6
|
|
58495
|
+
AVATAR_ROTATION_DEGREE: 15
|
|
58496
|
+
//game:DefineFastInt("LookAvatarRotationDegree1", 23)
|
|
58497
|
+
};
|
|
58498
|
+
function getTorsoOrUpperTorso(character) {
|
|
58499
|
+
return character.FindFirstChild("Torso") || character.FindFirstChild("UpperTorso");
|
|
58500
|
+
}
|
|
58501
|
+
function getMannequinBodyParts(character, humanoid) {
|
|
58502
|
+
const bodyParts = [];
|
|
58503
|
+
if (humanoid.Prop("RigType") === HumanoidRigType.R6) {
|
|
58504
|
+
for (const partName of R6BodyPartNames) {
|
|
58505
|
+
const bodyPart = character.FindFirstChild(partName);
|
|
58506
|
+
if (bodyPart) bodyParts.push(bodyPart);
|
|
58507
|
+
}
|
|
58508
|
+
} else if (humanoid.Prop("RigType") === HumanoidRigType.R15) {
|
|
58509
|
+
for (const partName of R15BodyPartNames) {
|
|
58510
|
+
const bodyPart = character.FindFirstChild(partName);
|
|
58511
|
+
if (bodyPart) bodyParts.push(bodyPart);
|
|
58512
|
+
}
|
|
58513
|
+
}
|
|
58514
|
+
return bodyParts;
|
|
58515
|
+
}
|
|
58516
|
+
function getCharacterTorsoCFrame(character) {
|
|
58517
|
+
const torso = getTorsoOrUpperTorso(character);
|
|
58518
|
+
return torso ? torso.Prop("CFrame") : new CFrame();
|
|
58519
|
+
}
|
|
58520
|
+
function getFullBodyCameraCFrame(character, applyEmote, isFallbackEmoteApplied = true, fieldOfViewDeg, characterInitialCFrame, autoZoom = true) {
|
|
58521
|
+
const fovAngle = fieldOfViewDeg || 56;
|
|
58522
|
+
const characterInitialPivotTo = characterInitialCFrame || getCharacterTorsoCFrame(character);
|
|
58523
|
+
const characterInitialLookVector = characterInitialPivotTo.lookVector();
|
|
58524
|
+
if (applyEmote) {
|
|
58525
|
+
applyEmote();
|
|
58526
|
+
}
|
|
58527
|
+
const humanoid = character.FindFirstChildOfClass("Humanoid");
|
|
58528
|
+
if (!humanoid) {
|
|
58529
|
+
return;
|
|
58530
|
+
}
|
|
58531
|
+
const bodyParts = getMannequinBodyParts(character, humanoid);
|
|
58532
|
+
const characterPivotToAuxiliaryCFrame = getCharacterTorsoCFrame(character);
|
|
58533
|
+
const characterAuxiliaryUpVector = characterPivotToAuxiliaryCFrame.upVector();
|
|
58534
|
+
const head = character.FindFirstChild("Head");
|
|
58535
|
+
if (!head) return;
|
|
58536
|
+
const [characterHeadRotationX, characterHeadRotationY, characterHeadRotationZ] = head.Prop("CFrame").toEulerAngles("XYZ");
|
|
58537
|
+
if (isFallbackEmoteApplied) {
|
|
58538
|
+
const rootAssembly = head.w.GetAssembly();
|
|
58539
|
+
const rootPart = rootAssembly.rootNode.part;
|
|
58540
|
+
rootPart.setProperty("CFrame", rootPart.Prop("CFrame").multiply(CFrame.Angles(0, rad(CONSTANTS_CameraPresetsUtility.AVATAR_ROTATION_DEGREE * -1), 0)));
|
|
58541
|
+
rootAssembly.traverseTree();
|
|
58542
|
+
}
|
|
58543
|
+
const [minPartsExtent, maxPartsExtent] = calculateBodyPartsExtents(characterPivotToAuxiliaryCFrame, bodyParts);
|
|
58544
|
+
const tanAlpha = Math.tan(rad(fovAngle / 2));
|
|
58545
|
+
const goldPositionOfExtent = minPartsExtent.lerp(maxPartsExtent, CONSTANTS_CameraPresetsUtility.GOLDEN_RATIO);
|
|
58546
|
+
const centerPositionOfExtent = minPartsExtent.lerp(maxPartsExtent, 0.5);
|
|
58547
|
+
const goldPosition = new Vector3(centerPositionOfExtent.X, goldPositionOfExtent.Y, centerPositionOfExtent.Z);
|
|
58548
|
+
const goldPositionWorldSpace = characterPivotToAuxiliaryCFrame.multiplyVector(goldPosition);
|
|
58549
|
+
let characterGoldenRatioPivotTo = characterPivotToAuxiliaryCFrame.rotationOnly();
|
|
58550
|
+
characterGoldenRatioPivotTo.Position = add(characterGoldenRatioPivotTo.Position, goldPositionWorldSpace.toVec3());
|
|
58551
|
+
if (!isFallbackEmoteApplied) {
|
|
58552
|
+
const headPivotTo = CFrame.fromEulerAngles(characterHeadRotationX, characterHeadRotationY, characterHeadRotationZ, "XYZ");
|
|
58553
|
+
characterGoldenRatioPivotTo = headPivotTo.rotationOnly();
|
|
58554
|
+
characterGoldenRatioPivotTo.Position = add(characterGoldenRatioPivotTo.Position, goldPositionWorldSpace.toVec3());
|
|
58555
|
+
}
|
|
58556
|
+
const distanceToLowerExtents = Math.max(goldPosition.X - minPartsExtent.X, goldPosition.Y - minPartsExtent.Y);
|
|
58557
|
+
const distanceToUpperExtents = Math.max(maxPartsExtent.X - goldPosition.X, maxPartsExtent.Y - goldPosition.Y);
|
|
58558
|
+
const dc1 = distanceToLowerExtents * CONSTANTS_CameraUtility.DefaultBodyMarginScale / tanAlpha;
|
|
58559
|
+
const dc1Option = distanceToUpperExtents * CONSTANTS_CameraUtility.DefaultBodyMarginScale / tanAlpha;
|
|
58560
|
+
let distanceToCameraOption = dc1;
|
|
58561
|
+
const isUpsideDown = characterAuxiliaryUpVector[1] < CONSTANTS_CameraPresetsUtility.UPVECTOR_ORENTATION_TRESHOLD;
|
|
58562
|
+
const isUpsideRight = characterAuxiliaryUpVector[0] < CONSTANTS_CameraPresetsUtility.UPVECTOR_ORENTATION_TRESHOLD;
|
|
58563
|
+
if (isUpsideDown || isUpsideRight) {
|
|
58564
|
+
distanceToCameraOption = Math.max(dc1, dc1Option);
|
|
58565
|
+
}
|
|
58566
|
+
let distanceToCamera = distanceToCameraOption * CONSTANTS_CameraUtility.DistanceScaleForFullBody;
|
|
58567
|
+
if (autoZoom) {
|
|
58568
|
+
const [minExtentWithAccessories, maxExtentWithAccessories] = calculateModelExtents(character, characterPivotToAuxiliaryCFrame);
|
|
58569
|
+
const dc2 = Math.max(maxExtentWithAccessories.X - minExtentWithAccessories.X, maxExtentWithAccessories.Y - minExtentWithAccessories.Y) * CONSTANTS_CameraUtility.DefaultBodyMarginScale / 2 / tanAlpha;
|
|
58570
|
+
distanceToCamera = Math.max(dc1, dc1Option) * Math.max(Math.min(dc2 / Math.max(dc1, dc1Option), 1.5), 1.1);
|
|
58571
|
+
}
|
|
58572
|
+
const relativePositionToCamera = new Vector3().fromVec3(multiply(characterInitialLookVector, [distanceToCamera, distanceToCamera, distanceToCamera]));
|
|
58573
|
+
return getCameraCFrame(characterGoldenRatioPivotTo, relativePositionToCamera);
|
|
58574
|
+
}
|
|
58575
|
+
function getHeadshotCameraCFrame(character, applyEmote, isFallbackEmoteApplied, fieldOfViewDeg, cameraOptionsOverride) {
|
|
58576
|
+
const fovAngle = fieldOfViewDeg || 30;
|
|
58577
|
+
if (applyEmote) {
|
|
58578
|
+
applyEmote();
|
|
58579
|
+
}
|
|
58580
|
+
const characterHead = character.FindFirstChild("Head");
|
|
58581
|
+
if (!characterHead) {
|
|
58582
|
+
return;
|
|
58583
|
+
}
|
|
58584
|
+
let targetCFrame = characterHead.Prop("CFrame");
|
|
58585
|
+
const faceFrontAttachment = characterHead.FindFirstChild("FaceFrontAttachment");
|
|
58586
|
+
if (faceFrontAttachment) {
|
|
58587
|
+
const faceFrontAttachmentW = faceFrontAttachment.w;
|
|
58588
|
+
if (faceFrontAttachmentW) {
|
|
58589
|
+
targetCFrame = faceFrontAttachmentW.getWorldCFrame();
|
|
58590
|
+
}
|
|
58591
|
+
}
|
|
58592
|
+
const headTargetCFrame = calculateTargetCFrame(targetCFrame);
|
|
58593
|
+
const [minHeadExtent, maxHeadExtent] = calculateHeadExtents(character, headTargetCFrame);
|
|
58594
|
+
const camera = createThumbnailCamera();
|
|
58595
|
+
const cameraOptions = {
|
|
58596
|
+
extentScale: FIntCameraPresetHeadshotExtentScaleHundredths / 100,
|
|
58597
|
+
maxExtent: maxHeadExtent,
|
|
58598
|
+
minExtent: minHeadExtent,
|
|
58599
|
+
optCameraXRot: CONSTANTS_CameraUtility.XRotForCloseup,
|
|
58600
|
+
optFieldOfView: fovAngle,
|
|
58601
|
+
targetCFrame: headTargetCFrame
|
|
58602
|
+
};
|
|
58603
|
+
Object.assign(cameraOptions, cameraOptionsOverride);
|
|
58604
|
+
setupCamera(camera, cameraOptions);
|
|
58605
|
+
return camera;
|
|
58606
|
+
}
|
|
58607
|
+
function getAvatarCameraCFrame(character, applyEmote, isFallbackEmoteApplied, fieldOfViewDeg, cameraOptionsOverride) {
|
|
58608
|
+
const fovAngle = fieldOfViewDeg || 30;
|
|
58609
|
+
if (applyEmote) {
|
|
58610
|
+
applyEmote();
|
|
58611
|
+
}
|
|
58612
|
+
const characterHead = character.FindFirstChild("Head");
|
|
58613
|
+
if (!characterHead) {
|
|
58614
|
+
return;
|
|
58615
|
+
}
|
|
58616
|
+
let targetCFrame = characterHead.Prop("CFrame");
|
|
58617
|
+
const faceFrontAttachment = characterHead.FindFirstChild("FaceFrontAttachment");
|
|
58618
|
+
if (faceFrontAttachment) {
|
|
58619
|
+
const faceFrontAttachmentW = faceFrontAttachment.w;
|
|
58620
|
+
if (faceFrontAttachmentW) {
|
|
58621
|
+
targetCFrame = faceFrontAttachmentW.getWorldCFrame();
|
|
58622
|
+
}
|
|
58623
|
+
}
|
|
58624
|
+
const torsoCFrame = getCharacterTorsoCFrame(character);
|
|
58625
|
+
targetCFrame.Position = torsoCFrame.Position;
|
|
58626
|
+
const headTargetCFrame = calculateTargetCFrame(targetCFrame);
|
|
58627
|
+
const [minHeadExtent, maxHeadExtent] = calculateModelExtents(character, headTargetCFrame);
|
|
58628
|
+
const camera = createThumbnailCamera();
|
|
58629
|
+
const cameraOptions = {
|
|
58630
|
+
extentScale: FIntCameraPresetHeadshotExtentScaleHundredths / 100,
|
|
58631
|
+
maxExtent: maxHeadExtent,
|
|
58632
|
+
minExtent: minHeadExtent,
|
|
58633
|
+
optCameraXRot: CONSTANTS_CameraUtility.XRotForFullBody,
|
|
58634
|
+
optFieldOfView: fovAngle,
|
|
58635
|
+
targetCFrame: headTargetCFrame
|
|
58636
|
+
};
|
|
58637
|
+
Object.assign(cameraOptions, cameraOptionsOverride);
|
|
58638
|
+
setupCamera(camera, cameraOptions);
|
|
58639
|
+
return camera;
|
|
58640
|
+
}
|
|
58641
|
+
function getCorners(cframe, size) {
|
|
58642
|
+
const halfX = size.X / 2;
|
|
58643
|
+
const halfY = size.Y / 2;
|
|
58644
|
+
const halfZ = size.Z / 2;
|
|
58645
|
+
return [
|
|
58646
|
+
cframe.multiply(new CFrame(halfX, halfY, halfZ)),
|
|
58647
|
+
cframe.multiply(new CFrame(halfX, halfY, -halfZ)),
|
|
58648
|
+
cframe.multiply(new CFrame(-halfX, halfY, halfZ)),
|
|
58649
|
+
cframe.multiply(new CFrame(-halfX, halfY, -halfZ)),
|
|
58650
|
+
cframe.multiply(new CFrame(halfX, -halfY, halfZ)),
|
|
58651
|
+
cframe.multiply(new CFrame(halfX, -halfY, -halfZ)),
|
|
58652
|
+
cframe.multiply(new CFrame(-halfX, -halfY, halfZ)),
|
|
58653
|
+
cframe.multiply(new CFrame(-halfX, -halfY, -halfZ))
|
|
58654
|
+
];
|
|
58655
|
+
}
|
|
58656
|
+
function getLower(a, b) {
|
|
58657
|
+
return new Vector3(
|
|
58658
|
+
a.X < b.X ? a.X : b.X,
|
|
58659
|
+
a.Y < b.Y ? a.Y : b.Y,
|
|
58660
|
+
a.Z < b.Z ? a.Z : b.Z
|
|
58661
|
+
);
|
|
58662
|
+
}
|
|
58663
|
+
function getHigher(a, b) {
|
|
58664
|
+
return new Vector3(
|
|
58665
|
+
a.X > b.X ? a.X : b.X,
|
|
58666
|
+
a.Y > b.Y ? a.Y : b.Y,
|
|
58667
|
+
a.Z > b.Z ? a.Z : b.Z
|
|
58668
|
+
);
|
|
58669
|
+
}
|
|
58670
|
+
function getExtentsForParts(parts, includeTransform) {
|
|
58671
|
+
let lowerExtents = new Vector3(0, 0, 0);
|
|
58672
|
+
let higherExtents = new Vector3(0, 0, 0);
|
|
58673
|
+
for (const child of parts) {
|
|
58674
|
+
if (child.createWrapper()?.IsA("BasePart")) {
|
|
58675
|
+
const cframe = traverseRigCFrame(child, includeTransform, true);
|
|
58676
|
+
const size = child.Prop("Size");
|
|
58677
|
+
const corners = getCorners(cframe, size);
|
|
58678
|
+
for (const corner of corners) {
|
|
58679
|
+
lowerExtents = getLower(lowerExtents, new Vector3().fromVec3(corner.Position));
|
|
58680
|
+
higherExtents = getHigher(higherExtents, new Vector3().fromVec3(corner.Position));
|
|
58681
|
+
}
|
|
58682
|
+
}
|
|
58683
|
+
}
|
|
58684
|
+
return [lowerExtents, higherExtents];
|
|
58685
|
+
}
|
|
58686
|
+
function getExtents(cframe, parts) {
|
|
58687
|
+
const inverseCF = cframe.inverse();
|
|
58688
|
+
let lowerExtents = new Vector3(0, 0, 0);
|
|
58689
|
+
let higherExtents = new Vector3(0, 0, 0);
|
|
58690
|
+
for (const child of parts) {
|
|
58691
|
+
if (child.createWrapper()?.IsA("BasePart")) {
|
|
58692
|
+
const partCF = child.Prop("CFrame");
|
|
58693
|
+
const partSize = child.Prop("Size");
|
|
58694
|
+
const corners = getCorners(inverseCF.multiply(partCF), partSize);
|
|
58695
|
+
for (const corner of corners) {
|
|
58696
|
+
lowerExtents = getLower(lowerExtents, new Vector3().fromVec3(corner.Position));
|
|
58697
|
+
higherExtents = getHigher(higherExtents, new Vector3().fromVec3(corner.Position));
|
|
58698
|
+
}
|
|
58699
|
+
}
|
|
58700
|
+
}
|
|
58701
|
+
return [lowerExtents, higherExtents];
|
|
58702
|
+
}
|
|
58703
|
+
function getExtentsWorld(rig) {
|
|
58704
|
+
const rigParts = [];
|
|
58705
|
+
for (const child of rig.GetDescendants()) {
|
|
58706
|
+
if (child.createWrapper()?.IsA("BasePart")) {
|
|
58707
|
+
rigParts.push(child);
|
|
58708
|
+
}
|
|
58709
|
+
}
|
|
58710
|
+
const extents = getExtents(new CFrame(), rigParts);
|
|
58711
|
+
return extents;
|
|
58712
|
+
}
|
|
58713
|
+
function getExtentsCenter(extents) {
|
|
58714
|
+
return extents[1].minus(extents[0]).divide(new Vector3(2, 2, 2)).add(extents[0]);
|
|
58715
|
+
}
|
|
58716
|
+
function zoomExtents(cameraCFrame, modelCFrame, modelSize, targetFOV, distanceScale, sizeType = "calculate") {
|
|
58717
|
+
let largestSize = Math.max(modelSize.X, modelSize.Y, modelSize.Z);
|
|
58718
|
+
if (sizeType === "calculate") {
|
|
58719
|
+
largestSize = modelSize.magnitude() / 2 / Math.sin(rad(targetFOV / 2));
|
|
58720
|
+
}
|
|
58721
|
+
const fovMultiplier = sizeType === "largestAxis" ? 70 / targetFOV : 1;
|
|
58722
|
+
const lookDir = multiply(normalize(minus(cameraCFrame.Position, modelCFrame.Position)), [distanceScale, distanceScale, distanceScale]);
|
|
58723
|
+
cameraCFrame.Position = add(modelCFrame.Position, multiply(multiply(lookDir, [largestSize, largestSize, largestSize]), [fovMultiplier, fovMultiplier, fovMultiplier]));
|
|
58724
|
+
}
|
|
58725
|
+
function getCameraOffset(fov2, extentsSize) {
|
|
58726
|
+
const halfSize = extentsSize.magnitude() / 2;
|
|
58727
|
+
const fovDivisor = Math.tan(rad(fov2 / 2));
|
|
58728
|
+
return halfSize / fovDivisor;
|
|
58729
|
+
}
|
|
58730
|
+
function zoomToExtents(cameraCFrame, modelCFrame, modelSize, fov2 = 70) {
|
|
58731
|
+
const cameraOffset = getCameraOffset(fov2, modelSize);
|
|
58732
|
+
const cameraRotation = new CFrame();
|
|
58733
|
+
cameraRotation.Orientation = cameraCFrame.Orientation;
|
|
58734
|
+
const instancePosition = modelCFrame.Position;
|
|
58735
|
+
cameraCFrame.Position = add(instancePosition, multiply(minus([0, 0, 0], cameraRotation.lookVector()), [cameraOffset, cameraOffset, cameraOffset]));
|
|
58736
|
+
}
|
|
58737
|
+
function getHeadExtents(rig) {
|
|
58738
|
+
const head = rig.FindFirstChild("Head");
|
|
58739
|
+
if (!head) return;
|
|
58740
|
+
const headParts = [];
|
|
58741
|
+
for (const child of rig.GetDescendants()) {
|
|
58742
|
+
if (child === head) {
|
|
58743
|
+
headParts.push(head);
|
|
58744
|
+
} else {
|
|
58745
|
+
const weld = child.FindFirstChildOfClass("Weld");
|
|
58746
|
+
if (weld && child.parent && child.parent.className === "Accessory") {
|
|
58747
|
+
if (weld.Prop("Part0") === head || weld.Prop("Part1") === head) {
|
|
58748
|
+
headParts.push(child);
|
|
58749
|
+
}
|
|
58750
|
+
}
|
|
58751
|
+
}
|
|
58752
|
+
}
|
|
58753
|
+
const extents = getExtents(head.Prop("CFrame"), headParts);
|
|
58754
|
+
return extents;
|
|
58755
|
+
}
|
|
58756
|
+
function getCameraCFrameForHeadshotCustomized(rig, fov2, yRot, distance2) {
|
|
58757
|
+
const camera = getHeadshotCameraCFrame(rig, void 0, void 0, fov2, {
|
|
58758
|
+
optCameraYRot: yRot,
|
|
58759
|
+
optCameraDistanceScale: distance2,
|
|
58760
|
+
extentScale: 1.1
|
|
58761
|
+
});
|
|
58762
|
+
if (camera) {
|
|
58763
|
+
const cameraCF = camera.Prop("CFrame");
|
|
58764
|
+
camera.Destroy();
|
|
58765
|
+
return cameraCF;
|
|
58766
|
+
}
|
|
58767
|
+
}
|
|
58768
|
+
function getCameraCFrameForAvatarCustomized(rig, fov2, yRot) {
|
|
58769
|
+
const camera = getAvatarCameraCFrame(rig, void 0, void 0, fov2, {
|
|
58770
|
+
optCameraYRot: yRot,
|
|
58771
|
+
optCameraDistanceScale: 1,
|
|
58772
|
+
extentScale: 1.1
|
|
58773
|
+
});
|
|
58774
|
+
if (camera) {
|
|
58775
|
+
const cameraCF = camera.Prop("CFrame");
|
|
58776
|
+
camera.Destroy();
|
|
58777
|
+
return cameraCF;
|
|
58778
|
+
}
|
|
58779
|
+
}
|
|
58780
|
+
function getCameraCFrameForAvatarNonCustomized(rig) {
|
|
58781
|
+
const thumbnailCamera = rig.FindFirstChildOfClass("Camera");
|
|
58782
|
+
if (thumbnailCamera) return thumbnailCamera.PropOrDefault("CFrame", new CFrame());
|
|
58783
|
+
let rootPart = rig.PropOrDefault("PrimaryPart", void 0);
|
|
58784
|
+
if (!rootPart) rootPart = rig.FindFirstChildOfClass("Part");
|
|
58785
|
+
if (!rootPart) rootPart = rig.FindFirstChildOfClass("MeshPart");
|
|
58786
|
+
if (!rootPart) return;
|
|
58787
|
+
const rootPartCF = rootPart.PropOrDefault("CFrame", new CFrame()).clone();
|
|
58788
|
+
const worldExtents = getExtentsWorld(rig);
|
|
58789
|
+
if (!worldExtents) return;
|
|
58790
|
+
const extentsSize = worldExtents[1].minus(worldExtents[0]);
|
|
58791
|
+
rootPartCF.Position = getExtentsCenter(worldExtents).toVec3();
|
|
58792
|
+
let lookVector = rootPartCF.lookVector();
|
|
58793
|
+
if (Math.abs(lookVector[1]) > 0.95) {
|
|
58794
|
+
lookVector = [0, 0, -1];
|
|
58795
|
+
} else {
|
|
58796
|
+
lookVector[1] = 0;
|
|
58797
|
+
lookVector = normalize(lookVector);
|
|
58798
|
+
}
|
|
58799
|
+
let lookCF = CFrame.lookAt([0, 0, 0], lookVector);
|
|
58800
|
+
lookCF = lookCF.multiply(CFrame.fromEulerAngles(25 * Math.PI / 180, 27.5 * Math.PI / 180, 0, "ZXY"));
|
|
58801
|
+
lookVector = lookCF.lookVector();
|
|
58802
|
+
lookCF.Position = add(rootPartCF.Position, multiply([10, 10, 10], lookVector));
|
|
58803
|
+
lookCF = CFrame.lookAt(lookCF.Position, rootPartCF.Position);
|
|
58804
|
+
const cameraCF = lookCF.clone();
|
|
58805
|
+
zoomExtents(cameraCF, rootPartCF, extentsSize, 70, 1);
|
|
58806
|
+
return cameraCF;
|
|
58807
|
+
}
|
|
58117
58808
|
class BackgroundRenderer {
|
|
58118
58809
|
auth;
|
|
58119
58810
|
avatarCyclorama;
|
|
@@ -58318,7 +59009,7 @@ class OutfitRenderer {
|
|
|
58318
59009
|
doCameraUpdate = false;
|
|
58319
59010
|
/**Does camera update every frame */
|
|
58320
59011
|
doAddInstance = true;
|
|
58321
|
-
/**If outfitRenderer should call RBXRenderer.addInstance() */
|
|
59012
|
+
/**If outfitRenderer should call RBXRenderer.addInstance(), setting this to false will make OutfitRenderer return success early */
|
|
58322
59013
|
forceAnimationLoop = true;
|
|
58323
59014
|
/**If future loaded animations should be set to loop */
|
|
58324
59015
|
backgroundRenderer;
|
|
@@ -58360,6 +59051,16 @@ class OutfitRenderer {
|
|
|
58360
59051
|
* @returns void
|
|
58361
59052
|
*/
|
|
58362
59053
|
onRenderError = new Event();
|
|
59054
|
+
get humanoid() {
|
|
59055
|
+
return this.currentRig?.FindFirstChildOfClass("Humanoid");
|
|
59056
|
+
}
|
|
59057
|
+
get animator() {
|
|
59058
|
+
return this.humanoid?.FindFirstChildOfClass("Animator");
|
|
59059
|
+
}
|
|
59060
|
+
get animatorW() {
|
|
59061
|
+
const animator = this.animator;
|
|
59062
|
+
if (animator) return new AnimatorWrapper(animator);
|
|
59063
|
+
}
|
|
58363
59064
|
/**
|
|
58364
59065
|
* Creates a new OutfitRenderer which makes it easy to render outfits
|
|
58365
59066
|
* @param auth The authentication object, you should have one you use for everything
|
|
@@ -58551,9 +59252,30 @@ class OutfitRenderer {
|
|
|
58551
59252
|
this.animationInterval = void 0;
|
|
58552
59253
|
}
|
|
58553
59254
|
}
|
|
59255
|
+
/**
|
|
59256
|
+
* Checks if the provided animation set is loaded
|
|
59257
|
+
* @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
|
|
59258
|
+
* @returns If the animation is loaded
|
|
59259
|
+
*/
|
|
59260
|
+
hasAnimationSetAnimation(name) {
|
|
59261
|
+
if (this.currentRig) {
|
|
59262
|
+
const humanoid = this.currentRig.FindFirstChildOfClass("Humanoid");
|
|
59263
|
+
if (humanoid) {
|
|
59264
|
+
const animator = humanoid.FindFirstChildOfClass("Animator");
|
|
59265
|
+
if (animator) {
|
|
59266
|
+
const animatorW = new AnimatorWrapper(animator);
|
|
59267
|
+
const entries = animatorW.data.animationSet[name];
|
|
59268
|
+
if (entries) {
|
|
59269
|
+
return entries.length > 0;
|
|
59270
|
+
}
|
|
59271
|
+
}
|
|
59272
|
+
}
|
|
59273
|
+
}
|
|
59274
|
+
return false;
|
|
59275
|
+
}
|
|
58554
59276
|
/**
|
|
58555
59277
|
* Sets the current animation being played
|
|
58556
|
-
* @param name The name of the animation, for example "idle", "run", "emote.1234" or "
|
|
59278
|
+
* @param name The name of the animation, for example "idle", "run", "emote.1234" or "id.1234"
|
|
58557
59279
|
* @returns If the animation started playing, it may start playing later if it has been queued despite returning false
|
|
58558
59280
|
*/
|
|
58559
59281
|
setMainAnimation(name) {
|
|
@@ -58622,16 +59344,28 @@ class OutfitRenderer {
|
|
|
58622
59344
|
}
|
|
58623
59345
|
async _prepareForThumbnail() {
|
|
58624
59346
|
this.doAddInstance = false;
|
|
59347
|
+
this.backgroundRenderer.affectSceneAppearance = false;
|
|
59348
|
+
this.backgroundRenderer.cameraAffectsTransparency = false;
|
|
58625
59349
|
if (this.outfit.playerAvatarType === AvatarType.R6) this.deltaTimeMultiplier = 0;
|
|
58626
59350
|
await new Promise((resolve) => {
|
|
58627
59351
|
this.onSuccess.Connect(() => {
|
|
59352
|
+
const animatorW = this.animatorW;
|
|
59353
|
+
if (animatorW) {
|
|
59354
|
+
animatorW.data.forceTransitionTime = 0;
|
|
59355
|
+
}
|
|
58628
59356
|
if (!this.outfit.containsAssetType("Gear")) {
|
|
58629
59357
|
if (this.outfit.playerAvatarType === AvatarType.R15) {
|
|
58630
|
-
this.
|
|
58631
|
-
|
|
58632
|
-
|
|
59358
|
+
if (this.hasAnimationSetAnimation("pose")) {
|
|
59359
|
+
this.setMainAnimation("pose").then(() => {
|
|
59360
|
+
resolve(void 0);
|
|
59361
|
+
});
|
|
59362
|
+
} else {
|
|
59363
|
+
this.setMainAnimation("idle:0").then(() => {
|
|
59364
|
+
resolve(void 0);
|
|
59365
|
+
});
|
|
59366
|
+
}
|
|
58633
59367
|
} else {
|
|
58634
|
-
this.setMainAnimation("idle").then(() => {
|
|
59368
|
+
this.setMainAnimation("idle:0").then(() => {
|
|
58635
59369
|
resolve(void 0);
|
|
58636
59370
|
});
|
|
58637
59371
|
}
|
|
@@ -58642,8 +59376,10 @@ class OutfitRenderer {
|
|
|
58642
59376
|
}
|
|
58643
59377
|
});
|
|
58644
59378
|
});
|
|
58645
|
-
this.animateOnce(
|
|
59379
|
+
this.animateOnce(0);
|
|
59380
|
+
if (this.outfit.playerAvatarType !== AvatarType.R6 && this.animatorW?.data.currentAnimation === "idle") this.animateOnce((this.animatorW?.data.currentAnimationTrack?.length || 0) / 2);
|
|
58646
59381
|
if (this.currentRig) RBXRenderer.addInstance(this.currentRig, this.auth, this.renderScene);
|
|
59382
|
+
this.hasFiredFullyRendered = false;
|
|
58647
59383
|
await new Promise((resolve) => {
|
|
58648
59384
|
const connection = this.onRenderSuccess.Connect(() => {
|
|
58649
59385
|
resolve(void 0);
|
|
@@ -58727,102 +59463,6 @@ async function modelThumbnailClick(renderScene, format, options) {
|
|
|
58727
59463
|
binary: format === "glb"
|
|
58728
59464
|
});
|
|
58729
59465
|
}
|
|
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
59466
|
function getThumbnailCameraCFrame(model, fov2, forceAngle) {
|
|
58827
59467
|
const thumbnailCamera = model.FindFirstChildOfClass("Camera");
|
|
58828
59468
|
if (thumbnailCamera) return thumbnailCamera.PropOrDefault("CFrame", new CFrame());
|
|
@@ -58869,7 +59509,7 @@ function setupThumbnailScene(renderScene) {
|
|
|
58869
59509
|
if (renderScene.shadowPlane) renderScene.scene.remove(renderScene.shadowPlane);
|
|
58870
59510
|
renderScene.scene.background = null;
|
|
58871
59511
|
}
|
|
58872
|
-
async function generateOutfitThumbnail(auth, outfit, size = [150, 150], type = "png", quality = 1, gltfAutoDownload = false, includeAnimations = false, renderSceneParam) {
|
|
59512
|
+
async function generateOutfitThumbnail(auth, outfit, size = [150, 150], type = "png", quality = 1, gltfAutoDownload = false, includeAnimations = false, renderSceneParam, thumbnailCameraType = "default") {
|
|
58873
59513
|
const renderScene = renderSceneParam || RBXRenderer.addScene();
|
|
58874
59514
|
if (renderScene !== renderSceneParam) {
|
|
58875
59515
|
setupThumbnailScene(renderScene);
|
|
@@ -58882,9 +59522,25 @@ async function generateOutfitThumbnail(auth, outfit, size = [150, 150], type = "
|
|
|
58882
59522
|
return void 0;
|
|
58883
59523
|
}
|
|
58884
59524
|
if (outfitRenderer.currentRig) {
|
|
58885
|
-
|
|
59525
|
+
let cameraCFrame = new CFrame();
|
|
59526
|
+
switch (thumbnailCameraType) {
|
|
59527
|
+
case "default":
|
|
59528
|
+
cameraCFrame = getThumbnailCameraCFrame(outfitRenderer.currentRig, renderScene.camera.fov) || cameraCFrame;
|
|
59529
|
+
break;
|
|
59530
|
+
case "avatarHeadshot":
|
|
59531
|
+
cameraCFrame = getCameraCFrameForHeadshotCustomized(outfitRenderer.currentRig, 28, 0, 1) || cameraCFrame;
|
|
59532
|
+
break;
|
|
59533
|
+
case "avatarFullbody":
|
|
59534
|
+
cameraCFrame = getCameraCFrameForAvatarCustomized(outfitRenderer.currentRig, 28, 0) || cameraCFrame;
|
|
59535
|
+
break;
|
|
59536
|
+
case "fullbody":
|
|
59537
|
+
cameraCFrame = getFullBodyCameraCFrame(outfitRenderer.currentRig) || cameraCFrame;
|
|
59538
|
+
break;
|
|
59539
|
+
}
|
|
58886
59540
|
if (cameraCFrame) {
|
|
58887
59541
|
RBXRenderer.setCameraCFrame(cameraCFrame, renderScene);
|
|
59542
|
+
RBXRenderer.setCameraFov(thumbnailCameraType === "default" ? 70 : thumbnailCameraType === "fullbody" ? 56 : 28, renderScene);
|
|
59543
|
+
renderScene.camera.updateProjectionMatrix();
|
|
58888
59544
|
}
|
|
58889
59545
|
outfitRenderer.updateParticleMatrix();
|
|
58890
59546
|
const result = type === "gltf" || type === "glb" ? await modelThumbnailClick(renderScene, type, {
|
|
@@ -58917,37 +59573,7 @@ async function generateOutfitModelThumbnail(auth, outfitModel, options) {
|
|
|
58917
59573
|
includeAnimations: false
|
|
58918
59574
|
};
|
|
58919
59575
|
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);
|
|
59576
|
+
return generateOutfitThumbnail(auth, outfitModel, defaultOptions.size, defaultOptions.type, defaultOptions.quality, defaultOptions.gltfAutoDownload, defaultOptions.includeAnimations);
|
|
58951
59577
|
}
|
|
58952
59578
|
function renderToRenderTarget(width, height, renderScene) {
|
|
58953
59579
|
const renderTarget = new WebGLRenderTarget(width, height, {
|
|
@@ -59030,79 +59656,6 @@ function exposeThumbnailGenerator() {
|
|
|
59030
59656
|
globalThis.setupThumbnailScene = setupThumbnailScene;
|
|
59031
59657
|
globalThis.getThumbnailCameraCFrame = getThumbnailCameraCFrame;
|
|
59032
59658
|
}
|
|
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
59659
|
export {
|
|
59107
59660
|
API,
|
|
59108
59661
|
AbbreviationToFaceControlProperty,
|
|
@@ -59138,6 +59691,7 @@ export {
|
|
|
59138
59691
|
AttachmentWrapper,
|
|
59139
59692
|
Authentication,
|
|
59140
59693
|
AvatarType,
|
|
59694
|
+
BackgroundRenderer,
|
|
59141
59695
|
BasePartWrapper,
|
|
59142
59696
|
BodyColor3s,
|
|
59143
59697
|
BodyColors,
|
|
@@ -59152,8 +59706,12 @@ export {
|
|
|
59152
59706
|
BundleTypes,
|
|
59153
59707
|
CACHE,
|
|
59154
59708
|
CFrame,
|
|
59709
|
+
CONSTANTS_CameraPresetsUtility,
|
|
59710
|
+
CONSTANTS_CameraUtility,
|
|
59155
59711
|
COREMESH,
|
|
59156
59712
|
Cache,
|
|
59713
|
+
CameraType,
|
|
59714
|
+
CameraWrapper,
|
|
59157
59715
|
CatalogBundleTypes,
|
|
59158
59716
|
CategoryDictionary,
|
|
59159
59717
|
Color3,
|
|
@@ -59217,11 +59775,14 @@ export {
|
|
|
59217
59775
|
PartType,
|
|
59218
59776
|
PartWrapper,
|
|
59219
59777
|
ParticleEmitterShapeInOut,
|
|
59778
|
+
ParticleEmitterWrapper,
|
|
59220
59779
|
ParticleFlipbookLayout,
|
|
59221
59780
|
ParticleFlipbookMode,
|
|
59222
59781
|
ParticleOrientation,
|
|
59223
59782
|
Property,
|
|
59224
59783
|
PropertyTypeInfo,
|
|
59784
|
+
R15BodyPartNames,
|
|
59785
|
+
R6BodyPartNames,
|
|
59225
59786
|
RBFDeformerPatch,
|
|
59226
59787
|
RBX,
|
|
59227
59788
|
RBXRenderer,
|
|
@@ -59275,6 +59836,7 @@ export {
|
|
|
59275
59836
|
browserSendMessage,
|
|
59276
59837
|
buildFaceKD,
|
|
59277
59838
|
buildVertKD,
|
|
59839
|
+
calculateBaseDistanceToCamera,
|
|
59278
59840
|
calculateMagnitude3D,
|
|
59279
59841
|
calculateMotor6Doffset,
|
|
59280
59842
|
clamp,
|
|
@@ -59283,6 +59845,7 @@ export {
|
|
|
59283
59845
|
cloneSearch_Payload,
|
|
59284
59846
|
closestPointTriangle,
|
|
59285
59847
|
createContentMap,
|
|
59848
|
+
createThumbnailCamera,
|
|
59286
59849
|
createWeightsForMeshChunked,
|
|
59287
59850
|
cross,
|
|
59288
59851
|
defaultPantAssetIds,
|
|
@@ -59307,14 +59870,20 @@ export {
|
|
|
59307
59870
|
generateOutfitModelThumbnail,
|
|
59308
59871
|
generateOutfitThumbnail,
|
|
59309
59872
|
generateUUIDv4,
|
|
59873
|
+
getAvatarCameraCFrame,
|
|
59874
|
+
getCameraCFrame,
|
|
59875
|
+
getCameraCFrameForAvatarCustomized,
|
|
59310
59876
|
getCameraCFrameForAvatarNonCustomized,
|
|
59311
59877
|
getCameraCFrameForHeadshotCustomized,
|
|
59878
|
+
getCharacterTorsoCFrame,
|
|
59312
59879
|
getDistIndexArray,
|
|
59313
59880
|
getExtents,
|
|
59314
59881
|
getExtentsCenter,
|
|
59315
59882
|
getExtentsForParts,
|
|
59316
59883
|
getExtentsWorld,
|
|
59884
|
+
getFullBodyCameraCFrame,
|
|
59317
59885
|
getHeadExtents,
|
|
59886
|
+
getHeadshotCameraCFrame,
|
|
59318
59887
|
getOffsetArray,
|
|
59319
59888
|
getOriginalAttachmentOrientation,
|
|
59320
59889
|
getOriginalAttachmentPosition,
|
|
@@ -59369,6 +59938,10 @@ export {
|
|
|
59369
59938
|
rotationMatrixToEulerAngles,
|
|
59370
59939
|
saveByteArray,
|
|
59371
59940
|
scaleMesh,
|
|
59941
|
+
setupAccessoryCamera,
|
|
59942
|
+
setupBodyPartCamera,
|
|
59943
|
+
setupCamera,
|
|
59944
|
+
setupHeadCamera,
|
|
59372
59945
|
setupThumbnailScene,
|
|
59373
59946
|
snapToNumber,
|
|
59374
59947
|
specialClamp,
|