- Implement camera controls

- Option to resolve object properties when fetching from object store (names, descriptions etc). Can be more efficient - TODO: use FamilyProperties for child prims.
- Refactored objectstore to reduce code duplication
This commit is contained in:
Casper Warden
2018-10-19 16:30:09 +01:00
parent ff0a5fa58b
commit 2852c76cb0
42 changed files with 2651 additions and 2121 deletions

View File

@@ -17,6 +17,10 @@ const __1 = require("../..");
const ObjectGrab_1 = require("../messages/ObjectGrab");
const ObjectDeGrab_1 = require("../messages/ObjectDeGrab");
const ObjectGrabUpdate_1 = require("../messages/ObjectGrabUpdate");
const ObjectSelect_1 = require("../messages/ObjectSelect");
const Utils_1 = require("../Utils");
const ObjectDeselect_1 = require("../messages/ObjectDeselect");
const PCode_1 = require("../../enums/PCode");
class RegionCommands extends CommandsBase_1.CommandsBase {
getRegionHandle(regionID) {
return __awaiter(this, void 0, void 0, function* () {
@@ -37,8 +41,216 @@ class RegionCommands extends CommandsBase_1.CommandsBase {
return responseMsg.ReplyBlock.RegionHandle;
});
}
getObjectsInArea(minX, maxX, minY, maxY, minZ, maxZ) {
return this.currentRegion.objects.getObjectsInArea(minX, maxX, minY, maxY, minZ, maxZ);
deselectObjects(objects) {
return __awaiter(this, void 0, void 0, function* () {
const selectLimit = 255;
if (objects.length > selectLimit) {
for (let x = 0; x < objects.length; x += selectLimit) {
const selectList = [];
for (let y = 0; y < selectLimit; y++) {
if (y < objects.length) {
selectList.push(objects[x + y]);
}
}
yield this.deselectObjects(selectList);
}
return;
}
else {
const deselectObject = new ObjectDeselect_1.ObjectDeselectMessage();
deselectObject.AgentData = {
AgentID: this.agent.agentID,
SessionID: this.circuit.sessionID
};
deselectObject.ObjectData = [];
const uuidMap = {};
for (const obj of objects) {
const uuidStr = obj.FullID.toString();
if (!uuidMap[uuidStr]) {
uuidMap[uuidStr] = obj;
deselectObject.ObjectData.push({
ObjectLocalID: obj.ID
});
}
}
const sequenceID = this.circuit.sendMessage(deselectObject, __1.PacketFlags.Reliable);
return yield this.circuit.waitForAck(sequenceID, 10000);
}
});
}
countObjects() {
return this.currentRegion.objects.getNumberOfObjects();
}
selectObjects(objects) {
return __awaiter(this, void 0, void 0, function* () {
const selectLimit = 255;
if (objects.length > selectLimit) {
for (let x = 0; x < objects.length; x += selectLimit) {
const selectList = [];
for (let y = 0; y < selectLimit; y++) {
if (y < objects.length) {
selectList.push(objects[x + y]);
}
}
yield this.selectObjects(selectList);
}
return;
}
else {
const selectObject = new ObjectSelect_1.ObjectSelectMessage();
selectObject.AgentData = {
AgentID: this.agent.agentID,
SessionID: this.circuit.sessionID
};
selectObject.ObjectData = [];
const uuidMap = {};
for (const obj of objects) {
const uuidStr = obj.FullID.toString();
if (!uuidMap[uuidStr]) {
uuidMap[uuidStr] = obj;
selectObject.ObjectData.push({
ObjectLocalID: obj.ID
});
}
}
let resolved = 0;
this.circuit.sendMessage(selectObject, __1.PacketFlags.Reliable);
return yield this.circuit.waitForMessage(Message_1.Message.ObjectProperties, 10000, (propertiesMessage) => {
let found = false;
for (const objData of propertiesMessage.ObjectData) {
const objDataUUID = objData.ObjectID.toString();
if (uuidMap[objDataUUID] !== undefined) {
resolved++;
const obj = uuidMap[objDataUUID];
obj.creatorID = objData.CreatorID;
obj.creationDate = objData.CreationDate;
obj.baseMask = objData.BaseMask;
obj.ownerMask = objData.OwnerMask;
obj.groupMask = objData.GroupMask;
obj.everyoneMask = objData.EveryoneMask;
obj.nextOwnerMask = objData.NextOwnerMask;
obj.ownershipCost = objData.OwnershipCost;
obj.saleType = objData.SaleType;
obj.salePrice = objData.SalePrice;
obj.aggregatePerms = objData.AggregatePerms;
obj.aggregatePermTextures = objData.AggregatePermTextures;
obj.aggregatePermTexturesOwner = objData.AggregatePermTexturesOwner;
obj.category = objData.Category;
obj.inventorySerial = objData.InventorySerial;
obj.itemID = objData.ItemID;
obj.folderID = objData.FolderID;
obj.fromTaskID = objData.FromTaskID;
obj.lastOwnerID = objData.LastOwnerID;
obj.name = Utils_1.Utils.BufferToStringSimple(objData.Name);
obj.description = Utils_1.Utils.BufferToStringSimple(objData.Description);
obj.touchName = Utils_1.Utils.BufferToStringSimple(objData.TouchName);
obj.sitName = Utils_1.Utils.BufferToStringSimple(objData.SitName);
obj.textureID = Utils_1.Utils.BufferToStringSimple(objData.TextureID);
obj.resolvedAt = new Date().getTime() / 1000;
delete uuidMap[objDataUUID];
found = true;
}
}
if (Object.keys(uuidMap).length === 0) {
return FilterResponse_1.FilterResponse.Finish;
}
if (!found) {
return FilterResponse_1.FilterResponse.NoMatch;
}
else {
return FilterResponse_1.FilterResponse.Match;
}
});
}
});
}
resolveObjects(objects) {
return __awaiter(this, void 0, void 0, function* () {
const objs = {};
const scanObject = function (obj) {
const localID = obj.ID;
if (!objs[localID]) {
objs[localID] = obj;
if (obj.children) {
for (const child of obj.children) {
scanObject(child);
}
}
}
};
for (const obj of objects) {
scanObject(obj);
}
const resolveTime = new Date().getTime() / 1000;
let objectList = [];
let totalRemaining = 0;
try {
for (const k of Object.keys(objs)) {
const ky = parseInt(k, 10);
if (objs[ky] !== undefined) {
const o = objs[ky];
if (o.resolvedAt === undefined) {
o.resolvedAt = 0;
}
if (o.resolvedAt !== undefined && o.resolvedAt < resolveTime && o.PCode !== PCode_1.PCode.Avatar) {
objs[ky].name = undefined;
totalRemaining++;
objectList.push(objs[ky]);
if (objectList.length > 254) {
try {
yield this.selectObjects(objectList);
yield this.deselectObjects(objectList);
for (const chk of objectList) {
if (chk.resolvedAt !== undefined && chk.resolvedAt >= resolveTime) {
totalRemaining--;
}
}
}
catch (ignore) {
}
finally {
objectList = [];
}
}
}
}
}
if (objectList.length > 0) {
yield this.selectObjects(objectList);
yield this.deselectObjects(objectList);
for (const chk of objectList) {
if (chk.resolvedAt !== undefined && chk.resolvedAt >= resolveTime) {
totalRemaining--;
}
}
}
}
catch (ignore) {
}
finally {
if (totalRemaining < 1) {
totalRemaining = 0;
for (const obj of objectList) {
if (obj.resolvedAt === undefined || obj.resolvedAt < resolveTime) {
totalRemaining++;
}
}
if (totalRemaining > 0) {
console.error(totalRemaining + ' objects could not be resolved');
}
}
}
});
}
getObjectsInArea(minX, maxX, minY, maxY, minZ, maxZ, resolve = false) {
return __awaiter(this, void 0, void 0, function* () {
const objs = this.currentRegion.objects.getObjectsInArea(minX, maxX, minY, maxY, minZ, maxZ);
if (resolve) {
console.log('Resolving ' + objs.length + ' objects');
yield this.resolveObjects(objs);
}
return objs;
});
}
grabObject(localID, grabOffset = __1.Vector3.getZero(), uvCoordinate = __1.Vector3.getZero(), stCoordinate = __1.Vector3.getZero(), faceIndex = 0, position = __1.Vector3.getZero(), normal = __1.Vector3.getZero(), binormal = __1.Vector3.getZero()) {
return __awaiter(this, void 0, void 0, function* () {