roavatar-renderer 1.4.0 → 1.4.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/README.md +2 -2
- package/dist/index.d.ts +662 -36
- package/dist/index.js +222 -24
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -29514,6 +29514,7 @@ const FLAGS = {
|
|
|
29514
29514
|
ROAVATAR_TRYON_PLACE: 135979364355750,
|
|
29515
29515
|
ASSETDELIVERY_V2: true,
|
|
29516
29516
|
ASSET_REQUEST_PRIORITY: "high",
|
|
29517
|
+
API_DOMAIN: "roblox.com",
|
|
29517
29518
|
//assets
|
|
29518
29519
|
ONLINE_ASSETS: false,
|
|
29519
29520
|
ASSETS_PATH: "../assets/rbxasset/",
|
|
@@ -29630,10 +29631,19 @@ class InstanceWrapper {
|
|
|
29630
29631
|
log(false, "Registered InstanceWrapper:", ClassNameToWrapper);
|
|
29631
29632
|
}
|
|
29632
29633
|
//virtual functions
|
|
29634
|
+
/**
|
|
29635
|
+
* @virtual
|
|
29636
|
+
*/
|
|
29633
29637
|
created() {
|
|
29634
29638
|
}
|
|
29639
|
+
/**
|
|
29640
|
+
* @virtual
|
|
29641
|
+
*/
|
|
29635
29642
|
destroy() {
|
|
29636
29643
|
}
|
|
29644
|
+
/**
|
|
29645
|
+
* @virtual
|
|
29646
|
+
*/
|
|
29637
29647
|
preRender() {
|
|
29638
29648
|
}
|
|
29639
29649
|
}
|
|
@@ -29764,6 +29774,9 @@ class Color3 {
|
|
|
29764
29774
|
clone() {
|
|
29765
29775
|
return new Color3(this.R, this.G, this.B);
|
|
29766
29776
|
}
|
|
29777
|
+
isSame(other) {
|
|
29778
|
+
return this.R === other.R && this.G === other.G && this.B === other.B;
|
|
29779
|
+
}
|
|
29767
29780
|
toColor3uint8() {
|
|
29768
29781
|
return new Color3uint8(Math.round(this.R * 255), Math.round(this.G * 255), Math.round(this.B * 255));
|
|
29769
29782
|
}
|
|
@@ -29808,6 +29821,9 @@ class NumberSequenceKeypoint {
|
|
|
29808
29821
|
clone() {
|
|
29809
29822
|
return new NumberSequenceKeypoint(this.time, this.value, this.envelope);
|
|
29810
29823
|
}
|
|
29824
|
+
isSame(other) {
|
|
29825
|
+
return this.time === other.time && this.value === other.value && this.envelope === other.envelope;
|
|
29826
|
+
}
|
|
29811
29827
|
}
|
|
29812
29828
|
class NumberSequence {
|
|
29813
29829
|
keypoints = [];
|
|
@@ -29821,6 +29837,13 @@ class NumberSequence {
|
|
|
29821
29837
|
}
|
|
29822
29838
|
return copy;
|
|
29823
29839
|
}
|
|
29840
|
+
isSame(other) {
|
|
29841
|
+
if (this.keypoints.length !== other.keypoints.length) return false;
|
|
29842
|
+
for (let i = 0; i < this.keypoints.length; i++) {
|
|
29843
|
+
if (!this.keypoints[i].isSame(other.keypoints[i])) return false;
|
|
29844
|
+
}
|
|
29845
|
+
return true;
|
|
29846
|
+
}
|
|
29824
29847
|
getLowerKey(time2) {
|
|
29825
29848
|
let resultKey = null;
|
|
29826
29849
|
for (const key of this.keypoints) {
|
|
@@ -29876,6 +29899,9 @@ class ColorSequenceKeypoint {
|
|
|
29876
29899
|
clone() {
|
|
29877
29900
|
return new ColorSequenceKeypoint(this.time, this.value.R, this.value.G, this.value.B);
|
|
29878
29901
|
}
|
|
29902
|
+
isSame(other) {
|
|
29903
|
+
return this.time === other.time && this.value.isSame(other.value);
|
|
29904
|
+
}
|
|
29879
29905
|
}
|
|
29880
29906
|
class ColorSequence {
|
|
29881
29907
|
keypoints = [];
|
|
@@ -29891,6 +29917,13 @@ class ColorSequence {
|
|
|
29891
29917
|
}
|
|
29892
29918
|
return copy;
|
|
29893
29919
|
}
|
|
29920
|
+
isSame(other) {
|
|
29921
|
+
if (this.keypoints.length !== other.keypoints.length) return false;
|
|
29922
|
+
for (let i = 0; i < this.keypoints.length; i++) {
|
|
29923
|
+
if (!this.keypoints[i].isSame(other.keypoints[i])) return false;
|
|
29924
|
+
}
|
|
29925
|
+
return true;
|
|
29926
|
+
}
|
|
29894
29927
|
getLowerKey(time2) {
|
|
29895
29928
|
let resultKey = null;
|
|
29896
29929
|
for (const key of this.keypoints) {
|
|
@@ -30078,17 +30111,23 @@ let lastInstanceId = 0;
|
|
|
30078
30111
|
const AllInstances = [];
|
|
30079
30112
|
class Instance {
|
|
30080
30113
|
_id;
|
|
30114
|
+
/**
|
|
30115
|
+
* @deprecated Use .Prop("Name") instead
|
|
30116
|
+
*/
|
|
30081
30117
|
_name;
|
|
30082
30118
|
//USED TO MAKE VIEWING EASIER
|
|
30083
30119
|
className;
|
|
30120
|
+
/**
|
|
30121
|
+
* @deprecated Do not use this directly
|
|
30122
|
+
*/
|
|
30084
30123
|
_properties = /* @__PURE__ */ new Map();
|
|
30085
30124
|
_referencedBy = [];
|
|
30086
30125
|
_connectionReferences = [];
|
|
30087
|
-
|
|
30126
|
+
_children = [];
|
|
30088
30127
|
parent = void 0;
|
|
30089
30128
|
destroyed = false;
|
|
30090
|
-
|
|
30091
|
-
|
|
30129
|
+
_hasWrappered = false;
|
|
30130
|
+
//private _canGC: boolean = true
|
|
30092
30131
|
classID;
|
|
30093
30132
|
//dont use this to identify instance class, it is only used during file loading
|
|
30094
30133
|
objectFormat;
|
|
@@ -30123,8 +30162,8 @@ class Instance {
|
|
|
30123
30162
|
}
|
|
30124
30163
|
createWrapper() {
|
|
30125
30164
|
const wrapper = GetWrapperForInstance(this);
|
|
30126
|
-
if (wrapper && !this.
|
|
30127
|
-
this.
|
|
30165
|
+
if (wrapper && !this._hasWrappered) {
|
|
30166
|
+
this._hasWrappered = true;
|
|
30128
30167
|
wrapper.created();
|
|
30129
30168
|
}
|
|
30130
30169
|
}
|
|
@@ -30242,6 +30281,13 @@ class Instance {
|
|
|
30242
30281
|
name = this.fixPropertyName(name);
|
|
30243
30282
|
return !!this._properties.get(name);
|
|
30244
30283
|
}
|
|
30284
|
+
/**
|
|
30285
|
+
* Returns the value of a property
|
|
30286
|
+
* @param name Name of property
|
|
30287
|
+
* @returns Property's value
|
|
30288
|
+
*
|
|
30289
|
+
* @throws When property doesn't exist, PropOrDefault is a safer alternative
|
|
30290
|
+
*/
|
|
30245
30291
|
Property(name) {
|
|
30246
30292
|
let property = this._properties.get(name);
|
|
30247
30293
|
if (property) return property.value;
|
|
@@ -30285,6 +30331,13 @@ class Instance {
|
|
|
30285
30331
|
throw new Error(`Property: ${name} does not exist`);
|
|
30286
30332
|
}
|
|
30287
30333
|
}
|
|
30334
|
+
/**
|
|
30335
|
+
* Returns the value of a property
|
|
30336
|
+
* @param name Name of property
|
|
30337
|
+
* @returns Property's value
|
|
30338
|
+
*
|
|
30339
|
+
* @throws When property doesn't exist, PropOrDefault is a safer alternative
|
|
30340
|
+
*/
|
|
30288
30341
|
Prop(name) {
|
|
30289
30342
|
return this.Property(name);
|
|
30290
30343
|
}
|
|
@@ -30305,9 +30358,9 @@ class Instance {
|
|
|
30305
30358
|
throw new Error("Cannot set parent of instance to a destroyed instance");
|
|
30306
30359
|
}
|
|
30307
30360
|
if (this.parent) {
|
|
30308
|
-
const index = this.parent.
|
|
30361
|
+
const index = this.parent._children.indexOf(this);
|
|
30309
30362
|
if (index !== -1) {
|
|
30310
|
-
this.parent.
|
|
30363
|
+
this.parent._children.splice(index, 1);
|
|
30311
30364
|
}
|
|
30312
30365
|
}
|
|
30313
30366
|
const originalParent = this.parent;
|
|
@@ -30316,7 +30369,7 @@ class Instance {
|
|
|
30316
30369
|
originalParent.ChildRemoved.Fire(this);
|
|
30317
30370
|
}
|
|
30318
30371
|
if (instance) {
|
|
30319
|
-
instance.
|
|
30372
|
+
instance._children.push(this);
|
|
30320
30373
|
}
|
|
30321
30374
|
if (fireEvents) {
|
|
30322
30375
|
if (instance) {
|
|
@@ -30373,7 +30426,7 @@ class Instance {
|
|
|
30373
30426
|
}
|
|
30374
30427
|
GetChildren() {
|
|
30375
30428
|
const childrenList = [];
|
|
30376
|
-
for (const child of this.
|
|
30429
|
+
for (const child of this._children) {
|
|
30377
30430
|
childrenList.push(child);
|
|
30378
30431
|
}
|
|
30379
30432
|
return childrenList;
|
|
@@ -30403,7 +30456,7 @@ class Instance {
|
|
|
30403
30456
|
return this.FindFirstChild(name);
|
|
30404
30457
|
}
|
|
30405
30458
|
FindFirstChildOfClass(className) {
|
|
30406
|
-
for (const child of this.
|
|
30459
|
+
for (const child of this._children) {
|
|
30407
30460
|
if (child.className === className) {
|
|
30408
30461
|
return child;
|
|
30409
30462
|
}
|
|
@@ -30411,7 +30464,7 @@ class Instance {
|
|
|
30411
30464
|
}
|
|
30412
30465
|
FindLastChildOfClass(className) {
|
|
30413
30466
|
let lastChild = void 0;
|
|
30414
|
-
for (const child of this.
|
|
30467
|
+
for (const child of this._children) {
|
|
30415
30468
|
if (child.className === className) {
|
|
30416
30469
|
lastChild = child;
|
|
30417
30470
|
}
|
|
@@ -30527,7 +30580,7 @@ class RBX {
|
|
|
30527
30580
|
treeGenerated = false;
|
|
30528
30581
|
xmlString;
|
|
30529
30582
|
get instances() {
|
|
30530
|
-
return this.dataModel.
|
|
30583
|
+
return this.dataModel.GetChildren();
|
|
30531
30584
|
}
|
|
30532
30585
|
constructor() {
|
|
30533
30586
|
this.reset();
|
|
@@ -31421,6 +31474,10 @@ class RBX {
|
|
|
31421
31474
|
}
|
|
31422
31475
|
return buffer2;
|
|
31423
31476
|
}
|
|
31477
|
+
/**
|
|
31478
|
+
* Generates if needed hierarchy and returns root instance
|
|
31479
|
+
* @returns Root instance
|
|
31480
|
+
*/
|
|
31424
31481
|
generateTree() {
|
|
31425
31482
|
if (this.treeGenerated) {
|
|
31426
31483
|
warn(false, "Tree already generated");
|
|
@@ -32722,6 +32779,10 @@ class Outfit {
|
|
|
32722
32779
|
}
|
|
32723
32780
|
return issues;
|
|
32724
32781
|
}
|
|
32782
|
+
/**
|
|
32783
|
+
* @deprecated Outdated
|
|
32784
|
+
* @returns
|
|
32785
|
+
*/
|
|
32725
32786
|
async toHumanoidDescription() {
|
|
32726
32787
|
const response = await fetch("/assets/HumanoidDescriptionTemplate.xml");
|
|
32727
32788
|
if (response.status !== 200)
|
|
@@ -32876,10 +32937,12 @@ class Outfit {
|
|
|
32876
32937
|
return HumanoidDescription;
|
|
32877
32938
|
}
|
|
32878
32939
|
//TODO: Implement
|
|
32940
|
+
/** @deprecated */
|
|
32879
32941
|
async fromHumanoidDescription(rootDocument) {
|
|
32880
32942
|
const humanoidDescription = rootDocument.querySelector(".HumanoidDescription");
|
|
32881
32943
|
log(false, humanoidDescription);
|
|
32882
32944
|
}
|
|
32945
|
+
/** @deprecated */
|
|
32883
32946
|
async downloadHumanoidDescription() {
|
|
32884
32947
|
const humanoidDescription = await this.toHumanoidDescription();
|
|
32885
32948
|
if (humanoidDescription) {
|
|
@@ -33022,6 +33085,9 @@ class Outfit {
|
|
|
33022
33085
|
asset.assetType.name = typeName;
|
|
33023
33086
|
this.assets.push(asset);
|
|
33024
33087
|
}
|
|
33088
|
+
/**
|
|
33089
|
+
* Fixes multiple layered assets having the same order value
|
|
33090
|
+
*/
|
|
33025
33091
|
fixOrders() {
|
|
33026
33092
|
for (const asset of this.assets.slice().reverse()) {
|
|
33027
33093
|
if (!AccessoryAssetTypes.includes(asset.assetType.name) && LayeredAssetTypes.includes(asset.assetType.name)) {
|
|
@@ -35133,6 +35199,9 @@ class Authentication {
|
|
|
35133
35199
|
}
|
|
35134
35200
|
}
|
|
35135
35201
|
async function RBLXPost(url, auth, body, attempt = 0, method = "POST") {
|
|
35202
|
+
if (url.match(/https?:\/\/[a-z]+.roblox.com/)) {
|
|
35203
|
+
url = url.replace("roblox.com", FLAGS.API_DOMAIN);
|
|
35204
|
+
}
|
|
35136
35205
|
if (typeof body !== "string") {
|
|
35137
35206
|
body = JSON.stringify(body);
|
|
35138
35207
|
}
|
|
@@ -35179,6 +35248,9 @@ async function RBLXPost(url, auth, body, attempt = 0, method = "POST") {
|
|
|
35179
35248
|
});
|
|
35180
35249
|
}
|
|
35181
35250
|
async function RBLXGet(url, headers, includeCredentials = true) {
|
|
35251
|
+
if (url.match(/https?:\/\/[a-z]+.roblox.com/)) {
|
|
35252
|
+
url = url.replace("roblox.com", FLAGS.API_DOMAIN);
|
|
35253
|
+
}
|
|
35182
35254
|
return new Promise((resolve) => {
|
|
35183
35255
|
let newHeaders = {
|
|
35184
35256
|
"Content-Type": "application/json"
|
|
@@ -36374,6 +36446,16 @@ class RBFDeformerPatch {
|
|
|
36374
36446
|
// avoid matrix from being singular
|
|
36375
36447
|
affectBones = true;
|
|
36376
36448
|
id = rbfDeformerIdCount++;
|
|
36449
|
+
/**
|
|
36450
|
+
* Creates the deformer and prepares for deformation
|
|
36451
|
+
* @param refMesh The reference cage
|
|
36452
|
+
* @param distMesh The destination cage
|
|
36453
|
+
* @param mesh The mesh to deform
|
|
36454
|
+
* @param ignoredIndices Indices in the reference cage to ignore
|
|
36455
|
+
* @param patchCount Amount of patches spread around the mesh, each one solves a linear equation
|
|
36456
|
+
* @param detailsCount Amount of close vertices in each patch
|
|
36457
|
+
* @param importantsCount Amount of far away vertices in each patch
|
|
36458
|
+
*/
|
|
36377
36459
|
constructor(refMesh, distMesh, mesh, ignoredIndices = [], patchCount = FLAGS.RBF_PATCH_COUNT, detailsCount = FLAGS.RBF_PATCH_DETAIL_SAMPLES, importantsCount = FLAGS.RBF_PATCH_SHAPE_SAMPLES) {
|
|
36378
36460
|
time(`RBFDeformerPatch.constructor.${this.id}`);
|
|
36379
36461
|
this.mesh = mesh;
|
|
@@ -36423,6 +36505,10 @@ class RBFDeformerPatch {
|
|
|
36423
36505
|
this.patchCount = patchCount;
|
|
36424
36506
|
timeEnd(`RBFDeformerPatch.constructor.${this.id}`);
|
|
36425
36507
|
}
|
|
36508
|
+
/**
|
|
36509
|
+
* Solves the linear equations asynchronously, required before deformation
|
|
36510
|
+
* @returns void
|
|
36511
|
+
*/
|
|
36426
36512
|
async solveAsync() {
|
|
36427
36513
|
if (this.refVerts.length === 0) {
|
|
36428
36514
|
return;
|
|
@@ -36448,6 +36534,12 @@ class RBFDeformerPatch {
|
|
|
36448
36534
|
this.nearestPatch = new Uint16Array(nearestPatchBuf);
|
|
36449
36535
|
timeEnd(`RBFDeformerPatch.solveAsync.unpack.${this.id}`);
|
|
36450
36536
|
}
|
|
36537
|
+
/**
|
|
36538
|
+
* solveAsync() needs to be called before this
|
|
36539
|
+
* Deforms the position of something inside the mesh
|
|
36540
|
+
* @param i The index of the vert to deform, if it is outside the range of vertices it will be a bone instead. For example vertices range from 1 - 100, and bones range from 101 - 110. Then index 101 will represent the first bone
|
|
36541
|
+
* @returns New position after deformation
|
|
36542
|
+
*/
|
|
36451
36543
|
deform(i) {
|
|
36452
36544
|
if (!this.nearestPatch || !this.neighborIndices || !this.weights) {
|
|
36453
36545
|
throw new Error("RBF has not been solved");
|
|
@@ -36471,6 +36563,10 @@ class RBFDeformerPatch {
|
|
|
36471
36563
|
}
|
|
36472
36564
|
return add(vec, [dx, dy, dz]);
|
|
36473
36565
|
}
|
|
36566
|
+
/**
|
|
36567
|
+
* solveAsync() needs to be called before this
|
|
36568
|
+
* Deforms vertices and bones in mesh (if this.affectBones = true)
|
|
36569
|
+
*/
|
|
36474
36570
|
deformMesh() {
|
|
36475
36571
|
if (this.refVerts.length === 0) {
|
|
36476
36572
|
return;
|
|
@@ -44926,6 +45022,12 @@ class RenderDesc extends DisposableDesc {
|
|
|
44926
45022
|
}
|
|
44927
45023
|
this.virtualFromRenderDesc(other);
|
|
44928
45024
|
}
|
|
45025
|
+
transferFrom(other) {
|
|
45026
|
+
this.virtualTransferFrom(other);
|
|
45027
|
+
}
|
|
45028
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
45029
|
+
virtualTransferFrom(_other) {
|
|
45030
|
+
}
|
|
44929
45031
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
44930
45032
|
virtualFromRenderDesc(_other) {
|
|
44931
45033
|
throw new Error("Virtual method virtualFromRenderDesc called");
|
|
@@ -45331,7 +45433,6 @@ class EmitterDesc extends DisposableDesc {
|
|
|
45331
45433
|
passedTime = 0;
|
|
45332
45434
|
lockedToPart = false;
|
|
45333
45435
|
lifetime = new NumberRange(1, 1);
|
|
45334
|
-
rate = 10;
|
|
45335
45436
|
spreadAngle = new Vector22(0, 0);
|
|
45336
45437
|
speed = new NumberRange(1, 1);
|
|
45337
45438
|
rotation = new NumberRange(0, 0);
|
|
@@ -45344,9 +45445,6 @@ class EmitterDesc extends DisposableDesc {
|
|
|
45344
45445
|
zOffset = 0;
|
|
45345
45446
|
offset = new Vector32();
|
|
45346
45447
|
shapeInOut = 0;
|
|
45347
|
-
colorTexture;
|
|
45348
|
-
alphaTexture;
|
|
45349
|
-
texture;
|
|
45350
45448
|
opacity = 1;
|
|
45351
45449
|
lightEmission = 1;
|
|
45352
45450
|
blending = AdditiveBlending;
|
|
@@ -45354,16 +45452,52 @@ class EmitterDesc extends DisposableDesc {
|
|
|
45354
45452
|
size = new NumberSequence();
|
|
45355
45453
|
transparency = new NumberSequence([new NumberSequenceKeypoint(0, 0, 0)]);
|
|
45356
45454
|
normalizeSizeKeypointTime = true;
|
|
45455
|
+
//requires recompilation
|
|
45456
|
+
rate = 10;
|
|
45457
|
+
colorTexture;
|
|
45458
|
+
alphaTexture;
|
|
45459
|
+
texture;
|
|
45460
|
+
//results
|
|
45357
45461
|
instanceOpacityBuffer;
|
|
45358
45462
|
instanceColorBuffer;
|
|
45359
45463
|
instanceSeedTimeBuffer;
|
|
45360
45464
|
result;
|
|
45361
45465
|
particles = [];
|
|
45466
|
+
initialParticleCount = 0;
|
|
45362
45467
|
get maxCount() {
|
|
45363
|
-
|
|
45468
|
+
const calculatedMax = Math.max(Math.ceil(this.lifetime.Max * this.rate) * 2, 1);
|
|
45469
|
+
const particleMax = this.initialParticleCount + calculatedMax;
|
|
45470
|
+
return particleMax;
|
|
45471
|
+
}
|
|
45472
|
+
needsRegeneration(other) {
|
|
45473
|
+
return this.texture === other.texture && this.alphaTexture === other.alphaTexture && this.colorTexture === other.colorTexture && this.rate === other.rate;
|
|
45364
45474
|
}
|
|
45365
45475
|
isSame(other) {
|
|
45366
|
-
return this.lifetime.isSame(other.lifetime) && this.
|
|
45476
|
+
return !this.needsRegeneration(other) && this.lockedToPart === other.lockedToPart && this.lifetime.isSame(other.lifetime) && this.spreadAngle.isSame(other.spreadAngle) && this.speed.isSame(other.speed) && this.rotation.isSame(other.rotation) && this.rotationSpeed.isSame(other.rotationSpeed) && this.localAcceleration.isSame(other.localAcceleration) && this.acceleration.isSame(other.acceleration) && this.drag === other.drag && this.timeScale === other.timeScale && this.orientation === other.orientation && this.zOffset === other.zOffset && this.offset.isSame(other.offset) && this.shapeInOut === other.shapeInOut && this.opacity === other.opacity && this.lightEmission === other.lightEmission && this.blending === other.blending && this.color.isSame(other.color) && this.size.isSame(other.size) && this.transparency.isSame(other.transparency) && this.normalizeSizeKeypointTime === other.normalizeSizeKeypointTime;
|
|
45477
|
+
}
|
|
45478
|
+
fromEmitterDesc(other) {
|
|
45479
|
+
this.lockedToPart = other.lockedToPart;
|
|
45480
|
+
this.lifetime = other.lifetime.clone();
|
|
45481
|
+
this.rate = other.rate;
|
|
45482
|
+
this.spreadAngle = other.spreadAngle.clone();
|
|
45483
|
+
this.speed = other.speed.clone();
|
|
45484
|
+
this.rotation = other.rotation.clone();
|
|
45485
|
+
this.rotationSpeed = other.rotationSpeed.clone();
|
|
45486
|
+
this.localAcceleration = other.localAcceleration.clone();
|
|
45487
|
+
this.acceleration = other.acceleration.clone();
|
|
45488
|
+
this.drag = other.drag;
|
|
45489
|
+
this.timeScale = other.timeScale;
|
|
45490
|
+
this.orientation = other.orientation;
|
|
45491
|
+
this.zOffset = other.zOffset;
|
|
45492
|
+
this.offset = other.offset.clone();
|
|
45493
|
+
this.shapeInOut = other.shapeInOut;
|
|
45494
|
+
this.opacity = other.opacity;
|
|
45495
|
+
this.lightEmission = other.lightEmission;
|
|
45496
|
+
this.blending = other.blending;
|
|
45497
|
+
this.color = other.color.clone();
|
|
45498
|
+
this.size = other.size.clone();
|
|
45499
|
+
this.transparency = other.transparency.clone();
|
|
45500
|
+
this.normalizeSizeKeypointTime = other.normalizeSizeKeypointTime;
|
|
45367
45501
|
}
|
|
45368
45502
|
dispose(renderer, scene) {
|
|
45369
45503
|
const mesh = this.result;
|
|
@@ -45589,17 +45723,14 @@ class EmitterGroupDesc extends RenderDesc {
|
|
|
45589
45723
|
if (this.needsRegeneration(other)) {
|
|
45590
45724
|
return false;
|
|
45591
45725
|
}
|
|
45592
|
-
|
|
45593
|
-
return false;
|
|
45594
|
-
}
|
|
45595
|
-
return true;
|
|
45726
|
+
return this.time === other.time;
|
|
45596
45727
|
}
|
|
45597
45728
|
needsRegeneration(other) {
|
|
45598
45729
|
if (this.emitterDescs.length !== other.emitterDescs.length) {
|
|
45599
45730
|
return true;
|
|
45600
45731
|
}
|
|
45601
45732
|
for (let i = 0; i < this.emitterDescs.length; i++) {
|
|
45602
|
-
if (!this.emitterDescs[i].
|
|
45733
|
+
if (!this.emitterDescs[i].needsRegeneration(other.emitterDescs[i])) {
|
|
45603
45734
|
return true;
|
|
45604
45735
|
}
|
|
45605
45736
|
}
|
|
@@ -45611,6 +45742,17 @@ class EmitterGroupDesc extends RenderDesc {
|
|
|
45611
45742
|
this.lowerBound = other.lowerBound;
|
|
45612
45743
|
this.higherBound = other.higherBound;
|
|
45613
45744
|
this.emitterDir = other.emitterDir;
|
|
45745
|
+
for (let i = 0; i < this.emitterDescs.length; i++) {
|
|
45746
|
+
this.emitterDescs[i].fromEmitterDesc(other.emitterDescs[i]);
|
|
45747
|
+
}
|
|
45748
|
+
}
|
|
45749
|
+
virtualTransferFrom(other) {
|
|
45750
|
+
if (this.emitterDescs.length === other.emitterDescs.length) {
|
|
45751
|
+
for (let i = 0; i < this.emitterDescs.length; i++) {
|
|
45752
|
+
this.emitterDescs[i].particles = other.emitterDescs[i].particles;
|
|
45753
|
+
this.emitterDescs[i].initialParticleCount = this.emitterDescs[i].particles.length;
|
|
45754
|
+
}
|
|
45755
|
+
}
|
|
45614
45756
|
}
|
|
45615
45757
|
fromInstance(child) {
|
|
45616
45758
|
this.instance = child;
|
|
@@ -46897,6 +47039,11 @@ class AnimatorWrapper extends InstanceWrapper {
|
|
|
46897
47039
|
this._switchToolAnimation(this.data.currentToolAnimation);
|
|
46898
47040
|
}
|
|
46899
47041
|
}
|
|
47042
|
+
/**
|
|
47043
|
+
* Resets all joints in the rig to be in their rest pose
|
|
47044
|
+
* @param includeMotors If motors (body movement joints) should be set to rest pose
|
|
47045
|
+
* @param includeFACS If FACS (face movement bones) should be set to rest pose
|
|
47046
|
+
*/
|
|
46900
47047
|
restPose(includeMotors = true, includeFACS = true) {
|
|
46901
47048
|
const rig = this.instance.parent?.parent;
|
|
46902
47049
|
if (!rig) {
|
|
@@ -46916,6 +47063,12 @@ class AnimatorWrapper extends InstanceWrapper {
|
|
|
46916
47063
|
}
|
|
46917
47064
|
}
|
|
46918
47065
|
}
|
|
47066
|
+
/**
|
|
47067
|
+
* Renders animation pose
|
|
47068
|
+
* @param addTime Time to add to the current time
|
|
47069
|
+
* @param forceTime Time to force animation to be at, -1 is in the middle of the animation
|
|
47070
|
+
* @param forceKeyframe Keyframe to force animation to be at
|
|
47071
|
+
*/
|
|
46919
47072
|
renderAnimation(addTime = 1 / 60, forceTime, forceKeyframe) {
|
|
46920
47073
|
const humanoid = this.instance.parent;
|
|
46921
47074
|
if (!humanoid) {
|
|
@@ -46988,11 +47141,22 @@ class AnimatorWrapper extends InstanceWrapper {
|
|
|
46988
47141
|
}
|
|
46989
47142
|
}
|
|
46990
47143
|
}
|
|
47144
|
+
/**
|
|
47145
|
+
*
|
|
47146
|
+
* @returns Currently playing animation track
|
|
47147
|
+
*/
|
|
46991
47148
|
getCurrentAnimationTrack() {
|
|
46992
47149
|
if (this.data.currentAnimationTrack) {
|
|
46993
47150
|
return this.data.currentAnimationTrack;
|
|
46994
47151
|
}
|
|
46995
47152
|
}
|
|
47153
|
+
/**
|
|
47154
|
+
* Loads a new animation
|
|
47155
|
+
* @param id
|
|
47156
|
+
* @param isEmote
|
|
47157
|
+
* @param forceLoop Forces animation track to loop
|
|
47158
|
+
* @returns undefined on success
|
|
47159
|
+
*/
|
|
46996
47160
|
async loadAvatarAnimation(id, isEmote = false, forceLoop = false) {
|
|
46997
47161
|
const humanoid = this.instance.parent;
|
|
46998
47162
|
if (!humanoid) {
|
|
@@ -47103,6 +47267,12 @@ class AnimatorWrapper extends InstanceWrapper {
|
|
|
47103
47267
|
}
|
|
47104
47268
|
}
|
|
47105
47269
|
}
|
|
47270
|
+
/**
|
|
47271
|
+
* Switches to new animation
|
|
47272
|
+
* @param name Animation name, such as "idle", "walk" or "emote.1234"
|
|
47273
|
+
* @param type
|
|
47274
|
+
* @returns If animation sucessfully played
|
|
47275
|
+
*/
|
|
47106
47276
|
playAnimation(name, type = "main") {
|
|
47107
47277
|
const humanoid = this.instance.parent;
|
|
47108
47278
|
if (!humanoid) {
|
|
@@ -47753,6 +47923,11 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
|
|
|
47753
47923
|
return void 0;
|
|
47754
47924
|
}
|
|
47755
47925
|
}
|
|
47926
|
+
/**
|
|
47927
|
+
* Update the data of the HumanoidDescription to match that inside an Outfit
|
|
47928
|
+
* @param outfit
|
|
47929
|
+
* @returns HumanoidDescription or Response if it fails
|
|
47930
|
+
*/
|
|
47756
47931
|
async fromOutfit(outfit) {
|
|
47757
47932
|
this.instance.setProperty("BodyTypeScale", outfit.scale.bodyType);
|
|
47758
47933
|
this.instance.setProperty("ProportionScale", outfit.scale.proportion);
|
|
@@ -49161,14 +49336,17 @@ class RBXRendererScene {
|
|
|
49161
49336
|
ambientLight;
|
|
49162
49337
|
directionalLight;
|
|
49163
49338
|
directionalLight2;
|
|
49339
|
+
/** Forces viewport to be within bounds */
|
|
49164
49340
|
setRect(bounds) {
|
|
49165
49341
|
this.viewport = [bounds.left, window.innerHeight - bounds.bottom, bounds.width, bounds.height];
|
|
49166
49342
|
this.scissor = [...this.viewport];
|
|
49167
49343
|
}
|
|
49344
|
+
/** Makes viewport size 0x0, invisible */
|
|
49168
49345
|
noRect() {
|
|
49169
49346
|
this.viewport = [0, 0, 0, 0];
|
|
49170
49347
|
this.scissor = [0, 0, 0, 0];
|
|
49171
49348
|
}
|
|
49349
|
+
/** Destroys all renderDescs but does not call Destroy on instances */
|
|
49172
49350
|
destroy() {
|
|
49173
49351
|
if (this.destroyed) return;
|
|
49174
49352
|
this.destroyed = true;
|
|
@@ -49185,6 +49363,12 @@ class RBXRendererScene {
|
|
|
49185
49363
|
this.shadowPlane = void 0;
|
|
49186
49364
|
}
|
|
49187
49365
|
}
|
|
49366
|
+
/**
|
|
49367
|
+
* Exports scene as a GLTF or GLB
|
|
49368
|
+
* @param name Name of the resulting file if autoDownload is true
|
|
49369
|
+
* @param autoDownload If resulting file should be auto downloaded
|
|
49370
|
+
* @returns The GLB (buffer) or GLTF (object)
|
|
49371
|
+
*/
|
|
49188
49372
|
async exportGLTF(name = "scene", autoDownload = true) {
|
|
49189
49373
|
return new Promise((resolve, reject) => {
|
|
49190
49374
|
const exporter = new GLTFExporter();
|
|
@@ -49667,6 +49851,7 @@ class RBXRenderer {
|
|
|
49667
49851
|
}
|
|
49668
49852
|
} else {
|
|
49669
49853
|
if (!renderScene.isRenderingMesh.get(instance)) {
|
|
49854
|
+
if (oldDesc) newDesc.transferFrom(oldDesc);
|
|
49670
49855
|
newDesc.results = oldDesc?.results;
|
|
49671
49856
|
renderScene.renderDescs.set(instance, newDesc);
|
|
49672
49857
|
renderScene.isRenderingMesh.set(instance, true);
|
|
@@ -49793,6 +49978,9 @@ class RBXRenderer {
|
|
|
49793
49978
|
static getRendererControls() {
|
|
49794
49979
|
return RBXRenderer.controls;
|
|
49795
49980
|
}
|
|
49981
|
+
/**
|
|
49982
|
+
* @returns ThreeJS renderer
|
|
49983
|
+
*/
|
|
49796
49984
|
static getRenderer() {
|
|
49797
49985
|
return RBXRenderer.renderer;
|
|
49798
49986
|
}
|
|
@@ -49800,7 +49988,8 @@ class RBXRenderer {
|
|
|
49800
49988
|
static getScene() {
|
|
49801
49989
|
return RBXRenderer.scene;
|
|
49802
49990
|
}
|
|
49803
|
-
|
|
49991
|
+
/**
|
|
49992
|
+
* @deprecated Superseded by RBXRendererScene.exportGLTF()
|
|
49804
49993
|
* This function is unstable and can throw errors, but might work
|
|
49805
49994
|
*/
|
|
49806
49995
|
static exportScene(renderScene = RBXRenderer.firstScene) {
|
|
@@ -50096,6 +50285,7 @@ class OutfitRenderer {
|
|
|
50096
50285
|
currentlyChangingRig = false;
|
|
50097
50286
|
currentlyUpdating = false;
|
|
50098
50287
|
hasNewUpdate = false;
|
|
50288
|
+
_queuedMainAnimation;
|
|
50099
50289
|
lastFrameTime = Date.now() / 100;
|
|
50100
50290
|
animationInterval;
|
|
50101
50291
|
animationFPS = 60;
|
|
@@ -50162,6 +50352,10 @@ class OutfitRenderer {
|
|
|
50162
50352
|
const humanoid = this.currentRig.FindFirstChildOfClass("Humanoid");
|
|
50163
50353
|
if (humanoid) {
|
|
50164
50354
|
hrpWrapper.applyDescription(humanoid).then((result) => {
|
|
50355
|
+
if (this._queuedMainAnimation) {
|
|
50356
|
+
this.setMainAnimation(this._queuedMainAnimation);
|
|
50357
|
+
this._queuedMainAnimation = void 0;
|
|
50358
|
+
}
|
|
50165
50359
|
this.currentlyUpdating = false;
|
|
50166
50360
|
if (this.currentRig) {
|
|
50167
50361
|
RBXRenderer.addInstance(this.currentRig, this.auth, this.renderScene);
|
|
@@ -50268,6 +50462,8 @@ class OutfitRenderer {
|
|
|
50268
50462
|
}
|
|
50269
50463
|
}
|
|
50270
50464
|
}
|
|
50465
|
+
} else {
|
|
50466
|
+
this._queuedMainAnimation = name;
|
|
50271
50467
|
}
|
|
50272
50468
|
}
|
|
50273
50469
|
}
|
|
@@ -50463,10 +50659,12 @@ export {
|
|
|
50463
50659
|
FindFirstMatchingAttachment,
|
|
50464
50660
|
FullBodyColors,
|
|
50465
50661
|
GetAttachedPart,
|
|
50662
|
+
GetWrapperForInstance,
|
|
50466
50663
|
HSR,
|
|
50467
50664
|
HumanoidDescriptionWrapper,
|
|
50468
50665
|
HumanoidRigType,
|
|
50469
50666
|
Instance,
|
|
50667
|
+
InstanceWrapper,
|
|
50470
50668
|
ItemInfo,
|
|
50471
50669
|
ItemSort,
|
|
50472
50670
|
LayeredAssetTypes,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "roavatar-renderer",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.2",
|
|
4
4
|
"description": "A renderer for Roblox avatars, used by the RoAvatar extension.",
|
|
5
5
|
"author": "steinan",
|
|
6
6
|
"type": "module",
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
"eslint-plugin-react-hooks": "^5.2.0",
|
|
47
47
|
"eslint-plugin-react-refresh": "^0.4.22",
|
|
48
48
|
"globals": "^16.4.0",
|
|
49
|
+
"typedoc": "^0.28.19",
|
|
49
50
|
"typescript": "~5.9.3",
|
|
50
51
|
"typescript-eslint": "^8.45.0",
|
|
51
52
|
"vite": "^7.1.7",
|