Implement GLTF overrides

This commit is contained in:
Casper Warden
2023-11-10 23:57:26 +00:00
parent 3c69b8f05e
commit cb77865537
10 changed files with 1034 additions and 354 deletions

View File

@@ -33,6 +33,7 @@ export class ObjectStoreFull extends ObjectStoreLite implements IObjectStore
{
super(circuit, agent, clientEvents, options);
this.rtree = new RBush3D();
this.fullStore = true;
}
protected objectUpdate(objectUpdate: ObjectUpdateMessage): void
@@ -43,17 +44,19 @@ export class ObjectStoreFull extends ObjectStoreLite implements IObjectStore
const parentID = objData.ParentID;
let addToParentList = true;
let newObject = false;
if (this.objects[localID])
let obj = this.objects.get(localID);
if (obj)
{
if (this.objects[localID].ParentID !== parentID && this.objectsByParent[parentID])
const objsByParent = this.objectsByParent.get(parentID ?? 0);
if (obj.ParentID !== parentID && objsByParent)
{
const ind = this.objectsByParent[parentID].indexOf(localID);
const ind = objsByParent.indexOf(localID);
if (ind !== -1)
{
this.objectsByParent[parentID].splice(ind, 1);
objsByParent.splice(ind, 1);
}
}
else if (this.objectsByParent[parentID])
else if (objsByParent)
{
addToParentList = false;
}
@@ -61,12 +64,12 @@ export class ObjectStoreFull extends ObjectStoreLite implements IObjectStore
else
{
newObject = true;
this.objects[localID] = new GameObject();
this.objects[localID].region = this.agent.currentRegion;
obj = new GameObject();
obj.region = this.agent.currentRegion;
this.objects.set(localID, obj);
}
this.objects[localID].deleted = false;
obj.deleted = false;
const obj = this.objects[localID];
obj.ID = objData.ID;
obj.State = objData.State;
obj.FullID = objData.FullID;
@@ -100,6 +103,12 @@ export class ObjectStoreFull extends ObjectStoreLite implements IObjectStore
obj.ProfileEnd = Utils.unpackEndCut(objData.ProfileEnd);
obj.ProfileHollow = Utils.unpackProfileHollow(objData.ProfileHollow);
obj.TextureEntry = TextureEntry.from(objData.TextureEntry);
const override = this.cachedMaterialOverrides.get(obj.ID);
if (override)
{
obj.TextureEntry.gltfMaterialOverrides = override;
this.cachedMaterialOverrides.delete(obj.ID);
}
obj.textureAnim = TextureAnim.from(objData.TextureAnim);
const pcodeData = objData.Data;
@@ -131,7 +140,7 @@ export class ObjectStoreFull extends ObjectStoreLite implements IObjectStore
break;
}
if (this.objects[localID].PCode === PCode.Avatar && this.objects[localID].FullID.toString() === this.agent.agentID.toString())
if (obj.PCode === PCode.Avatar && obj.FullID.toString() === this.agent.agentID.toString())
{
this.agent.localID = localID;
@@ -143,50 +152,53 @@ export class ObjectStoreFull extends ObjectStoreLite implements IObjectStore
if (parent !== this.agent.localID)
{
let foundAvatars = false;
for (const objID of this.objectsByParent[parent])
const objsByParent = this.objectsByParent.get(parent);
if (objsByParent)
{
if (this.objects[objID])
for (const objID of objsByParent)
{
const o = this.objects[objID];
if (o.PCode === PCode.Avatar)
const ob = this.objects.get(objID);
if (ob && ob.PCode === PCode.Avatar)
{
foundAvatars = true;
}
}
}
if (this.objects[parent])
{
const o = this.objects[parent];
if (o.PCode === PCode.Avatar)
const o = this.objects.get(parent);
if (o && o.PCode === PCode.Avatar)
{
foundAvatars = true;
}
}
if (!foundAvatars)
{
this.deleteObject(parent);
if (!foundAvatars)
{
this.deleteObject(parent);
}
}
}
}
}
}
this.objects[localID].extraParams = ExtraParams.from(objData.ExtraParams);
this.objects[localID].NameValue = this.parseNameValues(Utils.BufferToStringSimple(objData.NameValue));
this.objects[localID].IsAttachment = this.objects[localID].NameValue['AttachItemID'] !== undefined;
obj.extraParams = ExtraParams.from(objData.ExtraParams);
obj.NameValue = this.parseNameValues(Utils.BufferToStringSimple(objData.NameValue));
obj.IsAttachment = obj.NameValue['AttachItemID'] !== undefined;
if (obj.IsAttachment && obj.State !== undefined)
{
this.objects[localID].attachmentPoint = this.decodeAttachPoint(obj.State);
obj.attachmentPoint = this.decodeAttachPoint(obj.State);
}
this.objectsByUUID[objData.FullID.toString()] = localID;
if (!this.objectsByParent[parentID])
this.objectsByUUID.set(objData.FullID.toString(), localID);
let objByParent = this.objectsByParent.get(parentID);
if (!objByParent)
{
this.objectsByParent[parentID] = [];
objByParent = [];
this.objectsByParent.set(parentID, objByParent);
}
if (addToParentList)
{
this.objectsByParent[parentID].push(localID);
objByParent.push(localID);
}
if (objData.PCode !== PCode.Avatar && this.options & BotOptionFlags.StoreMyAttachmentsOnly && (this.agent.localID !== 0 && obj.ParentID !== this.agent.localID))
@@ -197,7 +209,8 @@ export class ObjectStoreFull extends ObjectStoreLite implements IObjectStore
else
{
this.insertIntoRtree(obj);
if (objData.ParentID !== undefined && objData.ParentID !== 0 && !this.objects[objData.ParentID])
const parentObj = this.objects.get(objData.ParentID ?? 0);
if (objData.ParentID !== undefined && objData.ParentID !== 0 && !parentObj)
{
this.requestMissingObject(objData.ParentID).then(() =>
{
@@ -225,7 +238,7 @@ export class ObjectStoreFull extends ObjectStoreLite implements IObjectStore
rmo.ObjectData = [];
for (const obj of objectUpdateCached.ObjectData)
{
if (!this.objects[obj.ID])
if (!this.objects.has(obj.ID))
{
rmo.ObjectData.push({
CacheMissType: 0,
@@ -257,15 +270,16 @@ export class ObjectStoreFull extends ObjectStoreLite implements IObjectStore
pos += 4;
const pcode = buf.readUInt8(pos++);
let newObj = false;
if (!this.objects[localID])
let o = this.objects.get(localID);
if (!o)
{
newObj = true;
this.objects[localID] = new GameObject();
this.objects[localID].region = this.agent.currentRegion;
o = new GameObject();
o.region = this.agent.currentRegion;
this.objects.set(localID, o);
}
const o = this.objects[localID];
o.ID = localID;
this.objectsByUUID[fullID.toString()] = localID;
this.objectsByUUID.set(fullID.toString(), localID);
o.FullID = fullID;
o.Flags = flags;
o.PCode = pcode;
@@ -301,26 +315,29 @@ export class ObjectStoreFull extends ObjectStoreLite implements IObjectStore
let add = true;
if (!newObj && o.ParentID !== undefined)
{
if (newParentID !== o.ParentID)
const obsByParent = this.objectsByParent.get(o.ParentID);
if (newParentID !== o.ParentID && obsByParent)
{
const index = this.objectsByParent[o.ParentID].indexOf(localID);
const index = obsByParent.indexOf(localID);
if (index !== -1)
{
this.objectsByParent[o.ParentID].splice(index, 1);
obsByParent.splice(index, 1);
}
}
else if (this.objectsByParent[o.ParentID])
else if (obsByParent)
{
add = false;
}
}
if (add)
{
if (!this.objectsByParent[newParentID])
let objsByNewParent = this.objectsByParent.get(newParentID);
if (!objsByNewParent)
{
this.objectsByParent[newParentID] = [];
objsByNewParent = [];
this.objectsByParent.set(newParentID, objsByNewParent);
}
this.objectsByParent[newParentID].push(localID);
objsByNewParent.push(localID);
}
if (pcode !== PCode.Avatar && newObj && this.options & BotOptionFlags.StoreMyAttachmentsOnly && (this.agent.localID !== 0 && o.ParentID !== this.agent.localID))
@@ -331,9 +348,12 @@ export class ObjectStoreFull extends ObjectStoreLite implements IObjectStore
}
else
{
if (o.ParentID !== undefined && o.ParentID !== 0 && !this.objects[o.ParentID])
if (o.ParentID !== undefined && o.ParentID !== 0 && !this.objects.has(o.ParentID))
{
this.requestMissingObject(o.ParentID);
this.requestMissingObject(o.ParentID).catch((e) =>
{
console.error(e);
});
}
if (compressedflags & CompressedFlags.Tree)
{
@@ -420,6 +440,12 @@ export class ObjectStoreFull extends ObjectStoreLite implements IObjectStore
const textureEntryLength = buf.readUInt32LE(pos);
pos = pos + 4;
o.TextureEntry = TextureEntry.from(buf.slice(pos, pos + textureEntryLength));
const override = this.cachedMaterialOverrides.get(o.ID);
if (override)
{
o.TextureEntry.gltfMaterialOverrides = override;
this.cachedMaterialOverrides.delete(o.ID);
}
pos = pos + textureEntryLength;
if (compressedflags & CompressedFlags.TextureAnimation)
@@ -432,7 +458,7 @@ export class ObjectStoreFull extends ObjectStoreLite implements IObjectStore
o.IsAttachment = (compressedflags & CompressedFlags.HasNameValues) !== 0 && o.ParentID !== 0;
if (o.IsAttachment && o.State !== undefined)
{
this.objects[localID].attachmentPoint = this.decodeAttachPoint(o.State);
o.attachmentPoint = this.decodeAttachPoint(o.State);
}
this.insertIntoRtree(o);
@@ -456,37 +482,38 @@ export class ObjectStoreFull extends ObjectStoreLite implements IObjectStore
let pos = 0;
const localID = objectData.Data.readUInt32LE(pos);
pos = pos + 4;
if (this.objects[localID])
const o = this.objects.get(localID);
if (o)
{
this.objects[localID].State = objectData.Data.readUInt8(pos++);
o.State = objectData.Data.readUInt8(pos++);
const avatar: boolean = (objectData.Data.readUInt8(pos++) !== 0);
if (avatar)
{
this.objects[localID].CollisionPlane = new Vector4(objectData.Data, pos);
o.CollisionPlane = new Vector4(objectData.Data, pos);
pos += 16;
}
this.objects[localID].Position = new Vector3(objectData.Data, pos);
o.Position = new Vector3(objectData.Data, pos);
pos += 12;
this.objects[localID].Velocity = new Vector3([
o.Velocity = new Vector3([
Utils.UInt16ToFloat(objectData.Data.readUInt16LE(pos), -128.0, 128.0),
Utils.UInt16ToFloat(objectData.Data.readUInt16LE(pos + 2), -128.0, 128.0),
Utils.UInt16ToFloat(objectData.Data.readUInt16LE(pos + 4), -128.0, 128.0)
]);
pos += 6;
this.objects[localID].Acceleration = new Vector3([
o.Acceleration = new Vector3([
Utils.UInt16ToFloat(objectData.Data.readUInt16LE(pos), -64.0, 64.0),
Utils.UInt16ToFloat(objectData.Data.readUInt16LE(pos + 2), -64.0, 64.0),
Utils.UInt16ToFloat(objectData.Data.readUInt16LE(pos + 4), -64.0, 64.0)
]);
pos += 6;
this.objects[localID].Rotation = new Quaternion([
o.Rotation = new Quaternion([
Utils.UInt16ToFloat(objectData.Data.readUInt16LE(pos), -1.0, 1.0),
Utils.UInt16ToFloat(objectData.Data.readUInt16LE(pos + 2), -1.0, 1.0),
Utils.UInt16ToFloat(objectData.Data.readUInt16LE(pos + 4), -1.0, 1.0),
Utils.UInt16ToFloat(objectData.Data.readUInt16LE(pos + 6), -1.0, 1.0)
]);
pos += 8;
this.objects[localID].AngularVelocity = new Vector3([
o.AngularVelocity = new Vector3([
Utils.UInt16ToFloat(objectData.Data.readUInt16LE(pos), -64.0, 64.0),
Utils.UInt16ToFloat(objectData.Data.readUInt16LE(pos + 2), -64.0, 64.0),
Utils.UInt16ToFloat(objectData.Data.readUInt16LE(pos + 4), -64.0, 64.0)
@@ -496,11 +523,17 @@ export class ObjectStoreFull extends ObjectStoreLite implements IObjectStore
if (objectData.TextureEntry.length > 0)
{
// No idea why the first four bytes are skipped here.
this.objects[localID].TextureEntry = TextureEntry.from(objectData.TextureEntry.slice(4));
this.objects[localID].onTextureUpdate.next();
o.TextureEntry = TextureEntry.from(objectData.TextureEntry.slice(4));
const override = this.cachedMaterialOverrides.get(o.ID);
if (override)
{
o.TextureEntry.gltfMaterialOverrides = override;
this.cachedMaterialOverrides.delete(o.ID);
}
o.onTextureUpdate.next();
}
this.insertIntoRtree(this.objects[localID]);
this.notifyTerseUpdate(this.objects[localID]);
this.insertIntoRtree(o);
this.notifyTerseUpdate(o);
}
else