mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-26 00:55:10 +02:00
Excluding EntityShapeVisualizer from Children list Now a name is given to the EntityShape of the EntityShapeVisualizer (used to display the zone) so we can now exclude them from the children list when it's time to figure if there are children for an entity. (This is a better approach than excluding al the local entities) The name has been used because it gives better results than trying to use the id map that arrive always too late. The name is unique for a session, it includes a UUID.
260 lines
8.2 KiB
JavaScript
260 lines
8.2 KiB
JavaScript
"use strict";
|
|
|
|
// entityShapeVisualizer.js
|
|
//
|
|
// Created by Thijs Wenker on 1/11/19
|
|
//
|
|
// Copyright 2019 High Fidelity, Inc.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
var SHAPETYPE_TO_SHAPE = {
|
|
"box": "Cube",
|
|
"ellipsoid": "Sphere",
|
|
"cylinder-y": "Cylinder",
|
|
};
|
|
|
|
var REQUESTED_ENTITY_SHAPE_PROPERTIES = [
|
|
'type', 'shapeType', 'compoundShapeURL', 'localDimensions'
|
|
];
|
|
|
|
function getEntityShapePropertiesForType(properties) {
|
|
switch (properties.type) {
|
|
case "Zone":
|
|
if (SHAPETYPE_TO_SHAPE[properties.shapeType]) {
|
|
return {
|
|
type: "Shape",
|
|
shape: SHAPETYPE_TO_SHAPE[properties.shapeType],
|
|
localDimensions: properties.localDimensions
|
|
};
|
|
} else if (properties.shapeType === "compound") {
|
|
return {
|
|
type: "Model",
|
|
modelURL: properties.compoundShapeURL,
|
|
localDimensions: properties.localDimensions
|
|
};
|
|
} else if (properties.shapeType === "sphere") {
|
|
var sphereDiameter = Math.max(properties.localDimensions.x, properties.localDimensions.y,
|
|
properties.localDimensions.z);
|
|
return {
|
|
type: "Sphere",
|
|
modelURL: properties.compoundShapeURL,
|
|
localDimensions: {x: sphereDiameter, y: sphereDiameter, z: sphereDiameter}
|
|
};
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Default properties
|
|
return {
|
|
type: "Shape",
|
|
shape: "Cube",
|
|
localDimensions: properties.localDimensions
|
|
};
|
|
}
|
|
|
|
function deepEqual(a, b) {
|
|
if (a === b) {
|
|
return true;
|
|
}
|
|
|
|
if (typeof(a) !== "object" || typeof(b) !== "object") {
|
|
return false;
|
|
}
|
|
|
|
if (Object.keys(a).length !== Object.keys(b).length) {
|
|
return false;
|
|
}
|
|
|
|
for (var property in a) {
|
|
if (!a.hasOwnProperty(property)) {
|
|
continue;
|
|
}
|
|
if (!b.hasOwnProperty(property)) {
|
|
return false;
|
|
}
|
|
if (!deepEqual(a[property], b[property])) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Returns an array of property names which are different in comparison.
|
|
* @param propertiesA
|
|
* @param propertiesB
|
|
* @returns {Array} - array of different property names
|
|
*/
|
|
function compareEntityProperties(propertiesA, propertiesB) {
|
|
var differentProperties = [],
|
|
property;
|
|
|
|
for (property in propertiesA) {
|
|
if (!propertiesA.hasOwnProperty(property)) {
|
|
continue;
|
|
}
|
|
if (!propertiesB.hasOwnProperty(property) || !deepEqual(propertiesA[property], propertiesB[property])) {
|
|
differentProperties.push(property);
|
|
}
|
|
}
|
|
for (property in propertiesB) {
|
|
if (!propertiesB.hasOwnProperty(property)) {
|
|
continue;
|
|
}
|
|
if (!propertiesA.hasOwnProperty(property)) {
|
|
differentProperties.push(property);
|
|
}
|
|
}
|
|
|
|
return differentProperties;
|
|
}
|
|
|
|
function deepCopy(v) {
|
|
return JSON.parse(JSON.stringify(v));
|
|
}
|
|
|
|
function EntityShape(entityID, entityShapeVisualizerSessionName) {
|
|
this.entityID = entityID;
|
|
this.entityShapeVisualizerSessionName = entityShapeVisualizerSessionName;
|
|
|
|
var propertiesForType = getEntityShapePropertiesForType(Entities.getEntityProperties(entityID, REQUESTED_ENTITY_SHAPE_PROPERTIES));
|
|
|
|
this.previousPropertiesForType = propertiesForType;
|
|
|
|
this.initialize(propertiesForType);
|
|
}
|
|
|
|
EntityShape.prototype = {
|
|
initialize: function(properties) {
|
|
// Create new instance of JS object:
|
|
var overlayProperties = deepCopy(properties);
|
|
|
|
overlayProperties.name = this.entityShapeVisualizerSessionName;
|
|
overlayProperties.localPosition = Vec3.ZERO;
|
|
overlayProperties.localRotation = Quat.IDENTITY;
|
|
overlayProperties.canCastShadows = false;
|
|
overlayProperties.parentID = this.entityID;
|
|
overlayProperties.collisionless = true;
|
|
overlayProperties.ignorePickIntersection = true;
|
|
this.entity = Entities.addEntity(overlayProperties, "local");
|
|
var PROJECTED_MATERIALS = false;
|
|
this.materialEntity = Entities.addEntity({
|
|
type: "Material",
|
|
localPosition: Vec3.ZERO,
|
|
localRotation: Quat.IDENTITY,
|
|
localDimensions: properties.localDimensions,
|
|
parentID: this.entity,
|
|
priority: 1,
|
|
materialMappingMode: PROJECTED_MATERIALS ? "projected" : "uv",
|
|
materialURL: Script.resolvePath("../../assets/images/materials/GridPattern.json"),
|
|
ignorePickIntersection: true
|
|
}, "local");
|
|
},
|
|
update: function() {
|
|
var propertiesForType = getEntityShapePropertiesForType(Entities.getEntityProperties(this.entityID, REQUESTED_ENTITY_SHAPE_PROPERTIES));
|
|
|
|
var difference = compareEntityProperties(propertiesForType, this.previousPropertiesForType);
|
|
|
|
if (deepEqual(difference, ['localDimensions'])) {
|
|
this.previousPropertiesForType = propertiesForType;
|
|
Entities.editEntity(this.entity, {
|
|
localDimensions: propertiesForType.localDimensions,
|
|
});
|
|
} else if (difference.length > 0) {
|
|
this.previousPropertiesForType = propertiesForType;
|
|
this.clear();
|
|
this.initialize(propertiesForType);
|
|
}
|
|
},
|
|
clear: function() {
|
|
Entities.deleteEntity(this.materialEntity);
|
|
Entities.deleteEntity(this.entity);
|
|
}
|
|
};
|
|
|
|
function EntityShapeVisualizer(visualizedTypes, entityShapeVisualizerSessionName) {
|
|
this.acceptedEntities = [];
|
|
this.ignoredEntities = [];
|
|
this.entityShapes = {};
|
|
this.entityShapeVisualizerSessionName = entityShapeVisualizerSessionName;
|
|
this.visualizedTypes = visualizedTypes;
|
|
}
|
|
|
|
EntityShapeVisualizer.prototype = {
|
|
addEntity: function(entityID) {
|
|
if (this.entityShapes[entityID]) {
|
|
return;
|
|
}
|
|
this.entityShapes[entityID] = new EntityShape(entityID, this.entityShapeVisualizerSessionName);
|
|
|
|
},
|
|
updateEntity: function(entityID) {
|
|
if (!this.entityShapes[entityID]) {
|
|
return;
|
|
}
|
|
this.entityShapes[entityID].update();
|
|
},
|
|
removeEntity: function(entityID) {
|
|
if (!this.entityShapes[entityID]) {
|
|
return;
|
|
}
|
|
this.entityShapes[entityID].clear();
|
|
delete this.entityShapes[entityID];
|
|
},
|
|
cleanup: function() {
|
|
Object.keys(this.entityShapes).forEach(function(entityID) {
|
|
this.entityShapes[entityID].clear();
|
|
}, this);
|
|
this.entityShapes = {};
|
|
},
|
|
setEntities: function(entities) {
|
|
var qualifiedEntities = entities.filter(function(entityID) {
|
|
if (this.acceptedEntities.indexOf(entityID) !== -1) {
|
|
return true;
|
|
}
|
|
if (this.ignoredEntities.indexOf(entityID) !== -1) {
|
|
return false;
|
|
}
|
|
if (this.visualizedTypes.indexOf(Entities.getEntityProperties(entityID, "type").type) !== -1) {
|
|
this.acceptedEntities.push(entityID);
|
|
return true;
|
|
}
|
|
this.ignoredEntities.push(entityID);
|
|
return false;
|
|
}, this);
|
|
|
|
|
|
var newEntries = [];
|
|
var updateEntries = [];
|
|
|
|
var currentEntries = Object.keys(this.entityShapes);
|
|
qualifiedEntities.forEach(function(entityID) {
|
|
if (currentEntries.indexOf(entityID) !== -1) {
|
|
updateEntries.push(entityID);
|
|
} else {
|
|
newEntries.push(entityID);
|
|
}
|
|
});
|
|
|
|
var deleteEntries = currentEntries.filter(function(entityID) {
|
|
return updateEntries.indexOf(entityID) === -1;
|
|
});
|
|
|
|
deleteEntries.forEach(function(entityID) {
|
|
this.removeEntity(entityID);
|
|
}, this);
|
|
|
|
updateEntries.forEach(function(entityID) {
|
|
this.updateEntity(entityID);
|
|
}, this);
|
|
|
|
newEntries.forEach(function(entityID) {
|
|
this.addEntity(entityID);
|
|
}, this);
|
|
}
|
|
};
|
|
|
|
module.exports = EntityShapeVisualizer;
|