mirror of
https://github.com/overte-org/overte.git
synced 2025-04-11 08:54:01 +02:00
Merge pull request #11997 from ZappoMan/oldPropsFilters
giving more info to entity edit filters to allow more flexibility
This commit is contained in:
commit
acda90577a
11 changed files with 408 additions and 17 deletions
|
@ -41,8 +41,8 @@ QList<EntityItemID> EntityEditFilters::getZonesByPosition(glm::vec3& position) {
|
|||
return zones;
|
||||
}
|
||||
|
||||
bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut, bool& wasChanged,
|
||||
EntityTree::FilterType filterType, EntityItemID& itemID) {
|
||||
bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut,
|
||||
bool& wasChanged, EntityTree::FilterType filterType, EntityItemID& itemID, EntityItemPointer& existingEntity) {
|
||||
|
||||
// get the ids of all the zones (plus the global entity edit filter) that the position
|
||||
// lies within
|
||||
|
@ -61,6 +61,17 @@ bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& proper
|
|||
if (filterData.rejectAll) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check to see if this filter wants to filter this message type
|
||||
if ((!filterData.wantsToFilterEdit && filterType == EntityTree::FilterType::Edit) ||
|
||||
(!filterData.wantsToFilterPhysics && filterType == EntityTree::FilterType::Physics) ||
|
||||
(!filterData.wantsToFilterDelete && filterType == EntityTree::FilterType::Delete) ||
|
||||
(!filterData.wantsToFilterAdd && filterType == EntityTree::FilterType::Add)) {
|
||||
|
||||
wasChanged = false;
|
||||
return true; // accept the message
|
||||
}
|
||||
|
||||
auto oldProperties = propertiesIn.getDesiredProperties();
|
||||
auto specifiedProperties = propertiesIn.getChangedProperties();
|
||||
propertiesIn.setDesiredProperties(specifiedProperties);
|
||||
|
@ -68,16 +79,62 @@ bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& proper
|
|||
propertiesIn.setDesiredProperties(oldProperties);
|
||||
|
||||
auto in = QJsonValue::fromVariant(inputValues.toVariant()); // grab json copy now, because the inputValues might be side effected by the filter.
|
||||
|
||||
QScriptValueList args;
|
||||
args << inputValues;
|
||||
args << filterType;
|
||||
|
||||
// get the current properties for then entity and include them for the filter call
|
||||
if (existingEntity && filterData.wantsOriginalProperties) {
|
||||
auto currentProperties = existingEntity->getProperties(filterData.includedOriginalProperties);
|
||||
QScriptValue currentValues = currentProperties.copyToScriptValue(filterData.engine, false, true, true);
|
||||
args << currentValues;
|
||||
}
|
||||
|
||||
|
||||
// get the zone properties
|
||||
if (filterData.wantsZoneProperties) {
|
||||
auto zoneEntity = _tree->findEntityByEntityItemID(id);
|
||||
if (zoneEntity) {
|
||||
auto zoneProperties = zoneEntity->getProperties(filterData.includedZoneProperties);
|
||||
QScriptValue zoneValues = zoneProperties.copyToScriptValue(filterData.engine, false, true, true);
|
||||
|
||||
if (filterData.wantsZoneBoundingBox) {
|
||||
bool success = true;
|
||||
AABox aaBox = zoneEntity->getAABox(success);
|
||||
if (success) {
|
||||
QScriptValue boundingBox = filterData.engine->newObject();
|
||||
QScriptValue bottomRightNear = vec3toScriptValue(filterData.engine, aaBox.getCorner());
|
||||
QScriptValue topFarLeft = vec3toScriptValue(filterData.engine, aaBox.calcTopFarLeft());
|
||||
QScriptValue center = vec3toScriptValue(filterData.engine, aaBox.calcCenter());
|
||||
QScriptValue boundingBoxDimensions = vec3toScriptValue(filterData.engine, aaBox.getDimensions());
|
||||
boundingBox.setProperty("brn", bottomRightNear);
|
||||
boundingBox.setProperty("tfl", topFarLeft);
|
||||
boundingBox.setProperty("center", center);
|
||||
boundingBox.setProperty("dimensions", boundingBoxDimensions);
|
||||
zoneValues.setProperty("boundingBox", boundingBox);
|
||||
}
|
||||
}
|
||||
|
||||
// If this is an add or delete, or original properties weren't requested
|
||||
// there won't be original properties in the args, but zone properties need
|
||||
// to be the fourth parameter, so we need to pad the args accordingly
|
||||
int EXPECTED_ARGS = 3;
|
||||
if (args.length() < EXPECTED_ARGS) {
|
||||
args << QScriptValue();
|
||||
}
|
||||
assert(args.length() == EXPECTED_ARGS); // we MUST have 3 args by now!
|
||||
args << zoneValues;
|
||||
}
|
||||
}
|
||||
|
||||
QScriptValue result = filterData.filterFn.call(_nullObjectForFilter, args);
|
||||
|
||||
if (filterData.uncaughtExceptions()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (result.isObject()){
|
||||
if (result.isObject()) {
|
||||
// make propertiesIn reflect the changes, for next filter...
|
||||
propertiesIn.copyFromScriptValue(result, false);
|
||||
|
||||
|
@ -86,6 +143,17 @@ bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& proper
|
|||
// Javascript objects are == only if they are the same object. To compare arbitrary values, we need to use JSON.
|
||||
auto out = QJsonValue::fromVariant(result.toVariant());
|
||||
wasChanged |= (in != out);
|
||||
} else if (result.isBool()) {
|
||||
|
||||
// if the filter returned false, then it's authoritative
|
||||
if (!result.toBool()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// otherwise, assume it wants to pass all properties
|
||||
propertiesOut = propertiesIn;
|
||||
wasChanged = false;
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -182,8 +250,8 @@ static bool hadUncaughtExceptions(QScriptEngine& engine, const QString& fileName
|
|||
void EntityEditFilters::scriptRequestFinished(EntityItemID entityID) {
|
||||
qDebug() << "script request completed for entity " << entityID;
|
||||
auto scriptRequest = qobject_cast<ResourceRequest*>(sender());
|
||||
const QString urlString = scriptRequest->getUrl().toString();
|
||||
if (scriptRequest && scriptRequest->getResult() == ResourceRequest::Success) {
|
||||
const QString urlString = scriptRequest->getUrl().toString();
|
||||
auto scriptContents = scriptRequest->getData();
|
||||
qInfo() << "Downloaded script:" << scriptContents;
|
||||
QScriptProgram program(scriptContents, urlString);
|
||||
|
@ -207,6 +275,7 @@ void EntityEditFilters::scriptRequestFinished(EntityItemID entityID) {
|
|||
entitiesObject.setProperty("ADD_FILTER_TYPE", EntityTree::FilterType::Add);
|
||||
entitiesObject.setProperty("EDIT_FILTER_TYPE", EntityTree::FilterType::Edit);
|
||||
entitiesObject.setProperty("PHYSICS_FILTER_TYPE", EntityTree::FilterType::Physics);
|
||||
entitiesObject.setProperty("DELETE_FILTER_TYPE", EntityTree::FilterType::Delete);
|
||||
global.setProperty("Entities", entitiesObject);
|
||||
filterData.filterFn = global.property("filter");
|
||||
if (!filterData.filterFn.isFunction()) {
|
||||
|
@ -214,8 +283,86 @@ void EntityEditFilters::scriptRequestFinished(EntityItemID entityID) {
|
|||
delete engine;
|
||||
filterData.rejectAll=true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// if the wantsToFilterEdit is a boolean evaluate as a boolean, otherwise assume true
|
||||
QScriptValue wantsToFilterAddValue = filterData.filterFn.property("wantsToFilterAdd");
|
||||
filterData.wantsToFilterAdd = wantsToFilterAddValue.isBool() ? wantsToFilterAddValue.toBool() : true;
|
||||
|
||||
// if the wantsToFilterEdit is a boolean evaluate as a boolean, otherwise assume true
|
||||
QScriptValue wantsToFilterEditValue = filterData.filterFn.property("wantsToFilterEdit");
|
||||
filterData.wantsToFilterEdit = wantsToFilterEditValue.isBool() ? wantsToFilterEditValue.toBool() : true;
|
||||
|
||||
// if the wantsToFilterPhysics is a boolean evaluate as a boolean, otherwise assume true
|
||||
QScriptValue wantsToFilterPhysicsValue = filterData.filterFn.property("wantsToFilterPhysics");
|
||||
filterData.wantsToFilterPhysics = wantsToFilterPhysicsValue.isBool() ? wantsToFilterPhysicsValue.toBool() : true;
|
||||
|
||||
// if the wantsToFilterDelete is a boolean evaluate as a boolean, otherwise assume false
|
||||
QScriptValue wantsToFilterDeleteValue = filterData.filterFn.property("wantsToFilterDelete");
|
||||
filterData.wantsToFilterDelete = wantsToFilterDeleteValue.isBool() ? wantsToFilterDeleteValue.toBool() : false;
|
||||
|
||||
// check to see if the filterFn has properties asking for Original props
|
||||
QScriptValue wantsOriginalPropertiesValue = filterData.filterFn.property("wantsOriginalProperties");
|
||||
// if the wantsOriginalProperties is a boolean, or a string, or list of strings, then evaluate as follows:
|
||||
// - boolean - true - include all original properties
|
||||
// false - no properties at all
|
||||
// - string - empty - no properties at all
|
||||
// any valid property - include just that property in the Original properties
|
||||
// - list of strings - include only those properties in the Original properties
|
||||
if (wantsOriginalPropertiesValue.isBool()) {
|
||||
filterData.wantsOriginalProperties = wantsOriginalPropertiesValue.toBool();
|
||||
} else if (wantsOriginalPropertiesValue.isString()) {
|
||||
auto stringValue = wantsOriginalPropertiesValue.toString();
|
||||
filterData.wantsOriginalProperties = !stringValue.isEmpty();
|
||||
if (filterData.wantsOriginalProperties) {
|
||||
EntityPropertyFlagsFromScriptValue(wantsOriginalPropertiesValue, filterData.includedOriginalProperties);
|
||||
}
|
||||
} else if (wantsOriginalPropertiesValue.isArray()) {
|
||||
EntityPropertyFlagsFromScriptValue(wantsOriginalPropertiesValue, filterData.includedOriginalProperties);
|
||||
filterData.wantsOriginalProperties = !filterData.includedOriginalProperties.isEmpty();
|
||||
}
|
||||
|
||||
// check to see if the filterFn has properties asking for Zone props
|
||||
QScriptValue wantsZonePropertiesValue = filterData.filterFn.property("wantsZoneProperties");
|
||||
// if the wantsZoneProperties is a boolean, or a string, or list of strings, then evaluate as follows:
|
||||
// - boolean - true - include all Zone properties
|
||||
// false - no properties at all
|
||||
// - string - empty - no properties at all
|
||||
// any valid property - include just that property in the Zone properties
|
||||
// - list of strings - include only those properties in the Zone properties
|
||||
if (wantsZonePropertiesValue.isBool()) {
|
||||
filterData.wantsZoneProperties = wantsZonePropertiesValue.toBool();
|
||||
filterData.wantsZoneBoundingBox = filterData.wantsZoneProperties; // include this too
|
||||
} else if (wantsZonePropertiesValue.isString()) {
|
||||
auto stringValue = wantsZonePropertiesValue.toString();
|
||||
filterData.wantsZoneProperties = !stringValue.isEmpty();
|
||||
if (filterData.wantsZoneProperties) {
|
||||
if (stringValue == "boundingBox") {
|
||||
filterData.wantsZoneBoundingBox = true;
|
||||
} else {
|
||||
EntityPropertyFlagsFromScriptValue(wantsZonePropertiesValue, filterData.includedZoneProperties);
|
||||
}
|
||||
}
|
||||
} else if (wantsZonePropertiesValue.isArray()) {
|
||||
auto length = wantsZonePropertiesValue.property("length").toInteger();
|
||||
for (int i = 0; i < length; i++) {
|
||||
auto stringValue = wantsZonePropertiesValue.property(i).toString();
|
||||
if (!stringValue.isEmpty()) {
|
||||
filterData.wantsZoneProperties = true;
|
||||
|
||||
// boundingBox is a special case since it's not a true EntityPropertyFlag, so we
|
||||
// need to detect it here.
|
||||
if (stringValue == "boundingBox") {
|
||||
filterData.wantsZoneBoundingBox = true;
|
||||
break; // we can break here, since there are no other special cases
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (filterData.wantsZoneProperties) {
|
||||
EntityPropertyFlagsFromScriptValue(wantsZonePropertiesValue, filterData.includedZoneProperties);
|
||||
}
|
||||
}
|
||||
|
||||
_lock.lockForWrite();
|
||||
_filterDataMap.insert(entityID, filterData);
|
||||
_lock.unlock();
|
||||
|
@ -227,6 +374,7 @@ void EntityEditFilters::scriptRequestFinished(EntityItemID entityID) {
|
|||
}
|
||||
}
|
||||
} else if (scriptRequest) {
|
||||
const QString urlString = scriptRequest->getUrl().toString();
|
||||
qCritical() << "Failed to download script at" << urlString;
|
||||
// See HTTPResourceRequest::onRequestFinished for interpretation of codes. For example, a 404 is code 6 and 403 is 3. A timeout is 2. Go figure.
|
||||
qCritical() << "ResourceRequest error was" << scriptRequest->getResult();
|
||||
|
|
|
@ -28,6 +28,18 @@ class EntityEditFilters : public QObject, public Dependency {
|
|||
public:
|
||||
struct FilterData {
|
||||
QScriptValue filterFn;
|
||||
bool wantsOriginalProperties { false };
|
||||
bool wantsZoneProperties { false };
|
||||
|
||||
bool wantsToFilterAdd { true };
|
||||
bool wantsToFilterEdit { true };
|
||||
bool wantsToFilterPhysics { true };
|
||||
bool wantsToFilterDelete { true };
|
||||
|
||||
EntityPropertyFlags includedOriginalProperties;
|
||||
EntityPropertyFlags includedZoneProperties;
|
||||
bool wantsZoneBoundingBox { false };
|
||||
|
||||
std::function<bool()> uncaughtExceptions;
|
||||
QScriptEngine* engine;
|
||||
bool rejectAll;
|
||||
|
@ -43,7 +55,7 @@ public:
|
|||
void removeFilter(EntityItemID entityID);
|
||||
|
||||
bool filter(glm::vec3& position, EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut, bool& wasChanged,
|
||||
EntityTree::FilterType filterType, EntityItemID& entityID);
|
||||
EntityTree::FilterType filterType, EntityItemID& entityID, EntityItemPointer& existingEntity);
|
||||
|
||||
signals:
|
||||
void filterAdded(EntityItemID id, bool success);
|
||||
|
|
|
@ -588,7 +588,10 @@ void EntityScriptingInterface::deleteEntity(QUuid id) {
|
|||
if (entity->getLocked()) {
|
||||
shouldDelete = false;
|
||||
} else {
|
||||
_entityTree->deleteEntity(entityID);
|
||||
// only delete local entities, server entities will round trip through the server filters
|
||||
if (entity->getClientOnly()) {
|
||||
_entityTree->deleteEntity(entityID);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1105,7 +1105,7 @@ bool EntityTree::filterProperties(EntityItemPointer& existingEntity, EntityItemP
|
|||
if (entityEditFilters) {
|
||||
auto position = existingEntity ? existingEntity->getWorldPosition() : propertiesIn.getPosition();
|
||||
auto entityID = existingEntity ? existingEntity->getEntityItemID() : EntityItemID();
|
||||
accepted = entityEditFilters->filter(position, propertiesIn, propertiesOut, wasChanged, filterType, entityID);
|
||||
accepted = entityEditFilters->filter(position, propertiesIn, propertiesOut, wasChanged, filterType, entityID, existingEntity);
|
||||
}
|
||||
|
||||
return accepted;
|
||||
|
@ -1868,6 +1868,36 @@ void EntityTree::forgetEntitiesDeletedBefore(quint64 sinceTime) {
|
|||
}
|
||||
|
||||
|
||||
bool EntityTree::shouldEraseEntity(EntityItemID entityID, const SharedNodePointer& sourceNode) {
|
||||
EntityItemPointer existingEntity;
|
||||
|
||||
auto startLookup = usecTimestampNow();
|
||||
existingEntity = findEntityByEntityItemID(entityID);
|
||||
auto endLookup = usecTimestampNow();
|
||||
_totalLookupTime += endLookup - startLookup;
|
||||
|
||||
auto startFilter = usecTimestampNow();
|
||||
FilterType filterType = FilterType::Delete;
|
||||
EntityItemProperties dummyProperties;
|
||||
bool wasChanged = false;
|
||||
|
||||
bool allowed = (sourceNode->isAllowedEditor()) || filterProperties(existingEntity, dummyProperties, dummyProperties, wasChanged, filterType);
|
||||
auto endFilter = usecTimestampNow();
|
||||
|
||||
_totalFilterTime += endFilter - startFilter;
|
||||
|
||||
if (allowed) {
|
||||
if (wantEditLogging() || wantTerseEditLogging()) {
|
||||
qCDebug(entities) << "User [" << sourceNode->getUUID() << "] deleting entity. ID:" << entityID;
|
||||
}
|
||||
} else if (wantEditLogging() || wantTerseEditLogging()) {
|
||||
qCDebug(entities) << "User [" << sourceNode->getUUID() << "] attempted to deleteentity. ID:" << entityID << " Filter rejected erase.";
|
||||
}
|
||||
|
||||
return allowed;
|
||||
}
|
||||
|
||||
|
||||
// TODO: consider consolidating processEraseMessageDetails() and processEraseMessage()
|
||||
int EntityTree::processEraseMessage(ReceivedMessage& message, const SharedNodePointer& sourceNode) {
|
||||
#ifdef EXTRA_ERASE_DEBUGGING
|
||||
|
@ -1895,12 +1925,10 @@ int EntityTree::processEraseMessage(ReceivedMessage& message, const SharedNodePo
|
|||
#endif
|
||||
|
||||
EntityItemID entityItemID(entityID);
|
||||
entityItemIDsToDelete << entityItemID;
|
||||
|
||||
if (wantEditLogging() || wantTerseEditLogging()) {
|
||||
qCDebug(entities) << "User [" << sourceNode->getUUID() << "] deleting entity. ID:" << entityItemID;
|
||||
if (shouldEraseEntity(entityID, sourceNode)) {
|
||||
entityItemIDsToDelete << entityItemID;
|
||||
}
|
||||
|
||||
}
|
||||
deleteEntities(entityItemIDsToDelete, true, true);
|
||||
}
|
||||
|
@ -1946,10 +1974,9 @@ int EntityTree::processEraseMessageDetails(const QByteArray& dataByteArray, cons
|
|||
#endif
|
||||
|
||||
EntityItemID entityItemID(entityID);
|
||||
entityItemIDsToDelete << entityItemID;
|
||||
|
||||
if (wantEditLogging() || wantTerseEditLogging()) {
|
||||
qCDebug(entities) << "User [" << sourceNode->getUUID() << "] deleting entity. ID:" << entityItemID;
|
||||
if (shouldEraseEntity(entityID, sourceNode)) {
|
||||
entityItemIDsToDelete << entityItemID;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -57,7 +57,8 @@ public:
|
|||
enum FilterType {
|
||||
Add,
|
||||
Edit,
|
||||
Physics
|
||||
Physics,
|
||||
Delete
|
||||
};
|
||||
EntityTree(bool shouldReaverage = false);
|
||||
virtual ~EntityTree();
|
||||
|
@ -193,6 +194,8 @@ public:
|
|||
|
||||
int processEraseMessage(ReceivedMessage& message, const SharedNodePointer& sourceNode);
|
||||
int processEraseMessageDetails(const QByteArray& buffer, const SharedNodePointer& sourceNode);
|
||||
bool shouldEraseEntity(EntityItemID entityID, const SharedNodePointer& sourceNode);
|
||||
|
||||
|
||||
EntityTreeElementPointer getContainingElement(const EntityItemID& entityItemID) /*const*/;
|
||||
void addEntityMapEntry(EntityItemPointer entity);
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// keep-in-zone-example.js
|
||||
//
|
||||
//
|
||||
// Created by Brad Hefta-Gaub to use Entities on Dec. 15, 2017
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// This sample entity edit filter script will keep any entity inside the bounding box of the zone this filter is applied to.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
function filter(properties, type, originalProperties, zoneProperties) {
|
||||
|
||||
var nearZero = 0.0001 * Math.random() + 0.001;
|
||||
|
||||
/* Clamp position changes to bounding box of zone.*/
|
||||
function clamp(val, min, max) {
|
||||
/* Random near-zero value used as "zero" to prevent two sequential updates from being
|
||||
exactly the same (which would cause them to be ignored) */
|
||||
if (val > max) {
|
||||
val = max - nearZero;
|
||||
} else if (val < min) {
|
||||
val = min + nearZero;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
if (properties.position) {
|
||||
properties.position.x = clamp(properties.position.x, zoneProperties.boundingBox.brn.x, zoneProperties.boundingBox.tfl.x);
|
||||
properties.position.y = clamp(properties.position.y, zoneProperties.boundingBox.brn.y, zoneProperties.boundingBox.tfl.y);
|
||||
properties.position.z = clamp(properties.position.z, zoneProperties.boundingBox.brn.z, zoneProperties.boundingBox.tfl.z);
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
filter.wantsOriginalProperties = true;
|
||||
filter.wantsZoneProperties = true;
|
||||
filter;
|
45
scripts/tutorials/entity_edit_filters/position-example.js
Normal file
45
scripts/tutorials/entity_edit_filters/position-example.js
Normal file
|
@ -0,0 +1,45 @@
|
|||
//
|
||||
// position-example.js
|
||||
//
|
||||
//
|
||||
// Created by Brad Hefta-Gaub to use Entities on Dec. 15, 2017
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// This sample entity edit filter script will only allow position to be changed by no more than 5 meters on any axis.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
function filter(properties, type, originalProperties) {
|
||||
|
||||
/* Clamp position changes.*/
|
||||
var maxChange = 5;
|
||||
|
||||
function clamp(val, min, max) {
|
||||
if (val > max) {
|
||||
val = max;
|
||||
} else if (val < min) {
|
||||
val = min;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
if (properties.position) {
|
||||
/* Random near-zero value used as "zero" to prevent two sequential updates from being
|
||||
exactly the same (which would cause them to be ignored) */
|
||||
var nearZero = 0.0001 * Math.random() + 0.001;
|
||||
var maxFudgeChange = (maxChange + nearZero);
|
||||
properties.position.x = clamp(properties.position.x, originalProperties.position.x
|
||||
- maxFudgeChange, originalProperties.position.x + maxFudgeChange);
|
||||
properties.position.y = clamp(properties.position.y, originalProperties.position.y
|
||||
- maxFudgeChange, originalProperties.position.y + maxFudgeChange);
|
||||
properties.position.z = clamp(properties.position.z, originalProperties.position.z
|
||||
- maxFudgeChange, originalProperties.position.z + maxFudgeChange);
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
filter.wantsOriginalProperties = "position";
|
||||
filter;
|
|
@ -0,0 +1,40 @@
|
|||
//
|
||||
// prevent-add-delete-or-edit-of-entities-with-name-of-zone.js
|
||||
//
|
||||
//
|
||||
// Created by Brad Hefta-Gaub to use Entities on Feb. 14, 2018
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// This sample entity edit filter script will get all edits, adds, physcis, and deletes, but will only block
|
||||
// deletes, and will pass through all others.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
function filter(properties, type, originalProperties, zoneProperties) {
|
||||
|
||||
// for adds, check the new properties, if the name is the same as the zone, prevent the add
|
||||
// note: this case tests the example where originalProperties will be unknown, since as an
|
||||
// add message, there is no existing entity to get proprties from. But we need to make sure
|
||||
// zoneProperties is still set in the correct 4th parameter.
|
||||
if (type == Entities.ADD_FILTER_TYPE) {
|
||||
if (properties.name == zoneProperties.name) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// for edits or deletes, check the "original" property for the entity against the zone's name
|
||||
if (originalProperties.name == zoneProperties.name) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
filter.wantsToFilterAdd = true; // do run on add
|
||||
filter.wantsToFilterEdit = true; // do not run on edit
|
||||
filter.wantsToFilterPhysics = false; // do not run on physics
|
||||
filter.wantsToFilterDelete = true; // do not run on delete
|
||||
filter.wantsOriginalProperties = "name";
|
||||
filter.wantsZoneProperties = "name";
|
||||
filter;
|
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// prevent-add-of-entities-named-bob-example.js
|
||||
//
|
||||
//
|
||||
// Created by Brad Hefta-Gaub to use Entities on Jan. 25, 2018
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// This sample entity edit filter script will get all edits, adds, physcis, and deletes, but will only block
|
||||
// deletes, and will pass through all others.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
function filter(properties, type) {
|
||||
if (properties.name == "bob") {
|
||||
return false;
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
filter.wantsToFilterAdd = true; // do run on add
|
||||
filter.wantsToFilterEdit = false; // do not run on edit
|
||||
filter.wantsToFilterPhysics = false; // do not run on physics
|
||||
filter.wantsToFilterDelete = false; // do not run on delete
|
||||
filter;
|
22
scripts/tutorials/entity_edit_filters/prevent-all-deletes.js
Normal file
22
scripts/tutorials/entity_edit_filters/prevent-all-deletes.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// prevent-all-deletes.js
|
||||
//
|
||||
//
|
||||
// Created by Brad Hefta-Gaub to use Entities on Jan. 25, 2018
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// This sample entity edit filter script will prevent deletes of any entities.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
function filter() {
|
||||
return false; // all deletes are blocked
|
||||
}
|
||||
|
||||
filter.wantsToFilterAdd = false; // don't run on adds
|
||||
filter.wantsToFilterEdit = false; // don't run on edits
|
||||
filter.wantsToFilterPhysics = false; // don't run on physics
|
||||
filter.wantsToFilterDelete = true; // do run on deletes
|
||||
filter;
|
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// prevent-delete-in-zone-example.js
|
||||
//
|
||||
//
|
||||
// Created by Brad Hefta-Gaub to use Entities on Jan. 25, 2018
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// This sample entity edit filter script will get all edits, adds, physcis, and deletes, but will only block
|
||||
// deletes, and will pass through all others.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
function filter(properties, type) {
|
||||
|
||||
if (type == Entities.DELETE_FILTER_TYPE) {
|
||||
return false;
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
filter.wantsToFilterDelete = true; // do run on deletes
|
||||
filter;
|
Loading…
Reference in a new issue