mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-06-04 09:30:13 +02:00
5172 lines
271 KiB
C++
5172 lines
271 KiB
C++
//
|
|
// EntityItemProperties.cpp
|
|
// libraries/entities/src
|
|
//
|
|
// Created by Brad Hefta-Gaub on 12/4/13.
|
|
// Copyright 2013 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
|
|
//
|
|
|
|
#include "EntityItemProperties.h"
|
|
|
|
#include <openssl/err.h>
|
|
#include <openssl/pem.h>
|
|
#include <openssl/x509.h>
|
|
#include <openssl/ecdsa.h>
|
|
|
|
#include <QDebug>
|
|
#include <QHash>
|
|
#include <QObject>
|
|
#include <QtCore/QJsonDocument>
|
|
#include <QtNetwork/QNetworkReply>
|
|
#include <QtNetwork/QNetworkRequest>
|
|
|
|
#include <NetworkAccessManager.h>
|
|
#include <ByteCountCoding.h>
|
|
#include <GLMHelpers.h>
|
|
#include <RegisteredMetaTypes.h>
|
|
#include <Extents.h>
|
|
#include <VariantMapToScriptValue.h>
|
|
|
|
#include "EntitiesLogging.h"
|
|
#include "EntityItem.h"
|
|
#include "ModelEntityItem.h"
|
|
#include "PolyLineEntityItem.h"
|
|
|
|
AnimationPropertyGroup EntityItemProperties::_staticAnimation;
|
|
SkyboxPropertyGroup EntityItemProperties::_staticSkybox;
|
|
HazePropertyGroup EntityItemProperties::_staticHaze;
|
|
BloomPropertyGroup EntityItemProperties::_staticBloom;
|
|
KeyLightPropertyGroup EntityItemProperties::_staticKeyLight;
|
|
AmbientLightPropertyGroup EntityItemProperties::_staticAmbientLight;
|
|
GrabPropertyGroup EntityItemProperties::_staticGrab;
|
|
PulsePropertyGroup EntityItemProperties::_staticPulse;
|
|
RingGizmoPropertyGroup EntityItemProperties::_staticRing;
|
|
|
|
EntityPropertyList PROP_LAST_ITEM = (EntityPropertyList)(PROP_AFTER_LAST_ITEM - 1);
|
|
|
|
EntityItemProperties::EntityItemProperties(EntityPropertyFlags desiredProperties) :
|
|
_id(UNKNOWN_ENTITY_ID),
|
|
_idSet(false),
|
|
_lastEdited(0),
|
|
_type(EntityTypes::Unknown),
|
|
|
|
_defaultSettings(true),
|
|
_naturalDimensions(1.0f, 1.0f, 1.0f),
|
|
_naturalPosition(0.0f, 0.0f, 0.0f),
|
|
_desiredProperties(desiredProperties)
|
|
{
|
|
|
|
}
|
|
|
|
void EntityItemProperties::calculateNaturalPosition(const vec3& min, const vec3& max) {
|
|
vec3 halfDimension = (max - min) / 2.0f;
|
|
_naturalPosition = max - halfDimension;
|
|
}
|
|
|
|
void EntityItemProperties::debugDump() const {
|
|
qCDebug(entities) << "EntityItemProperties...";
|
|
qCDebug(entities) << " _type=" << EntityTypes::getEntityTypeName(_type);
|
|
qCDebug(entities) << " _id=" << _id;
|
|
qCDebug(entities) << " _idSet=" << _idSet;
|
|
qCDebug(entities) << " _position=" << _position.x << "," << _position.y << "," << _position.z;
|
|
qCDebug(entities) << " _dimensions=" << getDimensions();
|
|
qCDebug(entities) << " _modelURL=" << _modelURL;
|
|
qCDebug(entities) << " _compoundShapeURL=" << _compoundShapeURL;
|
|
|
|
getAnimation().debugDump();
|
|
getSkybox().debugDump();
|
|
getHaze().debugDump();
|
|
getKeyLight().debugDump();
|
|
getAmbientLight().debugDump();
|
|
getBloom().debugDump();
|
|
getGrab().debugDump();
|
|
|
|
qCDebug(entities) << " changed properties...";
|
|
EntityPropertyFlags props = getChangedProperties();
|
|
props.debugDumpBits();
|
|
}
|
|
|
|
void EntityItemProperties::setLastEdited(quint64 usecTime) {
|
|
_lastEdited = usecTime > _created ? usecTime : _created;
|
|
}
|
|
|
|
bool EntityItemProperties::constructFromBuffer(const unsigned char* data, int dataLength) {
|
|
ReadBitstreamToTreeParams args;
|
|
EntityItemPointer tempEntity = EntityTypes::constructEntityItem(data, dataLength);
|
|
if (!tempEntity) {
|
|
return false;
|
|
}
|
|
tempEntity->readEntityDataFromBuffer(data, dataLength, args);
|
|
(*this) = tempEntity->getProperties();
|
|
return true;
|
|
}
|
|
|
|
inline void addShapeType(QHash<QString, ShapeType>& lookup, ShapeType type) { lookup[ShapeInfo::getNameForShapeType(type)] = type; }
|
|
QHash<QString, ShapeType> stringToShapeTypeLookup = [] {
|
|
QHash<QString, ShapeType> toReturn;
|
|
addShapeType(toReturn, SHAPE_TYPE_NONE);
|
|
addShapeType(toReturn, SHAPE_TYPE_BOX);
|
|
addShapeType(toReturn, SHAPE_TYPE_SPHERE);
|
|
addShapeType(toReturn, SHAPE_TYPE_CAPSULE_X);
|
|
addShapeType(toReturn, SHAPE_TYPE_CAPSULE_Y);
|
|
addShapeType(toReturn, SHAPE_TYPE_CAPSULE_Z);
|
|
addShapeType(toReturn, SHAPE_TYPE_CYLINDER_X);
|
|
addShapeType(toReturn, SHAPE_TYPE_CYLINDER_Y);
|
|
addShapeType(toReturn, SHAPE_TYPE_CYLINDER_Z);
|
|
addShapeType(toReturn, SHAPE_TYPE_HULL);
|
|
addShapeType(toReturn, SHAPE_TYPE_PLANE);
|
|
addShapeType(toReturn, SHAPE_TYPE_COMPOUND);
|
|
addShapeType(toReturn, SHAPE_TYPE_SIMPLE_HULL);
|
|
addShapeType(toReturn, SHAPE_TYPE_SIMPLE_COMPOUND);
|
|
addShapeType(toReturn, SHAPE_TYPE_STATIC_MESH);
|
|
addShapeType(toReturn, SHAPE_TYPE_ELLIPSOID);
|
|
addShapeType(toReturn, SHAPE_TYPE_CIRCLE);
|
|
return toReturn;
|
|
}();
|
|
QString EntityItemProperties::getShapeTypeAsString() const { return ShapeInfo::getNameForShapeType(_shapeType); }
|
|
void EntityItemProperties::setShapeTypeFromString(const QString& shapeName) {
|
|
auto shapeTypeItr = stringToShapeTypeLookup.find(shapeName.toLower());
|
|
if (shapeTypeItr != stringToShapeTypeLookup.end()) {
|
|
_shapeType = shapeTypeItr.value();
|
|
_shapeTypeChanged = true;
|
|
}
|
|
}
|
|
|
|
inline void addMaterialMappingMode(QHash<QString, MaterialMappingMode>& lookup, MaterialMappingMode mode) { lookup[MaterialMappingModeHelpers::getNameForMaterialMappingMode(mode)] = mode; }
|
|
const QHash<QString, MaterialMappingMode> stringToMaterialMappingModeLookup = [] {
|
|
QHash<QString, MaterialMappingMode> toReturn;
|
|
addMaterialMappingMode(toReturn, UV);
|
|
addMaterialMappingMode(toReturn, PROJECTED);
|
|
return toReturn;
|
|
}();
|
|
QString EntityItemProperties::getMaterialMappingModeAsString() const { return MaterialMappingModeHelpers::getNameForMaterialMappingMode(_materialMappingMode); }
|
|
void EntityItemProperties::setMaterialMappingModeFromString(const QString& materialMappingMode) {
|
|
auto materialMappingModeItr = stringToMaterialMappingModeLookup.find(materialMappingMode.toLower());
|
|
if (materialMappingModeItr != stringToMaterialMappingModeLookup.end()) {
|
|
_materialMappingMode = materialMappingModeItr.value();
|
|
_materialMappingModeChanged = true;
|
|
}
|
|
}
|
|
|
|
inline void addBillboardMode(QHash<QString, BillboardMode>& lookup, BillboardMode mode) { lookup[BillboardModeHelpers::getNameForBillboardMode(mode)] = mode; }
|
|
const QHash<QString, BillboardMode> stringToBillboardModeLookup = [] {
|
|
QHash<QString, BillboardMode> toReturn;
|
|
addBillboardMode(toReturn, BillboardMode::NONE);
|
|
addBillboardMode(toReturn, BillboardMode::YAW);
|
|
addBillboardMode(toReturn, BillboardMode::FULL);
|
|
return toReturn;
|
|
}();
|
|
QString EntityItemProperties::getBillboardModeAsString() const { return BillboardModeHelpers::getNameForBillboardMode(_billboardMode); }
|
|
void EntityItemProperties::setBillboardModeFromString(const QString& billboardMode) {
|
|
auto billboardModeItr = stringToBillboardModeLookup.find(billboardMode.toLower());
|
|
if (billboardModeItr != stringToBillboardModeLookup.end()) {
|
|
_billboardMode = billboardModeItr.value();
|
|
_billboardModeChanged = true;
|
|
}
|
|
}
|
|
|
|
inline void addRenderLayer(QHash<QString, RenderLayer>& lookup, RenderLayer mode) { lookup[RenderLayerHelpers::getNameForRenderLayer(mode)] = mode; }
|
|
const QHash<QString, RenderLayer> stringToRenderLayerLookup = [] {
|
|
QHash<QString, RenderLayer> toReturn;
|
|
addRenderLayer(toReturn, RenderLayer::WORLD);
|
|
addRenderLayer(toReturn, RenderLayer::FRONT);
|
|
addRenderLayer(toReturn, RenderLayer::HUD);
|
|
return toReturn;
|
|
}();
|
|
QString EntityItemProperties::getRenderLayerAsString() const { return RenderLayerHelpers::getNameForRenderLayer(_renderLayer); }
|
|
void EntityItemProperties::setRenderLayerFromString(const QString& renderLayer) {
|
|
auto renderLayerItr = stringToRenderLayerLookup.find(renderLayer.toLower());
|
|
if (renderLayerItr != stringToRenderLayerLookup.end()) {
|
|
_renderLayer = renderLayerItr.value();
|
|
_renderLayerChanged = true;
|
|
}
|
|
}
|
|
|
|
inline void addPrimitiveMode(QHash<QString, PrimitiveMode>& lookup, PrimitiveMode mode) { lookup[PrimitiveModeHelpers::getNameForPrimitiveMode(mode)] = mode; }
|
|
const QHash<QString, PrimitiveMode> stringToPrimitiveModeLookup = [] {
|
|
QHash<QString, PrimitiveMode> toReturn;
|
|
addPrimitiveMode(toReturn, PrimitiveMode::SOLID);
|
|
addPrimitiveMode(toReturn, PrimitiveMode::LINES);
|
|
return toReturn;
|
|
}();
|
|
QString EntityItemProperties::getPrimitiveModeAsString() const { return PrimitiveModeHelpers::getNameForPrimitiveMode(_primitiveMode); }
|
|
void EntityItemProperties::setPrimitiveModeFromString(const QString& primitiveMode) {
|
|
auto primitiveModeItr = stringToPrimitiveModeLookup.find(primitiveMode.toLower());
|
|
if (primitiveModeItr != stringToPrimitiveModeLookup.end()) {
|
|
_primitiveMode = primitiveModeItr.value();
|
|
_primitiveModeChanged = true;
|
|
}
|
|
}
|
|
|
|
inline void addWebInputMode(QHash<QString, WebInputMode>& lookup, WebInputMode mode) { lookup[WebInputModeHelpers::getNameForWebInputMode(mode)] = mode; }
|
|
const QHash<QString, WebInputMode> stringToWebInputModeLookup = [] {
|
|
QHash<QString, WebInputMode> toReturn;
|
|
addWebInputMode(toReturn, WebInputMode::TOUCH);
|
|
addWebInputMode(toReturn, WebInputMode::MOUSE);
|
|
return toReturn;
|
|
}();
|
|
QString EntityItemProperties::getInputModeAsString() const { return WebInputModeHelpers::getNameForWebInputMode(_inputMode); }
|
|
void EntityItemProperties::setInputModeFromString(const QString& webInputMode) {
|
|
auto webInputModeItr = stringToWebInputModeLookup.find(webInputMode.toLower());
|
|
if (webInputModeItr != stringToWebInputModeLookup.end()) {
|
|
_inputMode = webInputModeItr.value();
|
|
_inputModeChanged = true;
|
|
}
|
|
}
|
|
|
|
inline void addGizmoType(QHash<QString, GizmoType>& lookup, GizmoType mode) { lookup[GizmoTypeHelpers::getNameForGizmoType(mode)] = mode; }
|
|
const QHash<QString, GizmoType> stringToGizmoTypeLookup = [] {
|
|
QHash<QString, GizmoType> toReturn;
|
|
addGizmoType(toReturn, GizmoType::RING);
|
|
return toReturn;
|
|
}();
|
|
QString EntityItemProperties::getGizmoTypeAsString() const { return GizmoTypeHelpers::getNameForGizmoType(_gizmoType); }
|
|
void EntityItemProperties::setGizmoTypeFromString(const QString& gizmoType) {
|
|
auto gizmoTypeItr = stringToGizmoTypeLookup.find(gizmoType.toLower());
|
|
if (gizmoTypeItr != stringToGizmoTypeLookup.end()) {
|
|
_gizmoType = gizmoTypeItr.value();
|
|
_gizmoTypeChanged = true;
|
|
}
|
|
}
|
|
|
|
inline void addComponentMode(QHash<QString, ComponentMode>& lookup, ComponentMode mode) { lookup[ComponentModeHelpers::getNameForComponentMode(mode)] = mode; }
|
|
const QHash<QString, ComponentMode> stringToComponentMode = [] {
|
|
QHash<QString, ComponentMode> toReturn;
|
|
addComponentMode(toReturn, ComponentMode::COMPONENT_MODE_INHERIT);
|
|
addComponentMode(toReturn, ComponentMode::COMPONENT_MODE_DISABLED);
|
|
addComponentMode(toReturn, ComponentMode::COMPONENT_MODE_ENABLED);
|
|
return toReturn;
|
|
}();
|
|
QString EntityItemProperties::getComponentModeAsString(uint32_t mode) { return ComponentModeHelpers::getNameForComponentMode((ComponentMode)mode); }
|
|
QString EntityItemProperties::getSkyboxModeAsString() const { return getComponentModeAsString(_skyboxMode); }
|
|
QString EntityItemProperties::getKeyLightModeAsString() const { return getComponentModeAsString(_keyLightMode); }
|
|
QString EntityItemProperties::getAmbientLightModeAsString() const { return getComponentModeAsString(_ambientLightMode); }
|
|
QString EntityItemProperties::getHazeModeAsString() const { return getComponentModeAsString(_hazeMode); }
|
|
QString EntityItemProperties::getBloomModeAsString() const { return getComponentModeAsString(_bloomMode); }
|
|
void EntityItemProperties::setSkyboxModeFromString(const QString& mode) {
|
|
auto modeItr = stringToComponentMode.find(mode.toLower());
|
|
if (modeItr != stringToComponentMode.end()) {
|
|
_skyboxMode = modeItr.value();
|
|
_skyboxModeChanged = true;
|
|
}
|
|
}
|
|
void EntityItemProperties::setKeyLightModeFromString(const QString& mode) {
|
|
auto modeItr = stringToComponentMode.find(mode.toLower());
|
|
if (modeItr != stringToComponentMode.end()) {
|
|
_keyLightMode = modeItr.value();
|
|
_keyLightModeChanged = true;
|
|
}
|
|
}
|
|
void EntityItemProperties::setAmbientLightModeFromString(const QString& mode) {
|
|
auto modeItr = stringToComponentMode.find(mode.toLower());
|
|
if (modeItr != stringToComponentMode.end()) {
|
|
_ambientLightMode = modeItr.value();
|
|
_ambientLightModeChanged = true;
|
|
}
|
|
}
|
|
void EntityItemProperties::setHazeModeFromString(const QString& mode) {
|
|
auto modeItr = stringToComponentMode.find(mode.toLower());
|
|
if (modeItr != stringToComponentMode.end()) {
|
|
_hazeMode = modeItr.value();
|
|
_hazeModeChanged = true;
|
|
}
|
|
}
|
|
void EntityItemProperties::setBloomModeFromString(const QString& mode) {
|
|
auto modeItr = stringToComponentMode.find(mode.toLower());
|
|
if (modeItr != stringToComponentMode.end()) {
|
|
_bloomMode = modeItr.value();
|
|
_bloomModeChanged = true;
|
|
}
|
|
}
|
|
|
|
inline void addAvatarPriorityMode(QHash<QString, AvatarPriorityMode>& lookup, AvatarPriorityMode mode) { lookup[AvatarPriorityModeHelpers::getNameForAvatarPriorityMode(mode)] = mode; }
|
|
const QHash<QString, AvatarPriorityMode> stringToAvatarPriority = [] {
|
|
QHash<QString, AvatarPriorityMode> toReturn;
|
|
addAvatarPriorityMode(toReturn, AvatarPriorityMode::AVATAR_PRIORITY_INHERIT);
|
|
addAvatarPriorityMode(toReturn, AvatarPriorityMode::AVATAR_PRIORITY_CROWD);
|
|
addAvatarPriorityMode(toReturn, AvatarPriorityMode::AVATAR_PRIORITY_HERO);
|
|
return toReturn;
|
|
}();
|
|
QString EntityItemProperties::getAvatarPriorityAsString() const { return AvatarPriorityModeHelpers::getNameForAvatarPriorityMode((AvatarPriorityMode)_avatarPriority); }
|
|
void EntityItemProperties::setAvatarPriorityFromString(const QString& mode) {
|
|
auto modeItr = stringToAvatarPriority.find(mode.toLower());
|
|
if (modeItr != stringToAvatarPriority.end()) {
|
|
_avatarPriority = modeItr.value();
|
|
_avatarPriorityChanged = true;
|
|
}
|
|
}
|
|
|
|
QString EntityItemProperties::getScreenshareAsString() const { return getComponentModeAsString(_screenshare); }
|
|
void EntityItemProperties::setScreenshareFromString(const QString& mode) {
|
|
auto modeItr = stringToComponentMode.find(mode.toLower());
|
|
if (modeItr != stringToComponentMode.end()) {
|
|
_screenshare = modeItr.value();
|
|
_screenshareChanged = true;
|
|
}
|
|
}
|
|
|
|
|
|
inline void addTextEffect(QHash<QString, TextEffect>& lookup, TextEffect effect) { lookup[TextEffectHelpers::getNameForTextEffect(effect)] = effect; }
|
|
const QHash<QString, TextEffect> stringToTextEffectLookup = [] {
|
|
QHash<QString, TextEffect> toReturn;
|
|
addTextEffect(toReturn, TextEffect::NO_EFFECT);
|
|
addTextEffect(toReturn, TextEffect::OUTLINE_EFFECT);
|
|
addTextEffect(toReturn, TextEffect::OUTLINE_WITH_FILL_EFFECT);
|
|
addTextEffect(toReturn, TextEffect::SHADOW_EFFECT);
|
|
return toReturn;
|
|
}();
|
|
QString EntityItemProperties::getTextEffectAsString() const { return TextEffectHelpers::getNameForTextEffect(_textEffect); }
|
|
void EntityItemProperties::setTextEffectFromString(const QString& effect) {
|
|
auto textEffectItr = stringToTextEffectLookup.find(effect.toLower());
|
|
if (textEffectItr != stringToTextEffectLookup.end()) {
|
|
_textEffect = textEffectItr.value();
|
|
_textEffectChanged = true;
|
|
}
|
|
}
|
|
|
|
QString getCollisionGroupAsString(uint16_t group) {
|
|
switch (group) {
|
|
case USER_COLLISION_GROUP_DYNAMIC:
|
|
return "dynamic";
|
|
case USER_COLLISION_GROUP_STATIC:
|
|
return "static";
|
|
case USER_COLLISION_GROUP_KINEMATIC:
|
|
return "kinematic";
|
|
case USER_COLLISION_GROUP_MY_AVATAR:
|
|
return "myAvatar";
|
|
case USER_COLLISION_GROUP_OTHER_AVATAR:
|
|
return "otherAvatar";
|
|
};
|
|
return "";
|
|
}
|
|
|
|
uint16_t getCollisionGroupAsBitMask(const QStringRef& name) {
|
|
if (0 == name.compare(QString("dynamic"))) {
|
|
return USER_COLLISION_GROUP_DYNAMIC;
|
|
} else if (0 == name.compare(QString("static"))) {
|
|
return USER_COLLISION_GROUP_STATIC;
|
|
} else if (0 == name.compare(QString("kinematic"))) {
|
|
return USER_COLLISION_GROUP_KINEMATIC;
|
|
} else if (0 == name.compare(QString("myAvatar"))) {
|
|
return USER_COLLISION_GROUP_MY_AVATAR;
|
|
} else if (0 == name.compare(QString("otherAvatar"))) {
|
|
return USER_COLLISION_GROUP_OTHER_AVATAR;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
QString EntityItemProperties::getCollisionMaskAsString() const {
|
|
QString maskString("");
|
|
for (int i = 0; i < NUM_USER_COLLISION_GROUPS; ++i) {
|
|
uint16_t group = 0x0001 << i;
|
|
if (group & _collisionMask) {
|
|
maskString.append(getCollisionGroupAsString(group));
|
|
maskString.append(',');
|
|
}
|
|
}
|
|
return maskString;
|
|
}
|
|
|
|
void EntityItemProperties::setCollisionMaskFromString(const QString& maskString) {
|
|
QVector<QStringRef> groups = maskString.splitRef(',');
|
|
uint16_t mask = 0x0000;
|
|
for (auto groupName : groups) {
|
|
mask |= getCollisionGroupAsBitMask(groupName);
|
|
}
|
|
_collisionMask = mask;
|
|
_collisionMaskChanged = true;
|
|
}
|
|
|
|
QString EntityItemProperties::getEntityHostTypeAsString() const {
|
|
switch (_entityHostType) {
|
|
case entity::HostType::DOMAIN:
|
|
return "domain";
|
|
case entity::HostType::AVATAR:
|
|
return "avatar";
|
|
case entity::HostType::LOCAL:
|
|
return "local";
|
|
default:
|
|
return "";
|
|
}
|
|
}
|
|
|
|
void EntityItemProperties::setEntityHostTypeFromString(const QString& entityHostType) {
|
|
if (entityHostType == "domain") {
|
|
_entityHostType = entity::HostType::DOMAIN;
|
|
} else if (entityHostType == "avatar") {
|
|
_entityHostType = entity::HostType::AVATAR;
|
|
} else if (entityHostType == "local") {
|
|
_entityHostType = entity::HostType::LOCAL;
|
|
}
|
|
}
|
|
|
|
EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|
EntityPropertyFlags changedProperties;
|
|
|
|
// Core
|
|
CHECK_PROPERTY_CHANGE(PROP_SIMULATION_OWNER, simulationOwner);
|
|
CHECK_PROPERTY_CHANGE(PROP_PARENT_ID, parentID);
|
|
CHECK_PROPERTY_CHANGE(PROP_PARENT_JOINT_INDEX, parentJointIndex);
|
|
CHECK_PROPERTY_CHANGE(PROP_VISIBLE, visible);
|
|
CHECK_PROPERTY_CHANGE(PROP_NAME, name);
|
|
CHECK_PROPERTY_CHANGE(PROP_LOCKED, locked);
|
|
CHECK_PROPERTY_CHANGE(PROP_USER_DATA, userData);
|
|
CHECK_PROPERTY_CHANGE(PROP_PRIVATE_USER_DATA, privateUserData);
|
|
CHECK_PROPERTY_CHANGE(PROP_HREF, href);
|
|
CHECK_PROPERTY_CHANGE(PROP_DESCRIPTION, description);
|
|
CHECK_PROPERTY_CHANGE(PROP_POSITION, position);
|
|
CHECK_PROPERTY_CHANGE(PROP_DIMENSIONS, dimensions);
|
|
CHECK_PROPERTY_CHANGE(PROP_ROTATION, rotation);
|
|
CHECK_PROPERTY_CHANGE(PROP_REGISTRATION_POINT, registrationPoint);
|
|
CHECK_PROPERTY_CHANGE(PROP_CREATED, created);
|
|
CHECK_PROPERTY_CHANGE(PROP_LAST_EDITED_BY, lastEditedBy);
|
|
CHECK_PROPERTY_CHANGE(PROP_ENTITY_HOST_TYPE, entityHostType);
|
|
CHECK_PROPERTY_CHANGE(PROP_OWNING_AVATAR_ID, owningAvatarID);
|
|
CHECK_PROPERTY_CHANGE(PROP_QUERY_AA_CUBE, queryAACube);
|
|
CHECK_PROPERTY_CHANGE(PROP_CAN_CAST_SHADOW, canCastShadow);
|
|
CHECK_PROPERTY_CHANGE(PROP_VISIBLE_IN_SECONDARY_CAMERA, isVisibleInSecondaryCamera);
|
|
CHECK_PROPERTY_CHANGE(PROP_RENDER_LAYER, renderLayer);
|
|
CHECK_PROPERTY_CHANGE(PROP_PRIMITIVE_MODE, primitiveMode);
|
|
CHECK_PROPERTY_CHANGE(PROP_IGNORE_PICK_INTERSECTION, ignorePickIntersection);
|
|
CHECK_PROPERTY_CHANGE(PROP_RENDER_WITH_ZONES, renderWithZones);
|
|
changedProperties += _grab.getChangedProperties();
|
|
|
|
// Physics
|
|
CHECK_PROPERTY_CHANGE(PROP_DENSITY, density);
|
|
CHECK_PROPERTY_CHANGE(PROP_VELOCITY, velocity);
|
|
CHECK_PROPERTY_CHANGE(PROP_ANGULAR_VELOCITY, angularVelocity);
|
|
CHECK_PROPERTY_CHANGE(PROP_GRAVITY, gravity);
|
|
CHECK_PROPERTY_CHANGE(PROP_ACCELERATION, acceleration);
|
|
CHECK_PROPERTY_CHANGE(PROP_DAMPING, damping);
|
|
CHECK_PROPERTY_CHANGE(PROP_ANGULAR_DAMPING, angularDamping);
|
|
CHECK_PROPERTY_CHANGE(PROP_RESTITUTION, restitution);
|
|
CHECK_PROPERTY_CHANGE(PROP_FRICTION, friction);
|
|
CHECK_PROPERTY_CHANGE(PROP_LIFETIME, lifetime);
|
|
CHECK_PROPERTY_CHANGE(PROP_COLLISIONLESS, collisionless);
|
|
CHECK_PROPERTY_CHANGE(PROP_COLLISION_MASK, collisionMask);
|
|
CHECK_PROPERTY_CHANGE(PROP_DYNAMIC, dynamic);
|
|
CHECK_PROPERTY_CHANGE(PROP_COLLISION_SOUND_URL, collisionSoundURL);
|
|
CHECK_PROPERTY_CHANGE(PROP_ACTION_DATA, actionData);
|
|
|
|
// Cloning
|
|
CHECK_PROPERTY_CHANGE(PROP_CLONEABLE, cloneable);
|
|
CHECK_PROPERTY_CHANGE(PROP_CLONE_LIFETIME, cloneLifetime);
|
|
CHECK_PROPERTY_CHANGE(PROP_CLONE_LIMIT, cloneLimit);
|
|
CHECK_PROPERTY_CHANGE(PROP_CLONE_DYNAMIC, cloneDynamic);
|
|
CHECK_PROPERTY_CHANGE(PROP_CLONE_AVATAR_ENTITY, cloneAvatarEntity);
|
|
CHECK_PROPERTY_CHANGE(PROP_CLONE_ORIGIN_ID, cloneOriginID);
|
|
|
|
// Scripts
|
|
CHECK_PROPERTY_CHANGE(PROP_SCRIPT, script);
|
|
CHECK_PROPERTY_CHANGE(PROP_SCRIPT_TIMESTAMP, scriptTimestamp);
|
|
CHECK_PROPERTY_CHANGE(PROP_SERVER_SCRIPTS, serverScripts);
|
|
|
|
// Certifiable Properties
|
|
CHECK_PROPERTY_CHANGE(PROP_ITEM_NAME, itemName);
|
|
CHECK_PROPERTY_CHANGE(PROP_ITEM_DESCRIPTION, itemDescription);
|
|
CHECK_PROPERTY_CHANGE(PROP_ITEM_CATEGORIES, itemCategories);
|
|
CHECK_PROPERTY_CHANGE(PROP_ITEM_ARTIST, itemArtist);
|
|
CHECK_PROPERTY_CHANGE(PROP_ITEM_LICENSE, itemLicense);
|
|
CHECK_PROPERTY_CHANGE(PROP_LIMITED_RUN, limitedRun);
|
|
CHECK_PROPERTY_CHANGE(PROP_MARKETPLACE_ID, marketplaceID);
|
|
CHECK_PROPERTY_CHANGE(PROP_EDITION_NUMBER, editionNumber);
|
|
CHECK_PROPERTY_CHANGE(PROP_ENTITY_INSTANCE_NUMBER, entityInstanceNumber);
|
|
CHECK_PROPERTY_CHANGE(PROP_CERTIFICATE_ID, certificateID);
|
|
CHECK_PROPERTY_CHANGE(PROP_CERTIFICATE_TYPE, certificateType);
|
|
CHECK_PROPERTY_CHANGE(PROP_STATIC_CERTIFICATE_VERSION, staticCertificateVersion);
|
|
|
|
// Location data for scripts
|
|
CHECK_PROPERTY_CHANGE(PROP_LOCAL_POSITION, localPosition);
|
|
CHECK_PROPERTY_CHANGE(PROP_LOCAL_ROTATION, localRotation);
|
|
CHECK_PROPERTY_CHANGE(PROP_LOCAL_VELOCITY, localVelocity);
|
|
CHECK_PROPERTY_CHANGE(PROP_LOCAL_ANGULAR_VELOCITY, localAngularVelocity);
|
|
CHECK_PROPERTY_CHANGE(PROP_LOCAL_DIMENSIONS, localDimensions);
|
|
|
|
// Common
|
|
CHECK_PROPERTY_CHANGE(PROP_SHAPE_TYPE, shapeType);
|
|
CHECK_PROPERTY_CHANGE(PROP_COMPOUND_SHAPE_URL, compoundShapeURL);
|
|
CHECK_PROPERTY_CHANGE(PROP_COLOR, color);
|
|
CHECK_PROPERTY_CHANGE(PROP_ALPHA, alpha);
|
|
changedProperties += _pulse.getChangedProperties();
|
|
CHECK_PROPERTY_CHANGE(PROP_TEXTURES, textures);
|
|
CHECK_PROPERTY_CHANGE(PROP_BILLBOARD_MODE, billboardMode);
|
|
|
|
// Particles
|
|
CHECK_PROPERTY_CHANGE(PROP_MAX_PARTICLES, maxParticles);
|
|
CHECK_PROPERTY_CHANGE(PROP_LIFESPAN, lifespan);
|
|
CHECK_PROPERTY_CHANGE(PROP_EMITTING_PARTICLES, isEmitting);
|
|
CHECK_PROPERTY_CHANGE(PROP_EMIT_RATE, emitRate);
|
|
CHECK_PROPERTY_CHANGE(PROP_EMIT_SPEED, emitSpeed);
|
|
CHECK_PROPERTY_CHANGE(PROP_SPEED_SPREAD, speedSpread);
|
|
CHECK_PROPERTY_CHANGE(PROP_EMIT_ORIENTATION, emitOrientation);
|
|
CHECK_PROPERTY_CHANGE(PROP_EMIT_DIMENSIONS, emitDimensions);
|
|
CHECK_PROPERTY_CHANGE(PROP_EMIT_RADIUS_START, emitRadiusStart);
|
|
CHECK_PROPERTY_CHANGE(PROP_POLAR_START, polarStart);
|
|
CHECK_PROPERTY_CHANGE(PROP_POLAR_FINISH, polarFinish);
|
|
CHECK_PROPERTY_CHANGE(PROP_AZIMUTH_START, azimuthStart);
|
|
CHECK_PROPERTY_CHANGE(PROP_AZIMUTH_FINISH, azimuthFinish);
|
|
CHECK_PROPERTY_CHANGE(PROP_EMIT_ACCELERATION, emitAcceleration);
|
|
CHECK_PROPERTY_CHANGE(PROP_ACCELERATION_SPREAD, accelerationSpread);
|
|
CHECK_PROPERTY_CHANGE(PROP_PARTICLE_RADIUS, particleRadius);
|
|
CHECK_PROPERTY_CHANGE(PROP_RADIUS_SPREAD, radiusSpread);
|
|
CHECK_PROPERTY_CHANGE(PROP_RADIUS_START, radiusStart);
|
|
CHECK_PROPERTY_CHANGE(PROP_RADIUS_FINISH, radiusFinish);
|
|
CHECK_PROPERTY_CHANGE(PROP_COLOR_SPREAD, colorSpread);
|
|
CHECK_PROPERTY_CHANGE(PROP_COLOR_START, colorStart);
|
|
CHECK_PROPERTY_CHANGE(PROP_COLOR_FINISH, colorFinish);
|
|
CHECK_PROPERTY_CHANGE(PROP_ALPHA_SPREAD, alphaSpread);
|
|
CHECK_PROPERTY_CHANGE(PROP_ALPHA_START, alphaStart);
|
|
CHECK_PROPERTY_CHANGE(PROP_ALPHA_FINISH, alphaFinish);
|
|
CHECK_PROPERTY_CHANGE(PROP_EMITTER_SHOULD_TRAIL, emitterShouldTrail);
|
|
CHECK_PROPERTY_CHANGE(PROP_PARTICLE_SPIN, particleSpin);
|
|
CHECK_PROPERTY_CHANGE(PROP_SPIN_SPREAD, spinSpread);
|
|
CHECK_PROPERTY_CHANGE(PROP_SPIN_START, spinStart);
|
|
CHECK_PROPERTY_CHANGE(PROP_SPIN_FINISH, spinFinish);
|
|
CHECK_PROPERTY_CHANGE(PROP_PARTICLE_ROTATE_WITH_ENTITY, rotateWithEntity);
|
|
|
|
// Model
|
|
CHECK_PROPERTY_CHANGE(PROP_MODEL_URL, modelURL);
|
|
CHECK_PROPERTY_CHANGE(PROP_MODEL_SCALE, modelScale);
|
|
CHECK_PROPERTY_CHANGE(PROP_JOINT_ROTATIONS_SET, jointRotationsSet);
|
|
CHECK_PROPERTY_CHANGE(PROP_JOINT_ROTATIONS, jointRotations);
|
|
CHECK_PROPERTY_CHANGE(PROP_JOINT_TRANSLATIONS_SET, jointTranslationsSet);
|
|
CHECK_PROPERTY_CHANGE(PROP_JOINT_TRANSLATIONS, jointTranslations);
|
|
CHECK_PROPERTY_CHANGE(PROP_RELAY_PARENT_JOINTS, relayParentJoints);
|
|
CHECK_PROPERTY_CHANGE(PROP_GROUP_CULLED, groupCulled);
|
|
changedProperties += _animation.getChangedProperties();
|
|
|
|
// Light
|
|
CHECK_PROPERTY_CHANGE(PROP_IS_SPOTLIGHT, isSpotlight);
|
|
CHECK_PROPERTY_CHANGE(PROP_INTENSITY, intensity);
|
|
CHECK_PROPERTY_CHANGE(PROP_EXPONENT, exponent);
|
|
CHECK_PROPERTY_CHANGE(PROP_CUTOFF, cutoff);
|
|
CHECK_PROPERTY_CHANGE(PROP_FALLOFF_RADIUS, falloffRadius);
|
|
|
|
// Text
|
|
CHECK_PROPERTY_CHANGE(PROP_TEXT, text);
|
|
CHECK_PROPERTY_CHANGE(PROP_LINE_HEIGHT, lineHeight);
|
|
CHECK_PROPERTY_CHANGE(PROP_TEXT_COLOR, textColor);
|
|
CHECK_PROPERTY_CHANGE(PROP_TEXT_ALPHA, textAlpha);
|
|
CHECK_PROPERTY_CHANGE(PROP_BACKGROUND_COLOR, backgroundColor);
|
|
CHECK_PROPERTY_CHANGE(PROP_BACKGROUND_ALPHA, backgroundAlpha);
|
|
CHECK_PROPERTY_CHANGE(PROP_LEFT_MARGIN, leftMargin);
|
|
CHECK_PROPERTY_CHANGE(PROP_RIGHT_MARGIN, rightMargin);
|
|
CHECK_PROPERTY_CHANGE(PROP_TOP_MARGIN, topMargin);
|
|
CHECK_PROPERTY_CHANGE(PROP_BOTTOM_MARGIN, bottomMargin);
|
|
CHECK_PROPERTY_CHANGE(PROP_UNLIT, unlit);
|
|
CHECK_PROPERTY_CHANGE(PROP_FONT, font);
|
|
CHECK_PROPERTY_CHANGE(PROP_TEXT_EFFECT, textEffect);
|
|
CHECK_PROPERTY_CHANGE(PROP_TEXT_EFFECT_COLOR, textEffectColor);
|
|
CHECK_PROPERTY_CHANGE(PROP_TEXT_EFFECT_THICKNESS, textEffectThickness);
|
|
|
|
// Zone
|
|
changedProperties += _keyLight.getChangedProperties();
|
|
changedProperties += _ambientLight.getChangedProperties();
|
|
changedProperties += _skybox.getChangedProperties();
|
|
changedProperties += _haze.getChangedProperties();
|
|
changedProperties += _bloom.getChangedProperties();
|
|
CHECK_PROPERTY_CHANGE(PROP_FLYING_ALLOWED, flyingAllowed);
|
|
CHECK_PROPERTY_CHANGE(PROP_GHOSTING_ALLOWED, ghostingAllowed);
|
|
CHECK_PROPERTY_CHANGE(PROP_FILTER_URL, filterURL);
|
|
CHECK_PROPERTY_CHANGE(PROP_KEY_LIGHT_MODE, keyLightMode);
|
|
CHECK_PROPERTY_CHANGE(PROP_AMBIENT_LIGHT_MODE, ambientLightMode);
|
|
CHECK_PROPERTY_CHANGE(PROP_SKYBOX_MODE, skyboxMode);
|
|
CHECK_PROPERTY_CHANGE(PROP_HAZE_MODE, hazeMode);
|
|
CHECK_PROPERTY_CHANGE(PROP_BLOOM_MODE, bloomMode);
|
|
CHECK_PROPERTY_CHANGE(PROP_AVATAR_PRIORITY, avatarPriority);
|
|
CHECK_PROPERTY_CHANGE(PROP_SCREENSHARE, screenshare);
|
|
|
|
// Polyvox
|
|
CHECK_PROPERTY_CHANGE(PROP_VOXEL_VOLUME_SIZE, voxelVolumeSize);
|
|
CHECK_PROPERTY_CHANGE(PROP_VOXEL_DATA, voxelData);
|
|
CHECK_PROPERTY_CHANGE(PROP_VOXEL_SURFACE_STYLE, voxelSurfaceStyle);
|
|
CHECK_PROPERTY_CHANGE(PROP_X_TEXTURE_URL, xTextureURL);
|
|
CHECK_PROPERTY_CHANGE(PROP_Y_TEXTURE_URL, yTextureURL);
|
|
CHECK_PROPERTY_CHANGE(PROP_Z_TEXTURE_URL, zTextureURL);
|
|
CHECK_PROPERTY_CHANGE(PROP_X_N_NEIGHBOR_ID, xNNeighborID);
|
|
CHECK_PROPERTY_CHANGE(PROP_Y_N_NEIGHBOR_ID, yNNeighborID);
|
|
CHECK_PROPERTY_CHANGE(PROP_Z_N_NEIGHBOR_ID, zNNeighborID);
|
|
CHECK_PROPERTY_CHANGE(PROP_X_P_NEIGHBOR_ID, xPNeighborID);
|
|
CHECK_PROPERTY_CHANGE(PROP_Y_P_NEIGHBOR_ID, yPNeighborID);
|
|
CHECK_PROPERTY_CHANGE(PROP_Z_P_NEIGHBOR_ID, zPNeighborID);
|
|
|
|
// Web
|
|
CHECK_PROPERTY_CHANGE(PROP_SOURCE_URL, sourceUrl);
|
|
CHECK_PROPERTY_CHANGE(PROP_DPI, dpi);
|
|
CHECK_PROPERTY_CHANGE(PROP_SCRIPT_URL, scriptURL);
|
|
CHECK_PROPERTY_CHANGE(PROP_MAX_FPS, maxFPS);
|
|
CHECK_PROPERTY_CHANGE(PROP_INPUT_MODE, inputMode);
|
|
CHECK_PROPERTY_CHANGE(PROP_SHOW_KEYBOARD_FOCUS_HIGHLIGHT, showKeyboardFocusHighlight);
|
|
|
|
// Polyline
|
|
CHECK_PROPERTY_CHANGE(PROP_LINE_POINTS, linePoints);
|
|
CHECK_PROPERTY_CHANGE(PROP_STROKE_WIDTHS, strokeWidths);
|
|
CHECK_PROPERTY_CHANGE(PROP_STROKE_NORMALS, normals);
|
|
CHECK_PROPERTY_CHANGE(PROP_STROKE_COLORS, strokeColors);
|
|
CHECK_PROPERTY_CHANGE(PROP_IS_UV_MODE_STRETCH, isUVModeStretch);
|
|
CHECK_PROPERTY_CHANGE(PROP_LINE_GLOW, glow);
|
|
CHECK_PROPERTY_CHANGE(PROP_LINE_FACE_CAMERA, faceCamera);
|
|
|
|
// Shape
|
|
CHECK_PROPERTY_CHANGE(PROP_SHAPE, shape);
|
|
|
|
// Material
|
|
CHECK_PROPERTY_CHANGE(PROP_MATERIAL_URL, materialURL);
|
|
CHECK_PROPERTY_CHANGE(PROP_MATERIAL_MAPPING_MODE, materialMappingMode);
|
|
CHECK_PROPERTY_CHANGE(PROP_MATERIAL_PRIORITY, priority);
|
|
CHECK_PROPERTY_CHANGE(PROP_PARENT_MATERIAL_NAME, parentMaterialName);
|
|
CHECK_PROPERTY_CHANGE(PROP_MATERIAL_MAPPING_POS, materialMappingPos);
|
|
CHECK_PROPERTY_CHANGE(PROP_MATERIAL_MAPPING_SCALE, materialMappingScale);
|
|
CHECK_PROPERTY_CHANGE(PROP_MATERIAL_MAPPING_ROT, materialMappingRot);
|
|
CHECK_PROPERTY_CHANGE(PROP_MATERIAL_DATA, materialData);
|
|
CHECK_PROPERTY_CHANGE(PROP_MATERIAL_REPEAT, materialRepeat);
|
|
|
|
// Image
|
|
CHECK_PROPERTY_CHANGE(PROP_IMAGE_URL, imageURL);
|
|
CHECK_PROPERTY_CHANGE(PROP_EMISSIVE, emissive);
|
|
CHECK_PROPERTY_CHANGE(PROP_KEEP_ASPECT_RATIO, keepAspectRatio);
|
|
CHECK_PROPERTY_CHANGE(PROP_SUB_IMAGE, subImage);
|
|
|
|
// Grid
|
|
CHECK_PROPERTY_CHANGE(PROP_GRID_FOLLOW_CAMERA, followCamera);
|
|
CHECK_PROPERTY_CHANGE(PROP_MAJOR_GRID_EVERY, majorGridEvery);
|
|
CHECK_PROPERTY_CHANGE(PROP_MINOR_GRID_EVERY, minorGridEvery);
|
|
|
|
// Gizmo
|
|
CHECK_PROPERTY_CHANGE(PROP_GIZMO_TYPE, gizmoType);
|
|
changedProperties += _ring.getChangedProperties();
|
|
|
|
return changedProperties;
|
|
}
|
|
|
|
/**jsdoc
|
|
* Different entity types have different properties: some common to all entities (listed in the table) and some specific to
|
|
* each {@link Entities.EntityType|EntityType} (linked to below).
|
|
*
|
|
* @typedef {object} Entities.EntityProperties
|
|
* @property {Uuid} id - The ID of the entity. <em>Read-only.</em>
|
|
* @property {string} name="" - A name for the entity. Need not be unique.
|
|
* @property {Entities.EntityType} type - The entity's type. You cannot change the type of an entity after it's created.
|
|
* However, its value may switch among <code>"Box"</code>, <code>"Shape"</code>, and <code>"Sphere"</code> depending on
|
|
* changes to the <code>shape</code> property set for entities of these types. <em>Read-only.</em>
|
|
*
|
|
* @property {Entities.EntityHostType} entityHostType="domain" - How the entity is hosted and sent to others for display.
|
|
* The value can only be set at entity creation by one of the {@link Entities.addEntity} methods. <em>Read-only.</em>
|
|
* @property {boolean} avatarEntity=false - <code>true</code> if the entity is an {@link Entities.EntityHostType|avatar entity},
|
|
* <code>false</code> if it isn't. The value is per the <code>entityHostType</code> property value, set at entity creation
|
|
* by one of the {@link Entities.addEntity} methods. <em>Read-only.</em>
|
|
* @property {boolean} clientOnly=false - A synonym for <code>avatarEntity</code>. <em>Read-only.</em>
|
|
* @property {boolean} localEntity=false - <code>true</code> if the entity is a {@link Entities.EntityHostType|local entity},
|
|
* <code>false</code> if it isn't. The value is per the <code>entityHostType</code> property value, set at entity creation
|
|
* by one of the {@link Entities.addEntity} methods. <em>Read-only.</em>
|
|
*
|
|
* @property {Uuid} owningAvatarID=Uuid.NULL - The session ID of the owning avatar if <code>avatarEntity</code> is
|
|
* <code>true</code>, otherwise {@link Uuid(0)|Uuid.NULL}. <em>Read-only.</em>
|
|
*
|
|
* @property {string} created - The UTC date and time that the entity was created, in ISO 8601 format as
|
|
* <code>yyyy-MM-ddTHH:mm:ssZ</code>. <em>Read-only.</em>
|
|
* @property {number} age - The age of the entity in seconds since it was created. <em>Read-only.</em>
|
|
* @property {string} ageAsText - The age of the entity since it was created, formatted as <code>h hours m minutes s
|
|
* seconds</code>.
|
|
* @property {number} lifetime=-1 - How long an entity lives for, in seconds, before being automatically deleted. A value of
|
|
* <code>-1</code> means that the entity lives for ever.
|
|
* @property {number} lastEdited - When the entity was last edited, expressed as the number of microseconds since
|
|
* 1970-01-01T00:00:00 UTC. <em>Read-only.</em>
|
|
* @property {Uuid} lastEditedBy - The session ID of the avatar or agent that most recently created or edited the entity.
|
|
* <em>Read-only.</em>
|
|
*
|
|
* @property {boolean} locked=false - <code>true</code> if properties other than <code>locked</code> cannot be changed and the
|
|
* entity cannot be deleted, <code>false</code> if all properties can be changed and the entity can be deleted.
|
|
* @property {boolean} visible=true - <code>true</code> if the entity is rendered, <code>false</code> if it isn't.
|
|
* @property {boolean} canCastShadow=true - <code>true</code> if the entity can cast a shadow, <code>false</code> if it can't.
|
|
* Currently applicable only to {@link Entities.EntityProperties-Model|Model} and
|
|
* {@link Entities.EntityProperties-Shape|Shape} entities. Shadows are cast if inside a
|
|
* {@link Entities.EntityProperties-Zone|Zone} entity with <code>castShadows</code> enabled in its <code>keyLight</code>
|
|
* property.
|
|
* @property {boolean} isVisibleInSecondaryCamera=true - <code>true</code> if the entity is rendered in the secondary camera,
|
|
* <code>false</code> if it isn't.
|
|
* @property {Entities.RenderLayer} renderLayer="world" - The layer that the entity renders in.
|
|
* @property {Entities.PrimitiveMode} primitiveMode="solid" - How the entity's geometry is rendered.
|
|
* @property {boolean} ignorePickIntersection=false - <code>true</code> if {@link Picks} and {@link RayPick} ignore the entity,
|
|
* <code>false</code> if they don't.
|
|
*
|
|
* @property {Vec3} position=0,0,0 - The position of the entity in world coordinates.
|
|
* @property {Quat} rotation=0,0,0,1 - The orientation of the entity in world coordinates.
|
|
* @property {Vec3} registrationPoint=0.5,0.5,0.5 - The point in the entity that is set to the entity's position and is rotated
|
|
* about, range {@link Vec3(0)|Vec3.ZERO} – {@link Vec3(0)|Vec3.ONE}. A value of {@link Vec3(0)|Vec3.ZERO} is the
|
|
* entity's minimum x, y, z corner; a value of {@link Vec3(0)|Vec3.ONE} is the entity's maximum x, y, z corner.
|
|
*
|
|
* @property {Vec3} naturalPosition=0,0,0 - The center of the entity's unscaled mesh model if it has one, otherwise
|
|
* {@link Vec3(0)|Vec3.ZERO}. <em>Read-only.</em>
|
|
* @property {Vec3} naturalDimensions - The dimensions of the entity's unscaled mesh model if it has one, otherwise
|
|
* {@link Vec3(0)|Vec3.ONE}. <em>Read-only.</em>
|
|
*
|
|
* @property {Vec3} velocity=0,0,0 - The linear velocity of the entity in m/s with respect to world coordinates.
|
|
* @property {number} damping=0.39347 - How much the linear velocity of an entity slows down over time, range
|
|
* <code>0.0</code> – <code>1.0</code>. A higher damping value slows down the entity more quickly. The default value
|
|
* is for an exponential decay timescale of 2.0s, where it takes 2.0s for the movement to slow to <code>1/e = 0.368</code>
|
|
* of its initial value.
|
|
* @property {Vec3} angularVelocity=0,0,0 - The angular velocity of the entity in rad/s with respect to its axes, about its
|
|
* registration point.
|
|
* @property {number} angularDamping=0.39347 - How much the angular velocity of an entity slows down over time, range
|
|
* <code>0.0</code> – <code>1.0</code>. A higher damping value slows down the entity more quickly. The default value
|
|
* is for an exponential decay timescale of 2.0s, where it takes 2.0s for the movement to slow to <code>1/e = 0.368</code>
|
|
* of its initial value.
|
|
*
|
|
* @property {Vec3} gravity=0,0,0 - The acceleration due to gravity in m/s<sup>2</sup> that the entity should move with, in
|
|
* world coordinates. Use a value of <code>{ x: 0, y: -9.8, z: 0 }</code> to simulate Earth's gravity. Gravity is applied
|
|
* to an entity's motion only if its <code>dynamic</code> property is <code>true</code>.
|
|
* <p>If changing an entity's <code>gravity</code> from {@link Vec3(0)|Vec3.ZERO}, you need to give it a small
|
|
* <code>velocity</code> in order to kick off physics simulation.</p>
|
|
* @property {Vec3} acceleration - The current, measured acceleration of the entity, in m/s<sup>2</sup>.
|
|
* <p class="important">Deprecated: This property is deprecated and will be removed.</p>
|
|
* @property {number} restitution=0.5 - The "bounciness" of an entity when it collides, range <code>0.0</code> –
|
|
* <code>0.99</code>. The higher the value, the more bouncy.
|
|
* @property {number} friction=0.5 - How much an entity slows down when it's moving against another, range <code>0.0</code>
|
|
* – <code>10.0</code>. The higher the value, the more quickly it slows down. Examples: <code>0.1</code> for ice,
|
|
* <code>0.9</code> for sandpaper.
|
|
* @property {number} density=1000 - The density of the entity in kg/m<sup>3</sup>, range <code>100</code> –
|
|
* <code>10000</code>. Examples: <code>100</code> for balsa wood, <code>10000</code> for silver. The density is used in
|
|
* conjunction with the entity's bounding box volume to work out its mass in the application of physics.
|
|
*
|
|
* @property {boolean} collisionless=false - <code>true</code> if the entity shouldn't collide, <code>false</code> if it
|
|
* collides with items per its <code>collisionMask</code> property.
|
|
* @property {boolean} ignoreForCollisions - Synonym for <code>collisionless</code>.
|
|
* @property {CollisionMask} collisionMask=31 - What types of items the entity should collide with.
|
|
* @property {string} collidesWith="static,dynamic,kinematic,myAvatar,otherAvatar," - Synonym for <code>collisionMask</code>,
|
|
* in text format.
|
|
* @property {string} collisionSoundURL="" - The sound that's played when the entity experiences a collision. Valid file
|
|
* formats are per {@link SoundObject}.
|
|
* @property {boolean} dynamic=false - <code>true</code> if the entity's movement is affected by collisions, <code>false</code>
|
|
* if it isn't.
|
|
* @property {boolean} collisionsWillMove - A synonym for <code>dynamic</code>.
|
|
*
|
|
* @property {string} href="" - A "hifi://" metaverse address that a user is teleported to when they click on the entity.
|
|
* @property {string} description="" - A description of the <code>href</code> property value.
|
|
*
|
|
* @property {string} userData="" - Used to store extra data about the entity in JSON format.
|
|
* <p><strong>Warning:</strong> Other apps may also use this property, so make sure you handle data stored by other apps:
|
|
* edit only your bit and leave the rest of the data intact. You can use <code>JSON.parse()</code> to parse the string into
|
|
* a JavaScript object which you can manipulate the properties of, and use <code>JSON.stringify()</code> to convert the
|
|
* object into a string to put back in the property.</p>
|
|
*
|
|
* @property {string} privateUserData="" - Like <code>userData</code>, but only accessible by server entity scripts, assignment
|
|
* client scripts, and users who have "Can Get and Set Private User Data" permissions in the domain.
|
|
*
|
|
* @property {string} script="" - The URL of the client entity script, if any, that is attached to the entity.
|
|
* @property {number} scriptTimestamp=0 - Used to indicate when the client entity script was loaded. Should be
|
|
* an integer number of milliseconds since midnight GMT on January 1, 1970 (e.g., as supplied by <code>Date.now()</code>.
|
|
* If you update the property's value, the <code>script</code> is re-downloaded and reloaded. This is how the "reload"
|
|
* button beside the "script URL" field in properties tab of the Create app works.
|
|
* @property {string} serverScripts="" - The URL of the server entity script, if any, that is attached to the entity.
|
|
*
|
|
* @property {Uuid} parentID=Uuid.NULL - The ID of the entity or avatar that the entity is parented to. A value of
|
|
* {@link Uuid(0)|Uuid.NULL} is used if the entity is not parented.
|
|
* @property {number} parentJointIndex=65535 - The joint of the entity or avatar that the entity is parented to. Use
|
|
* <code>65535</code> or <code>-1</code> to parent to the entity or avatar's position and orientation rather than a joint.
|
|
* @property {Vec3} localPosition=0,0,0 - The position of the entity relative to its parent if the entity is parented,
|
|
* otherwise the same value as <code>position</code>. If the entity is parented to an avatar and is an avatar entity
|
|
* so that it scales with the avatar, this value remains the original local position value while the avatar scale changes.
|
|
* @property {Quat} localRotation=0,0,0,1 - The rotation of the entity relative to its parent if the entity is parented,
|
|
* otherwise the same value as <code>rotation</code>.
|
|
* @property {Vec3} localVelocity=0,0,0 - The velocity of the entity relative to its parent if the entity is parented,
|
|
* otherwise the same value as <code>velocity</code>.
|
|
* @property {Vec3} localAngularVelocity=0,0,0 - The angular velocity of the entity relative to its parent if the entity is
|
|
* parented, otherwise the same value as <code>angularVelocity</code>.
|
|
* @property {Vec3} localDimensions - The dimensions of the entity. If the entity is parented to an avatar and is an
|
|
* avatar entity so that it scales with the avatar, this value remains the original dimensions value while the
|
|
* avatar scale changes.
|
|
*
|
|
* @property {Entities.BoundingBox} boundingBox - The axis-aligned bounding box that tightly encloses the entity.
|
|
* <em>Read-only.</em>
|
|
* @property {AACube} queryAACube - The axis-aligned cube that determines where the entity lives in the entity server's octree.
|
|
* The cube may be considerably larger than the entity in some situations, e.g., when the entity is grabbed by an avatar:
|
|
* the position of the entity is determined through avatar mixer updates and so the AA cube is expanded in order to reduce
|
|
* unnecessary entity server updates. Scripts should not change this property's value.
|
|
*
|
|
* @property {string} actionData="" - Base-64 encoded compressed dump of the actions associated with the entity. This property
|
|
* is typically not used in scripts directly; rather, functions that manipulate an entity's actions update it, e.g.,
|
|
* {@link Entities.addAction}. The size of this property increases with the number of actions. Because this property value
|
|
* has to fit within a Vircadia datagram packet, there is a limit to the number of actions that an entity can have;
|
|
* edits which would result in overflow are rejected. <em>Read-only.</em>
|
|
* @property {Entities.RenderInfo} renderInfo - Information on the cost of rendering the entity. Currently information is only
|
|
* provided for <code>Model</code> entities. <em>Read-only.</em>
|
|
*
|
|
* @property {boolean} cloneable=false - <code>true</code> if the domain or avatar entity can be cloned via
|
|
* {@link Entities.cloneEntity}, <code>false</code> if it can't be.
|
|
* @property {number} cloneLifetime=300 - The entity lifetime for clones created from this entity.
|
|
* @property {number} cloneLimit=0 - The total number of clones of this entity that can exist in the domain at any given time.
|
|
* @property {boolean} cloneDynamic=false - <code>true</code> if clones created from this entity will have their
|
|
* <code>dynamic</code> property set to <code>true</code>, <code>false</code> if they won't.
|
|
* @property {boolean} cloneAvatarEntity=false - <code>true</code> if clones created from this entity will be created as
|
|
* avatar entities, <code>false</code> if they won't be.
|
|
* @property {Uuid} cloneOriginID - The ID of the entity that this entity was cloned from.
|
|
*
|
|
* @property {Uuid[]} renderWithZones=[]] - A list of entity IDs representing with which zones this entity should render.
|
|
* If it is empty, this entity will render normally. Otherwise, this entity will only render if your avatar is within
|
|
* one of the zones in this list.
|
|
*
|
|
* @property {Entities.Grab} grab - The entity's grab-related properties.
|
|
*
|
|
* @property {string} itemName="" - Certifiable name of the Marketplace item.
|
|
* @property {string} itemDescription="" - Certifiable description of the Marketplace item.
|
|
* @property {string} itemCategories="" - Certifiable category of the Marketplace item.
|
|
* @property {string} itemArtist="" - Certifiable artist that created the Marketplace item.
|
|
* @property {string} itemLicense="" - Certifiable license URL for the Marketplace item.
|
|
* @property {number} limitedRun=4294967295 - Certifiable maximum integer number of editions (copies) of the Marketplace item
|
|
* allowed to be sold.
|
|
* @property {number} editionNumber=0 - Certifiable integer edition (copy) number or the Marketplace item. Each copy sold in
|
|
* the Marketplace is numbered sequentially, starting at 1.
|
|
* @property {number} entityInstanceNumber=0 - Certifiable integer instance number for identical entities in a Marketplace
|
|
* item. A Marketplace item may have multiple, identical parts. If so, then each is numbered sequentially with an instance
|
|
* number.
|
|
* @property {string} marketplaceID="" - Certifiable UUID for the Marketplace item, as used in the URL of the item's download
|
|
* and its Marketplace Web page.
|
|
* @property {string} certificateID="" - Hash of the entity's static certificate JSON, signed by the artist's private key.
|
|
* @property {number} staticCertificateVersion=0 - The version of the method used to generate the <code>certificateID</code>.
|
|
*
|
|
* @comment The different entity types have additional properties as follows:
|
|
* @see {@link Entities.EntityProperties-Box|EntityProperties-Box}
|
|
* @see {@link Entities.EntityProperties-Gizmo|EntityProperties-Gizmo}
|
|
* @see {@link Entities.EntityProperties-Grid|EntityProperties-Grid}
|
|
* @see {@link Entities.EntityProperties-Image|EntityProperties-Image}
|
|
* @see {@link Entities.EntityProperties-Light|EntityProperties-Light}
|
|
* @see {@link Entities.EntityProperties-Line|EntityProperties-Line}
|
|
* @see {@link Entities.EntityProperties-Material|EntityProperties-Material}
|
|
* @see {@link Entities.EntityProperties-Model|EntityProperties-Model}
|
|
* @see {@link Entities.EntityProperties-ParticleEffect|EntityProperties-ParticleEffect}
|
|
* @see {@link Entities.EntityProperties-PolyLine|EntityProperties-PolyLine}
|
|
* @see {@link Entities.EntityProperties-PolyVox|EntityProperties-PolyVox}
|
|
* @see {@link Entities.EntityProperties-Shape|EntityProperties-Shape}
|
|
* @see {@link Entities.EntityProperties-Sphere|EntityProperties-Sphere}
|
|
* @see {@link Entities.EntityProperties-Text|EntityProperties-Text}
|
|
* @see {@link Entities.EntityProperties-Web|EntityProperties-Web}
|
|
* @see {@link Entities.EntityProperties-Zone|EntityProperties-Zone}
|
|
*/
|
|
|
|
/**jsdoc
|
|
* The <code>"Box"</code> {@link Entities.EntityType|EntityType} is the same as the <code>"Shape"</code>
|
|
* {@link Entities.EntityType|EntityType} except that its <code>shape</code> value is always set to <code>"Cube"</code>
|
|
* when the entity is created. If its <code>shape</code> property value is subsequently changed then the entity's
|
|
* <code>type</code> will be reported as <code>"Sphere"</code> if the <code>shape</code> is set to <code>"Sphere"</code>,
|
|
* otherwise it will be reported as <code>"Shape"</code>.
|
|
*
|
|
* @typedef {object} Entities.EntityProperties-Box
|
|
* @see {@link Entities.EntityProperties-Shape|EntityProperties-Shape}
|
|
*/
|
|
|
|
/**jsdoc
|
|
* The <code>"Light"</code> {@link Entities.EntityType|EntityType} adds local lighting effects. It has properties in addition
|
|
* to the common {@link Entities.EntityProperties|EntityProperties}.
|
|
*
|
|
* @typedef {object} Entities.EntityProperties-Light
|
|
* @property {Vec3} dimensions=0.1,0.1,0.1 - The dimensions of the entity. Surfaces outside these dimensions are not lit
|
|
* by the light.
|
|
* @property {Color} color=255,255,255 - The color of the light emitted.
|
|
* @property {number} intensity=1 - The brightness of the light.
|
|
* @property {number} falloffRadius=0.1 - The distance from the light's center at which intensity is reduced by 25%.
|
|
* @property {boolean} isSpotlight=false - <code>true</code> if the light is directional, emitting along the entity's
|
|
* local negative z-axis; <code>false</code> if the light is a point light which emanates in all directions.
|
|
* @property {number} exponent=0 - Affects the softness of the spotlight beam: the higher the value the softer the beam.
|
|
* @property {number} cutoff=1.57 - Affects the size of the spotlight beam: the higher the value the larger the beam.
|
|
* @example <caption>Create a spotlight pointing at the ground.</caption>
|
|
* Entities.addEntity({
|
|
* type: "Light",
|
|
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0.5, z: -4 })),
|
|
* rotation: Quat.fromPitchYawRollDegrees(-75, 0, 0),
|
|
* dimensions: { x: 5, y: 5, z: 5 },
|
|
* intensity: 100,
|
|
* falloffRadius: 0.3,
|
|
* isSpotlight: true,
|
|
* exponent: 20,
|
|
* cutoff: 30,
|
|
* lifetime: 300 // Delete after 5 minutes.
|
|
* });
|
|
*/
|
|
|
|
/**jsdoc
|
|
* The <code>"Line"</code> {@link Entities.EntityType|EntityType} draws thin, straight lines between a sequence of two or more
|
|
* points. It has properties in addition to the common {@link Entities.EntityProperties|EntityProperties}.
|
|
* <p class=important>Deprecated: Use {@link Entities.EntityProperties-PolyLine|PolyLine} entities instead.</p>
|
|
*
|
|
* @typedef {object} Entities.EntityProperties-Line
|
|
* @property {Vec3} dimensions=0.1,0.1,0.1 - The dimensions of the entity. Must be sufficient to contain all the
|
|
* <code>linePoints</code>.
|
|
* @property {Vec3[]} linePoints=[]] - The sequence of points to draw lines between. The values are relative to the entity's
|
|
* position. A maximum of 70 points can be specified. The property's value is set only if all the <code>linePoints</code>
|
|
* lie within the entity's <code>dimensions</code>.
|
|
* @property {Color} color=255,255,255 - The color of the line.
|
|
* @example <caption>Draw lines in a "V".</caption>
|
|
* var entity = Entities.addEntity({
|
|
* type: "Line",
|
|
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0.75, z: -5 })),
|
|
* rotation: MyAvatar.orientation,
|
|
* dimensions: { x: 2, y: 2, z: 1 },
|
|
* linePoints: [
|
|
* { x: -1, y: 1, z: 0 },
|
|
* { x: 0, y: -1, z: 0 },
|
|
* { x: 1, y: 1, z: 0 },
|
|
* ],
|
|
* color: { red: 255, green: 0, blue: 0 },
|
|
* lifetime: 300 // Delete after 5 minutes.
|
|
* });
|
|
*/
|
|
|
|
/**jsdoc
|
|
* The <code>"Material"</code> {@link Entities.EntityType|EntityType} modifies existing materials on entities and avatars. It
|
|
* has properties in addition to the common {@link Entities.EntityProperties|EntityProperties}.
|
|
* <p>To apply a material to an entity, set the material entity's <code>parentID</code> property to the entity ID.
|
|
* To apply a material to an avatar, set the material entity's <code>parentID</code> property to the avatar's session UUID.
|
|
* To apply a material to your avatar such that it persists across domains and log-ins, create the material as an avatar entity
|
|
* by setting the <code>entityHostType</code> parameter in {@link Entities.addEntity} to <code>"avatar"</code> and set the
|
|
* entity's <code>parentID</code> property to <code>MyAvatar.SELF_ID</code>.
|
|
* Material entities render as non-scalable spheres if they don't have their parent set.</p>
|
|
*
|
|
* @typedef {object} Entities.EntityProperties-Material
|
|
* @property {Vec3} dimensions=0.1,0.1,0.1 - Used when <code>materialMappingMode == "projected"</code>.
|
|
* @property {string} materialURL="" - URL to a {@link Entities.MaterialResource|MaterialResource}. If you append
|
|
* <code>"#name"</code> to the URL, the material with that name in the {@link Entities.MaterialResource|MaterialResource}
|
|
* will be applied to the entity. Alternatively, set the property value to <code>"materialData"</code> to use the
|
|
* <code>materialData</code> property for the {@link Entities.MaterialResource|MaterialResource} values.
|
|
* @property {string} materialData="" - Used to store {@link Entities.MaterialResource|MaterialResource} data as a JSON string.
|
|
* You can use <code>JSON.parse()</code> to parse the string into a JavaScript object which you can manipulate the
|
|
* properties of, and use <code>JSON.stringify()</code> to convert the object into a string to put in the property.
|
|
* @property {number} priority=0 - The priority for applying the material to its parent. Only the highest priority material is
|
|
* applied, with materials of the same priority randomly assigned. Materials that come with the model have a priority of
|
|
* <code>0</code>.
|
|
* @property {string} parentMaterialName="0" - Selects the mesh part or parts within the parent to which to apply the material.
|
|
* If in the format <code>"mat::string"</code>, all mesh parts with material name <code>"string"</code> are replaced.
|
|
* If <code>"all"</code>, then all mesh parts are replaced.
|
|
* Otherwise the property value is parsed as an unsigned integer, specifying the mesh part index to modify.
|
|
* <p>If the string represents an array (starts with <code>"["</code> and ends with <code>"]"</code>), the string is split
|
|
* at each <code>","</code> and each element parsed as either a number or a string if it starts with <code>"mat::"</code>.
|
|
* For example, <code>"[0,1,mat::string,mat::string2]"</code> will replace mesh parts 0 and 1, and any mesh parts with
|
|
* material <code>"string"</code> or <code>"string2"</code>. Do not put spaces around the commas. Invalid values are parsed
|
|
* to <code>0</code>.</p>
|
|
* @property {string} materialMappingMode="uv" - How the material is mapped to the entity. Either <code>"uv"</code> or
|
|
* <code>"projected"</code>. In <code>"uv"</code> mode, the material is evaluated within the UV space of the mesh it is
|
|
* applied to. In <code>"projected"</code> mode, the 3D transform (position, rotation, and dimensions) of the Material
|
|
* entity is used to evaluate the texture coordinates for the material.
|
|
* @property {Vec2} materialMappingPos=0,0 - Offset position in UV-space of the top left of the material, range
|
|
* <code>{ x: 0, y: 0 }</code> – <code>{ x: 1, y: 1 }</code>.
|
|
* @property {Vec2} materialMappingScale=1,1 - How much to scale the material within the parent's UV-space.
|
|
* @property {number} materialMappingRot=0 - How much to rotate the material within the parent's UV-space, in degrees.
|
|
* @property {boolean} materialRepeat=true - <code>true</code> if the material repeats, <code>false</code> if it doesn't. If
|
|
* <code>false</code>, fragments outside of texCoord 0 – 1 will be discarded. Works in both <code>"uv"</code> and
|
|
* <code>"projected"</code> modes.
|
|
* @example <caption>Color a sphere using a Material entity.</caption>
|
|
* var entityID = Entities.addEntity({
|
|
* type: "Sphere",
|
|
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })),
|
|
* dimensions: { x: 1, y: 1, z: 1 },
|
|
* color: { red: 128, green: 128, blue: 128 },
|
|
* lifetime: 300 // Delete after 5 minutes.
|
|
* });
|
|
*
|
|
* var materialID = Entities.addEntity({
|
|
* type: "Material",
|
|
* parentID: entityID,
|
|
* materialURL: "materialData",
|
|
* priority: 1,
|
|
* materialData: JSON.stringify({
|
|
* materialVersion: 1,
|
|
* materials: {
|
|
* // Value overrides entity's "color" property.
|
|
* albedo: [1.0, 1.0, 0] // Yellow
|
|
* }
|
|
* })
|
|
* });
|
|
*/
|
|
|
|
/**jsdoc
|
|
* The <code>"Model"</code> {@link Entities.EntityType|EntityType} displays a glTF, FBX, or OBJ model. When adding an entity,
|
|
* if no <code>dimensions</code> value is specified then the model is automatically sized to its
|
|
* <code>{@link Entities.EntityProperties|naturalDimensions}</code>. It has properties in addition to the common
|
|
* {@link Entities.EntityProperties|EntityProperties}.
|
|
*
|
|
* @typedef {object} Entities.EntityProperties-Model
|
|
* @property {Vec3} dimensions=0.1,0.1,0.1 - The dimensions of the entity. When adding an entity, if no <code>dimensions</code>
|
|
* value is specified then the model is automatically sized to its
|
|
* <code>{@link Entities.EntityProperties|naturalDimensions}</code>.
|
|
* @property {string} modelURL="" - The URL of the glTF, FBX, or OBJ model. glTF models may be in JSON or binary format
|
|
* (".gltf" or ".glb" URLs respectively). Baked models' URLs have ".baked" before the file type. Model files may also be
|
|
* compressed in GZ format, in which case the URL ends in ".gz".
|
|
* @property {Vec3} modelScale - The scale factor applied to the model's dimensions.
|
|
* <p class="important">Deprecated: This property is deprecated and will be removed.</p>
|
|
* @property {string} textures="" - A JSON string of texture name, URL pairs used when rendering the model in place of the
|
|
* model's original textures. Use a texture name from the <code>originalTextures</code> property to override that texture.
|
|
* Only the texture names and URLs to be overridden need be specified; original textures are used where there are no
|
|
* overrides. You can use <code>JSON.stringify()</code> to convert a JavaScript object of name, URL pairs into a JSON
|
|
* string.
|
|
* @property {string} originalTextures="{}" - A JSON string of texture name, URL pairs used in the model. The property value is
|
|
* filled in after the entity has finished rezzing (i.e., textures have loaded). You can use <code>JSON.parse()</code> to
|
|
* parse the JSON string into a JavaScript object of name, URL pairs. <em>Read-only.</em>
|
|
* @property {Color} color=255,255,255 - <em>Currently not used.</em>
|
|
*
|
|
* @property {ShapeType} shapeType="none" - The shape of the collision hull used if collisions are enabled.
|
|
* @property {string} compoundShapeURL="" - The model file to use for the compound shape if <code>shapeType</code> is
|
|
* <code>"compound"</code>.
|
|
*
|
|
* @property {Entities.AnimationProperties} animation - An animation to play on the model.
|
|
*
|
|
* @property {Quat[]} jointRotations=[]] - Joint rotations applied to the model; <code>[]</code> if none are applied or the
|
|
* model hasn't loaded. The array indexes are per {@link Entities.getJointIndex|getJointIndex}. Rotations are relative to
|
|
* each joint's parent.
|
|
* <p>Joint rotations can be set by {@link Entities.setLocalJointRotation|setLocalJointRotation} and similar functions, or
|
|
* by setting the value of this property. If you set a joint rotation using this property, you also need to set the
|
|
* corresponding <code>jointRotationsSet</code> value to <code>true</code>.</p>
|
|
* @property {boolean[]} jointRotationsSet=[]] - <code>true</code> values for joints that have had rotations applied,
|
|
* <code>false</code> otherwise; <code>[]</code> if none are applied or the model hasn't loaded. The array indexes are per
|
|
* {@link Entities.getJointIndex|getJointIndex}.
|
|
* @property {Vec3[]} jointTranslations=[]] - Joint translations applied to the model; <code>[]</code> if none are applied or
|
|
* the model hasn't loaded. The array indexes are per {@link Entities.getJointIndex|getJointIndex}. Translations are
|
|
* relative to each joint's parent.
|
|
* <p>Joint translations can be set by {@link Entities.setLocalJointTranslation|setLocalJointTranslation} and similar
|
|
* functions, or by setting the value of this property. If you set a joint translation using this property you also need to
|
|
* set the corresponding <code>jointTranslationsSet</code> value to <code>true</code>.</p>
|
|
* @property {boolean[]} jointTranslationsSet=[]] - <code>true</code> values for joints that have had translations applied,
|
|
* <code>false</code> otherwise; <code>[]</code> if none are applied or the model hasn't loaded. The array indexes are per
|
|
* {@link Entities.getJointIndex|getJointIndex}.
|
|
* @property {boolean} relayParentJoints=false - <code>true</code> if when the entity is parented to an avatar, the avatar's
|
|
* joint rotations are applied to the entity's joints; <code>false</code> if a parent avatar's joint rotations are not
|
|
* applied to the entity's joints.
|
|
* @property {boolean} groupCulled=false - <code>true</code> if the mesh parts of the model are LOD culled as a group,
|
|
* <code>false</code> if separate mesh parts are LOD culled individually.
|
|
*
|
|
* @example <caption>Rez a Vive tracker puck.</caption>
|
|
* var entity = Entities.addEntity({
|
|
* type: "Model",
|
|
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0.75, z: -2 })),
|
|
* rotation: MyAvatar.orientation,
|
|
* modelURL: "https://apidocs.vircadia.dev/models/cowboy-hat.fbx",
|
|
* dimensions: { x: 0.8569, y: 0.3960, z: 1.0744 },
|
|
* lifetime: 300 // Delete after 5 minutes.
|
|
* });
|
|
*/
|
|
|
|
/**jsdoc
|
|
* The <code>"ParticleEffect"</code> {@link Entities.EntityType|EntityType} displays a particle system that can be used to
|
|
* simulate things such as fire, smoke, snow, magic spells, etc. The particles emanate from an ellipsoid or part thereof.
|
|
* It has properties in addition to the common {@link Entities.EntityProperties|EntityProperties}.
|
|
*
|
|
* @typedef {object} Entities.EntityProperties-ParticleEffect
|
|
* @property {boolean} isEmitting=true - <code>true</code> if particles are being emitted, <code>false</code> if they aren't.
|
|
* @property {number} maxParticles=1000 - The maximum number of particles to render at one time. Older particles are deleted if
|
|
* necessary when new ones are created.
|
|
* @property {number} lifespan=3s - How long, in seconds, each particle lives.
|
|
* @property {number} emitRate=15 - The number of particles per second to emit.
|
|
* @property {number} emitSpeed=5 - The speed, in m/s, that each particle is emitted at.
|
|
* @property {number} speedSpread=1 - The spread in speeds at which particles are emitted at. For example, if
|
|
* <code>emitSpeed == 5</code> and <code>speedSpread == 1</code>, particles will be emitted with speeds in the range
|
|
* <code>4</code> – <code>6</code>m/s.
|
|
* @property {Vec3} emitAcceleration=0,-9.8,0 - The acceleration that is applied to each particle during its lifetime. The
|
|
* default is Earth's gravity value.
|
|
* @property {Vec3} accelerationSpread=0,0,0 - The spread in accelerations that each particle is given. For example, if
|
|
* <code>emitAccelerations == {x: 0, y: -9.8, z: 0}</code> and <code>accelerationSpread ==
|
|
* {x: 0, y: 1, z: 0}</code>, each particle will have an acceleration in the range <code>{x: 0, y: -10.8, z: 0}</code>
|
|
* – <code>{x: 0, y: -8.8, z: 0}</code>.
|
|
* @property {Vec3} dimensions - The dimensions of the particle effect, i.e., a bounding box containing all the particles
|
|
* during their lifetimes, assuming that <code>emitterShouldTrail == false</code>. <em>Read-only.</em>
|
|
* @property {boolean} emitterShouldTrail=false - <code>true</code> if particles are "left behind" as the emitter moves,
|
|
* <code>false</code> if they stay within the entity's dimensions.
|
|
*
|
|
* @property {Quat} emitOrientation=-0.707,0,0,0.707 - The orientation of particle emission relative to the entity's axes. By
|
|
* default, particles emit along the entity's local z-axis, and <code>azimuthStart</code> and <code>azimuthFinish</code>
|
|
* are relative to the entity's local x-axis. The default value is a rotation of -90 degrees about the local x-axis, i.e.,
|
|
* the particles emit vertically.
|
|
*
|
|
* @property {ShapeType} shapeType="ellipsoid" - The shape from which particles are emitted.
|
|
* @property {string} compoundShapeURL="" - The model file to use for the compound shape if <code>shapeType ==
|
|
* "compound"</code>.
|
|
* @property {Vec3} emitDimensions=0,0,0 - The dimensions of the shape from which particles are emitted.
|
|
* @property {number} emitRadiusStart=1 - The starting radius within the shape at which particles start being emitted;
|
|
* range <code>0.0</code> – <code>1.0</code> for the center to the surface, respectively.
|
|
* Particles are emitted from the portion of the shape that lies between <code>emitRadiusStart</code> and the
|
|
* shape's surface.
|
|
* @property {number} polarStart=0 - The angle in radians from the entity's local z-axis at which particles start being emitted
|
|
* within the shape; range <code>0</code> – <code>Math.PI</code>. Particles are emitted from the portion of the
|
|
* shape that lies between <code>polarStart</code> and <code>polarFinish</code>. Only used if <code>shapeType</code> is
|
|
* <code>"ellipsoid"</code> or <code>"sphere"</code>.
|
|
* @property {number} polarFinish=0 - The angle in radians from the entity's local z-axis at which particles stop being emitted
|
|
* within the shape; range <code>0</code> – <code>Math.PI</code>. Particles are emitted from the portion of the
|
|
* shape that lies between <code>polarStart</code> and <code>polarFinish</code>. Only used if <code>shapeType</code> is
|
|
* <code>"ellipsoid"</code> or <code>"sphere"</code>.
|
|
* @property {number} azimuthStart=-Math.PI - The angle in radians from the entity's local x-axis about the entity's local
|
|
* z-axis at which particles start being emitted; range <code>-Math.PI</code> – <code>Math.PI</code>. Particles are
|
|
* emitted from the portion of the shape that lies between <code>azimuthStart</code> and <code>azimuthFinish</code>.
|
|
* Only used if <code>shapeType</code> is <code>"ellipsoid"</code>, <code>"sphere"</code>, or <code>"circle"</code>.
|
|
* @property {number} azimuthFinish=Math.PI - The angle in radians from the entity's local x-axis about the entity's local
|
|
* z-axis at which particles stop being emitted; range <code>-Math.PI</code> – <code>Math.PI</code>. Particles are
|
|
* emitted from the portion of the shape that lies between <code>azimuthStart</code> and <code>azimuthFinish</code>.
|
|
* Only used if <code>shapeType</code> is <code>"ellipsoid"</code>, <code>"sphere"</code>, or <code>"circle"</code>.
|
|
*
|
|
* @property {string} textures="" - The URL of a JPG or PNG image file to display for each particle. If you want transparency,
|
|
* use PNG format.
|
|
* @property {number} particleRadius=0.025 - The radius of each particle at the middle of its life.
|
|
* @property {number} radiusStart=null - The radius of each particle at the start of its life. If <code>null</code>, the
|
|
* <code>particleRadius</code> value is used.
|
|
* @property {number} radiusFinish=null - The radius of each particle at the end of its life. If <code>null</code>, the
|
|
* <code>particleRadius</code> value is used.
|
|
* @property {number} radiusSpread=0 - The spread in radius that each particle is given. For example, if
|
|
* <code>particleRadius == 0.5</code> and <code>radiusSpread == 0.25</code>, each particle will have a radius in the range
|
|
* <code>0.25</code> – <code>0.75</code>.
|
|
* @property {Color} color=255,255,255 - The color of each particle at the middle of its life.
|
|
* @property {ColorFloat} colorStart=null,null,null - The color of each particle at the start of its life. If any of the
|
|
* component values are undefined, the <code>color</code> value is used.
|
|
* @property {ColorFloat} colorFinish=null,null,null - The color of each particle at the end of its life. If any of the
|
|
* component values are undefined, the <code>color</code> value is used.
|
|
* @property {Color} colorSpread=0,0,0 - The spread in color that each particle is given. For example, if
|
|
* <code>color == {red: 100, green: 100, blue: 100}</code> and <code>colorSpread ==
|
|
* {red: 10, green: 25, blue: 50}</code>, each particle will have a color in the range
|
|
* <code>{red: 90, green: 75, blue: 50}</code> – <code>{red: 110, green: 125, blue: 150}</code>.
|
|
* @property {number} alpha=1 - The opacity of each particle at the middle of its life.
|
|
* @property {number} alphaStart=null - The opacity of each particle at the start of its life. If <code>null</code>, the
|
|
* <code>alpha</code> value is used.
|
|
* @property {number} alphaFinish=null - The opacity of each particle at the end of its life. If <code>null</code>, the
|
|
* <code>alpha</code> value is used.
|
|
* @property {number} alphaSpread=0 - The spread in alpha that each particle is given. For example, if
|
|
* <code>alpha == 0.5</code> and <code>alphaSpread == 0.25</code>, each particle will have an alpha in the range
|
|
* <code>0.25</code> – <code>0.75</code>.
|
|
* @property {Entities.Pulse} pulse - Color and alpha pulse.
|
|
* <p class="important">Deprecated: This property is deprecated and will be removed.</p>
|
|
* @property {number} particleSpin=0 - The rotation of each particle at the middle of its life, range <code>-2 * Math.PI</code>
|
|
* – <code>2 * Math.PI</code> radians.
|
|
* @property {number} spinStart=null - The rotation of each particle at the start of its life, range <code>-2 * Math.PI</code>
|
|
* – <code>2 * Math.PI</code> radians. If <code>null</code>, the <code>particleSpin</code> value is used.
|
|
* @property {number} spinFinish=null - The rotation of each particle at the end of its life, range <code>-2 * Math.PI</code>
|
|
* – <code>2 * Math.PI</code> radians. If <code>null</code>, the <code>particleSpin</code> value is used.
|
|
* @property {number} spinSpread=0 - The spread in spin that each particle is given, range <code>0</code> –
|
|
* <code>2 * Math.PI</code> radians. For example, if <code>particleSpin == Math.PI</code> and
|
|
* <code>spinSpread == Math.PI / 2</code>, each particle will have a rotation in the range <code>Math.PI / 2</code> –
|
|
* <code>3 * Math.PI / 2</code>.
|
|
* @property {boolean} rotateWithEntity=false - <code>true</code> if the particles' rotations are relative to the entity's
|
|
* instantaneous rotation, <code>false</code> if they're relative to world coordinates. If <code>true</code> with
|
|
* <code>particleSpin == 0</code>, the particles keep oriented per the entity's orientation.
|
|
*
|
|
* @example <caption>Create a ball of green smoke.</caption>
|
|
* particles = Entities.addEntity({
|
|
* type: "ParticleEffect",
|
|
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0.5, z: -4 })),
|
|
* lifespan: 5,
|
|
* emitRate: 10,
|
|
* emitSpeed: 0.02,
|
|
* speedSpread: 0.01,
|
|
* emitAcceleration: { x: 0, y: 0.02, z: 0 },
|
|
* polarFinish: Math.PI,
|
|
* textures: "https://content.highfidelity.com/DomainContent/production/Particles/wispy-smoke.png",
|
|
* particleRadius: 0.1,
|
|
* color: { red: 0, green: 255, blue: 0 },
|
|
* alphaFinish: 0,
|
|
* lifetime: 300 // Delete after 5 minutes.
|
|
* });
|
|
*/
|
|
|
|
/**jsdoc
|
|
* The <code>"PolyLine"</code> {@link Entities.EntityType|EntityType} draws textured, straight lines between a sequence of
|
|
* points. It has properties in addition to the common {@link Entities.EntityProperties|EntityProperties}.
|
|
*
|
|
* @typedef {object} Entities.EntityProperties-PolyLine
|
|
* @property {Vec3} dimensions=0.1,0.1,0.1 - The dimensions of the entity, i.e., the size of the bounding box that contains the
|
|
* lines drawn. <em>Read-only.</em>
|
|
* @property {Vec3[]} linePoints=[]] - The sequence of points to draw lines between. The values are relative to the entity's
|
|
* position. A maximum of 70 points can be specified.
|
|
* @property {Vec3[]} normals=[]] - The normal vectors for the line's surface at the <code>linePoints</code>. The values are
|
|
* relative to the entity's orientation. Must be specified in order for the entity to render.
|
|
* @property {number[]} strokeWidths=[]] - The widths, in m, of the line at the <code>linePoints</code>. Must be specified in
|
|
* order for the entity to render.
|
|
* @property {Vec3[]} strokeColors=[]] - The base colors of each point, with values in the range <code>0.0,0.0,0.0</code>
|
|
* – <code>1.0,1.0,1.0</code>. These colors are multiplied with the color of the texture. If there are more line
|
|
* points than stroke colors, the <code>color</code> property value is used for the remaining points.
|
|
* <p><strong>Warning:</strong> The ordinate values are in the range <code>0.0</code> – <code>1.0</code>.</p>
|
|
* @property {Color} color=255,255,255 - Used as the color for each point if <code>strokeColors</code> doesn't have a value for
|
|
* the point.
|
|
* @property {string} textures="" - The URL of a JPG or PNG texture to use for the lines. If you want transparency, use PNG
|
|
* format.
|
|
* @property {boolean} isUVModeStretch=true - <code>true</code> if the texture is stretched to fill the whole line,
|
|
* <code>false</code> if the texture repeats along the line.
|
|
* @property {boolean} glow=false - <code>true</code> if the opacity of the strokes drops off away from the line center,
|
|
* <code>false</code> if it doesn't.
|
|
* @property {boolean} faceCamera=false - <code>true</code> if each line segment rotates to face the camera, <code>false</code>
|
|
* if they don't.
|
|
* @example <caption>Draw a textured "V".</caption>
|
|
* var entity = Entities.addEntity({
|
|
* type: "PolyLine",
|
|
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0.75, z: -5 })),
|
|
* rotation: MyAvatar.orientation,
|
|
* linePoints: [
|
|
* { x: -1, y: 0.5, z: 0 },
|
|
* { x: 0, y: 0, z: 0 },
|
|
* { x: 1, y: 0.5, z: 0 }
|
|
* ],
|
|
* normals: [
|
|
* { x: 0, y: 0, z: 1 },
|
|
* { x: 0, y: 0, z: 1 },
|
|
* { x: 0, y: 0, z: 1 }
|
|
* ],
|
|
* strokeWidths: [ 0.1, 0.1, 0.1 ],
|
|
* color: { red: 255, green: 0, blue: 0 }, // Use just the red channel from the image.
|
|
* textures: "http://hifi-production.s3.amazonaws.com/DomainContent/Toybox/flowArts/trails.png",
|
|
* isUVModeStretch: true,
|
|
* lifetime: 300 // Delete after 5 minutes.
|
|
* });
|
|
*/
|
|
|
|
/**jsdoc
|
|
* The <code>"PolyVox"</code> {@link Entities.EntityType|EntityType} displays a set of textured voxels.
|
|
* It has properties in addition to the common {@link Entities.EntityProperties|EntityProperties}.
|
|
* If you have two or more neighboring PolyVox entities of the same size abutting each other, you can display them as joined by
|
|
* configuring their <code>voxelSurfaceStyle</code> and various neighbor ID properties.
|
|
* <p>PolyVox entities uses a library from <a href="http://www.volumesoffun.com/">Volumes of Fun</a>. Their
|
|
* <a href="http://www.volumesoffun.com/polyvox-documentation/">library documentation</a> may be useful to read.</p>
|
|
*
|
|
* @typedef {object} Entities.EntityProperties-PolyVox
|
|
* @property {Vec3} dimensions=0.1,0.1,0.1 - The dimensions of the entity.
|
|
* @property {Vec3} voxelVolumeSize=32,32,32 - Integer number of voxels along each axis of the entity, in the range
|
|
* <code>1,1,1</code> to <code>128,128,128</code>. The dimensions of each voxel is
|
|
* <code>dimensions / voxelVolumesize</code>.
|
|
* @property {string} voxelData="ABAAEAAQAAAAHgAAEAB42u3BAQ0AAADCoPdPbQ8HFAAAAPBuEAAAAQ==" - Base-64 encoded compressed dump of
|
|
* the PolyVox data. This property is typically not used in scripts directly; rather, functions that manipulate a PolyVox
|
|
* entity update it.
|
|
* <p>The size of this property increases with the size and complexity of the PolyVox entity, with the size depending on how
|
|
* the particular entity's voxels compress. Because this property value has to fit within a Vircadia datagram packet,
|
|
* there is a limit to the size and complexity of a PolyVox entity; edits which would result in an overflow are rejected.</p>
|
|
* @property {Entities.PolyVoxSurfaceStyle} voxelSurfaceStyle=2 - The style of rendering the voxels' surface and how
|
|
* neighboring PolyVox entities are joined.
|
|
* @property {string} xTextureURL="" - The URL of the texture to map to surfaces perpendicular to the entity's local x-axis.
|
|
* JPG or PNG format. If no texture is specified the surfaces display white.
|
|
* @property {string} yTextureURL="" - The URL of the texture to map to surfaces perpendicular to the entity's local y-axis.
|
|
* JPG or PNG format. If no texture is specified the surfaces display white.
|
|
* @property {string} zTextureURL="" - The URL of the texture to map to surfaces perpendicular to the entity's local z-axis.
|
|
* JPG or PNG format. If no texture is specified the surfaces display white.
|
|
* @property {Uuid} xNNeighborID=Uuid.NULL - The ID of the neighboring PolyVox entity in the entity's -ve local x-axis
|
|
* direction, if you want them joined. Set to {@link Uuid(0)|Uuid.NULL} if there is none or you don't want to join them.
|
|
* @property {Uuid} yNNeighborID=Uuid.NULL - The ID of the neighboring PolyVox entity in the entity's -ve local y-axis
|
|
* direction, if you want them joined. Set to {@link Uuid(0)|Uuid.NULL} if there is none or you don't want to join them.
|
|
* @property {Uuid} zNNeighborID=Uuid.NULL - The ID of the neighboring PolyVox entity in the entity's -ve local z-axis
|
|
* direction, if you want them joined. Set to {@link Uuid(0)|Uuid.NULL} if there is none or you don't want to join them.
|
|
* @property {Uuid} xPNeighborID=Uuid.NULL - The ID of the neighboring PolyVox entity in the entity's +ve local x-axis
|
|
* direction, if you want them joined. Set to {@link Uuid(0)|Uuid.NULL} if there is none or you don't want to join them.
|
|
* @property {Uuid} yPNeighborID=Uuid.NULL - The ID of the neighboring PolyVox entity in the entity's +ve local y-axis
|
|
* direction, if you want them joined. Set to {@link Uuid(0)|Uuid.NULL} if there is none or you don't want to join them.
|
|
* @property {Uuid} zPNeighborID=Uuid.NULL - The ID of the neighboring PolyVox entity in the entity's +ve local z-axis
|
|
* direction, if you want them joined. Set to {@link Uuid(0)|Uuid.NULL} if there is none or you don't want to join them.
|
|
* @example <caption>Create a textured PolyVox sphere.</caption>
|
|
* var position = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0.5, z: -8 }));
|
|
* var texture = "http://public.highfidelity.com/cozza13/tuscany/Concrete2.jpg";
|
|
* var polyVox = Entities.addEntity({
|
|
* type: "PolyVox",
|
|
* position: position,
|
|
* dimensions: { x: 2, y: 2, z: 2 },
|
|
* xTextureURL: texture,
|
|
* yTextureURL: texture,
|
|
* zTextureURL: texture,
|
|
* lifetime: 300 // Delete after 5 minutes.
|
|
* });
|
|
* Entities.setVoxelSphere(polyVox, position, 0.8, 255);
|
|
*/
|
|
|
|
/**jsdoc
|
|
* The <code>"Shape"</code> {@link Entities.EntityType|EntityType} displays an entity of a specified <code>shape</code>.
|
|
* It has properties in addition to the common {@link Entities.EntityProperties|EntityProperties}.
|
|
*
|
|
* @typedef {object} Entities.EntityProperties-Shape
|
|
* @property {Entities.Shape} shape="Sphere" - The shape of the entity.
|
|
* @property {Vec3} dimensions=0.1,0.1,0.1 - The dimensions of the entity.
|
|
* @property {Color} color=255,255,255 - The color of the entity.
|
|
* @property {number} alpha=1 - The opacity of the entity, range <code>0.0</code> – <code>1.0</code>.
|
|
* @property {Entities.Pulse} pulse - Color and alpha pulse.
|
|
* <p class="important">Deprecated: This property is deprecated and will be removed.</p>
|
|
* @example <caption>Create a cylinder.</caption>
|
|
* var shape = Entities.addEntity({
|
|
* type: "Shape",
|
|
* shape: "Cylinder",
|
|
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })),
|
|
* dimensions: { x: 0.4, y: 0.6, z: 0.4 },
|
|
* lifetime: 300 // Delete after 5 minutes.
|
|
* });
|
|
*/
|
|
|
|
/**jsdoc
|
|
* The <code>"Sphere"</code> {@link Entities.EntityType|EntityType} is the same as the <code>"Shape"</code>
|
|
* {@link Entities.EntityType|EntityType} except that its <code>shape</code> value is always set to <code>"Sphere"</code>
|
|
* when the entity is created. If its <code>shape</code> property value is subsequently changed then the entity's
|
|
* <code>type</code> will be reported as <code>"Box"</code> if the <code>shape</code> is set to <code>"Cube"</code>,
|
|
* otherwise it will be reported as <code>"Shape"</code>.
|
|
*
|
|
* @typedef {object} Entities.EntityProperties-Sphere
|
|
* @see {@link Entities.EntityProperties-Shape|EntityProperties-Shape}
|
|
*/
|
|
|
|
/**jsdoc
|
|
* The <code>"Text"</code> {@link Entities.EntityType|EntityType} displays a 2D rectangle of text in the domain.
|
|
* It has properties in addition to the common {@link Entities.EntityProperties|EntityProperties}.
|
|
*
|
|
* @typedef {object} Entities.EntityProperties-Text
|
|
* @property {Vec3} dimensions=0.1,0.1,0.01 - The dimensions of the entity.
|
|
* @property {string} text="" - The text to display on the face of the entity. Text wraps if necessary to fit. New lines can be
|
|
* created using <code>\n</code>. Overflowing lines are not displayed.
|
|
* @property {number} lineHeight=0.1 - The height of each line of text (thus determining the font size).
|
|
* @property {Color} textColor=255,255,255 - The color of the text.
|
|
* @property {number} textAlpha=1.0 - The opacity of the text.
|
|
* @property {Color} backgroundColor=0,0,0 - The color of the background rectangle.
|
|
* @property {number} backgroundAlpha=1.0 - The opacity of the background.
|
|
* @property {Entities.Pulse} pulse - Color and alpha pulse.
|
|
* <p class="important">Deprecated: This property is deprecated and will be removed.</p>
|
|
* @property {number} leftMargin=0.0 - The left margin, in meters.
|
|
* @property {number} rightMargin=0.0 - The right margin, in meters.
|
|
* @property {number} topMargin=0.0 - The top margin, in meters.
|
|
* @property {number} bottomMargin=0.0 - The bottom margin, in meters.
|
|
* @property {boolean} unlit=false - <code>true</code> if the entity is unaffected by lighting, <code>false</code> if it is lit
|
|
* by the key light and local lights.
|
|
* @property {string} font="" - The font to render the text with. It can be one of the following: <code>"Courier"</code>,
|
|
* <code>"Inconsolata"</code>, <code>"Roboto"</code>, <code>"Timeless"</code>, or a path to a .sdff file.
|
|
* @property {Entities.TextEffect} textEffect="none" - The effect that is applied to the text.
|
|
* @property {Color} textEffectColor=255,255,255 - The color of the effect.
|
|
* @property {number} textEffectThickness=0.2 - The magnitude of the text effect, range <code>0.0</code> – <code>0.5</code>.
|
|
* @property {BillboardMode} billboardMode="none" - Whether the entity is billboarded to face the camera.
|
|
* @property {boolean} faceCamera - <code>true</code> if <code>billboardMode</code> is <code>"yaw"</code>, <code>false</code>
|
|
* if it isn't. Setting this property to <code>false</code> sets the <code>billboardMode</code> to <code>"none"</code>.
|
|
* <p class="important">Deprecated: This property is deprecated and will be removed.</p>
|
|
* @property {boolean} isFacingAvatar - <code>true</code> if <code>billboardMode</code> is <code>"full"</code>,
|
|
* <code>false</code> if it isn't. Setting this property to <code>false</code> sets the <code>billboardMode</code> to
|
|
* <code>"none"</code>.
|
|
* <p class="important">Deprecated: This property is deprecated and will be removed.</p>
|
|
* @example <caption>Create a text entity.</caption>
|
|
* var text = Entities.addEntity({
|
|
* type: "Text",
|
|
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })),
|
|
* dimensions: { x: 0.6, y: 0.3, z: 0.01 },
|
|
* lineHeight: 0.12,
|
|
* text: "Hello\nthere!",
|
|
* billboardMode: "yaw",
|
|
* lifetime: 300 // Delete after 5 minutes.
|
|
* });
|
|
*/
|
|
|
|
/**jsdoc
|
|
* The <code>"Web"</code> {@link Entities.EntityType|EntityType} displays a browsable web page. Each user views their own copy
|
|
* of the web page: if one user navigates to another page on the entity, other users do not see the change; if a video is being
|
|
* played, users don't see it in sync. It has properties in addition to the common
|
|
* {@link Entities.EntityProperties|EntityProperties}.
|
|
*
|
|
* @typedef {object} Entities.EntityProperties-Web
|
|
* @property {Vec3} dimensions=0.1,0.1,0.01 - The dimensions of the entity.
|
|
* @property {string} sourceUrl="" - The URL of the web page to display. This value does not change as you or others navigate
|
|
* on the Web entity.
|
|
* @property {Color} color=255,255,255 - The color of the web surface. This color tints the web page displayed: the pixel
|
|
* colors on the web page are multiplied by the property color. For example, a value of
|
|
* <code>{ red: 255, green: 0, blue: 0 }</code> lets only the red channel of pixels' colors through.
|
|
* @property {number} alpha=1 - The opacity of the web surface.
|
|
* @property {Entities.Pulse} pulse - Color and alpha pulse.
|
|
* <p class="important">Deprecated: This property is deprecated and will be removed.</p>
|
|
* @property {BillboardMode} billboardMode="none" - Whether the entity is billboarded to face the camera.
|
|
* @property {boolean} faceCamera - <code>true</code> if <code>billboardMode</code> is <code>"yaw"</code>, <code>false</code>
|
|
* if it isn't. Setting this property to <code>false</code> sets the <code>billboardMode</code> to <code>"none"</code>.
|
|
* <p class="important">Deprecated: This property is deprecated and will be removed.</p>
|
|
* @property {boolean} isFacingAvatar - <code>true</code> if <code>billboardMode</code> is <code>"full"</code>,
|
|
* <code>false</code> if it isn't. Setting this property to <code>false</code> sets the <code>billboardMode</code> to
|
|
* <code>"none"</code>.
|
|
* <p class="important">Deprecated: This property is deprecated and will be removed.</p>
|
|
* @property {number} dpi=30 - The resolution to display the page at, in dots per inch. If you convert this to dots per meter
|
|
* (multiply by 1 / 0.0254 = 39.3701) then multiply <code>dimensions.x</code> and <code>dimensions.y</code> by that value
|
|
* you get the resolution in pixels.
|
|
* @property {string} scriptURL="" - The URL of a JavaScript file to inject into the web page.
|
|
* @property {number} maxFPS=10 - The maximum update rate for the web content, in frames/second.
|
|
* @property {WebInputMode} inputMode="touch" - The user input mode to use.
|
|
* @property {boolean} showKeyboardFocusHighlight=true - <code>true</code> if the entity is highlighted when it has keyboard
|
|
* focus, <code>false</code> if it isn't.
|
|
* @example <caption>Create a Web entity displaying at 1920 x 1080 resolution.</caption>
|
|
* var METERS_TO_INCHES = 39.3701;
|
|
* var entity = Entities.addEntity({
|
|
* type: "Web",
|
|
* sourceUrl: "https://vircadia.com/",
|
|
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0.75, z: -4 })),
|
|
* rotation: MyAvatar.orientation,
|
|
* dimensions: {
|
|
* x: 3,
|
|
* y: 3 * 1080 / 1920,
|
|
* z: 0.01
|
|
* },
|
|
* dpi: 1920 / (3 * METERS_TO_INCHES),
|
|
* lifetime: 300 // Delete after 5 minutes.
|
|
* });
|
|
*/
|
|
|
|
/**jsdoc
|
|
* The <code>"Zone"</code> {@link Entities.EntityType|EntityType} is a volume of lighting effects and avatar permissions.
|
|
* Avatar interaction events such as {@link Entities.enterEntity} are also often used with a Zone entity. It has properties in
|
|
* addition to the common {@link Entities.EntityProperties|EntityProperties}.
|
|
*
|
|
* @typedef {object} Entities.EntityProperties-Zone
|
|
* @property {Vec3} dimensions=0.1,0.1,0.1 - The dimensions of the volume in which the zone's lighting effects and avatar
|
|
* permissions have effect.
|
|
*
|
|
* @property {ShapeType} shapeType="box" - The shape of the volume in which the zone's lighting effects and avatar
|
|
* permissions have effect. Reverts to the default value if set to <code>"none"</code>, or set to <code>"compound"</code>
|
|
* and <code>compoundShapeURL</code> is <code>""</code>.
|
|
* @property {string} compoundShapeURL="" - The model file to use for the compound shape if <code>shapeType</code> is
|
|
* <code>"compound"</code>.
|
|
*
|
|
* @property {Entities.ComponentMode} keyLightMode="inherit" - Configures the key light in the zone.
|
|
* @property {Entities.KeyLight} keyLight - The key light properties of the zone.
|
|
*
|
|
* @property {Entities.ComponentMode} ambientLightMode="inherit" - Configures the ambient light in the zone.
|
|
* @property {Entities.AmbientLight} ambientLight - The ambient light properties of the zone.
|
|
*
|
|
* @property {Entities.ComponentMode} skyboxMode="inherit" - Configures the skybox displayed in the zone.
|
|
* @property {Entities.Skybox} skybox - The skybox properties of the zone.
|
|
*
|
|
* @property {Entities.ComponentMode} hazeMode="inherit" - Configures the haze in the zone.
|
|
* @property {Entities.Haze} haze - The haze properties of the zone.
|
|
*
|
|
* @property {Entities.ComponentMode} bloomMode="inherit" - Configures the bloom in the zone.
|
|
* @property {Entities.Bloom} bloom - The bloom properties of the zone.
|
|
*
|
|
* @property {boolean} flyingAllowed=true - <code>true</code> if visitors can fly in the zone; <code>false</code> if they
|
|
* cannot. Only works for domain entities.
|
|
* @property {boolean} ghostingAllowed=true - <code>true</code> if visitors with avatar collisions turned off will not
|
|
* collide with content in the zone; <code>false</code> if visitors will always collide with content in the zone. Only
|
|
* works for domain entities.
|
|
*
|
|
* @property {string} filterURL="" - The URL of a JavaScript file that filters changes to properties of entities within the
|
|
* zone. It is periodically executed for each entity in the zone. It can, for example, be used to not allow changes to
|
|
* certain properties:
|
|
* <pre>
|
|
* function filter(properties) {
|
|
* // Check and edit properties object values,
|
|
* // e.g., properties.modelURL, as required.
|
|
* return properties;
|
|
* }
|
|
* </pre>
|
|
*
|
|
* @property {Entities.AvatarPriorityMode} avatarPriority="inherit" - Configures the priority of updates from avatars in the
|
|
* zone to other clients.
|
|
*
|
|
* @property {Entities.ScreenshareMode} screenshare="inherit" - Configures a zone for screen-sharing.
|
|
*
|
|
* @example <caption>Create a zone that casts a red key light along the x-axis.</caption>
|
|
* var zone = Entities.addEntity({
|
|
* type: "Zone",
|
|
* position: MyAvatar.position,
|
|
* dimensions: { x: 100, y: 100, z: 100 },
|
|
* keyLightMode: "enabled",
|
|
* keyLight: {
|
|
* "color": { "red": 255, "green": 0, "blue": 0 },
|
|
* "direction": { "x": 1, "y": 0, "z": 0 }
|
|
* },
|
|
* lifetime: 300 // Delete after 5 minutes.
|
|
* });
|
|
*/
|
|
|
|
/**jsdoc
|
|
* The <code>"Image"</code> {@link Entities.EntityType|EntityType} displays an image on a 2D rectangle in the domain.
|
|
* It has properties in addition to the common {@link Entities.EntityProperties|EntityProperties}.
|
|
*
|
|
* @typedef {object} Entities.EntityProperties-Image
|
|
* @property {Vec3} dimensions=0.1,0.1,0.01 - The dimensions of the entity.
|
|
* @property {string} imageURL="" - The URL of the image to use.
|
|
* @property {boolean} emissive=false - <code>true</code> if the image should be emissive (unlit), <code>false</code> if it
|
|
* shouldn't.
|
|
* @property {boolean} keepAspectRatio=true - <code>true</code> if the image should maintain its aspect ratio,
|
|
* <code>false</code> if it shouldn't.
|
|
* @property {Rect} subImage=0,0,0,0 - The portion of the image to display. If width or height are <code>0</code>, it defaults
|
|
* to the full image in that dimension.
|
|
* @property {Color} color=255,255,255 - The color of the image.
|
|
* @property {number} alpha=1 - The opacity of the image.
|
|
* @property {Entities.Pulse} pulse - Color and alpha pulse.
|
|
* <p class="important">Deprecated: This property is deprecated and will be removed.</p>
|
|
* @property {BillboardMode} billboardMode="none" - Whether the entity is billboarded to face the camera.
|
|
* @property {boolean} faceCamera - <code>true</code> if <code>billboardMode</code> is <code>"yaw"</code>, <code>false</code>
|
|
* if it isn't. Setting this property to <code>false</code> sets the <code>billboardMode</code> to <code>"none"</code>.
|
|
* <p class="important">Deprecated: This property is deprecated and will be removed.</p>
|
|
* @property {boolean} isFacingAvatar - <code>true</code> if <code>billboardMode</code> is <code>"full"</code>,
|
|
* <code>false</code> if it isn't. Setting this property to <code>false</code> sets the <code>billboardMode</code> to
|
|
* <code>"none"</code>.
|
|
* <p class="important">Deprecated: This property is deprecated and will be removed.</p>
|
|
* @example <caption>Create an image entity.</caption>
|
|
* var image = Entities.addEntity({
|
|
* type: "Image",
|
|
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })),
|
|
* dimensions: { x: 0.6, y: 0.3, z: 0.01 },
|
|
* imageURL: "https://images.pexels.com/photos/1020315/pexels-photo-1020315.jpeg",
|
|
* billboardMode: "yaw",
|
|
* lifetime: 300 // Delete after 5 minutes.
|
|
* });
|
|
*/
|
|
|
|
/**jsdoc
|
|
* The <code>"Grid"</code> {@link Entities.EntityType|EntityType} displays a grid on a 2D plane.
|
|
* It has properties in addition to the common {@link Entities.EntityProperties|EntityProperties}.
|
|
*
|
|
* @typedef {object} Entities.EntityProperties-Grid
|
|
* @property {Vec3} dimensions - 0.1,0.1,0.01 - The dimensions of the entity.
|
|
* @property {Color} color=255,255,255 - The color of the grid.
|
|
* @property {number} alpha=1 - The opacity of the grid.
|
|
* @property {Entities.Pulse} pulse - Color and alpha pulse.
|
|
* <p class="important">Deprecated: This property is deprecated and will be removed.</p>
|
|
* @property {boolean} followCamera=true - <code>true</code> if the grid is always visible even as the camera moves to another
|
|
* position, <code>false</code> if it doesn't follow the camrmea.
|
|
* @property {number} majorGridEvery=5 - Integer number of <code>minorGridEvery</code> intervals at which to draw a thick grid
|
|
* line. Minimum value = <code>1</code>.
|
|
* @property {number} minorGridEvery=1 - Real number of meters at which to draw thin grid lines. Minimum value =
|
|
* <code>0.001</code>.
|
|
* @example <caption>Create a grid entity.</caption>
|
|
* var grid = Entities.addEntity({
|
|
* type: "Grid",
|
|
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })),
|
|
* dimensions: { x: 100.0, y: 100.0, z: 0.01 },
|
|
* followCamera: false,
|
|
* majorGridEvery: 4,
|
|
* minorGridEvery: 0.5,
|
|
* lifetime: 300 // Delete after 5 minutes.
|
|
* });
|
|
*/
|
|
|
|
/**jsdoc
|
|
* The <code>"Gizmo"</code> {@link Entities.EntityType|EntityType} displays an entity that could be used as UI.
|
|
* It has properties in addition to the common {@link Entities.EntityProperties|EntityProperties}.
|
|
*
|
|
* @typedef {object} Entities.EntityProperties-Gizmo
|
|
* @property {Vec3} dimensions=0.1,0.001,0.1 - The dimensions of the entity.
|
|
* @property {Entities.GizmoType} gizmoType="ring" - The gizmo type of the entity.
|
|
* @property {Entities.RingGizmo} ring - The ring gizmo properties.
|
|
*/
|
|
|
|
QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool skipDefaults, bool allowUnknownCreateTime,
|
|
bool strictSemantics, EntityPsuedoPropertyFlags psueudoPropertyFlags) const {
|
|
|
|
// If strictSemantics is true and skipDefaults is false, then all and only those properties are copied for which the property flag
|
|
// is included in _desiredProperties, or is one of the specially enumerated ALWAYS properties below.
|
|
// (There may be exceptions, but if so, they are bugs.)
|
|
// In all other cases, you are welcome to inspect the code and try to figure out what was intended. I wish you luck. -HRS 1/18/17
|
|
QScriptValue properties = engine->newObject();
|
|
EntityItemProperties defaultEntityProperties;
|
|
|
|
const bool psuedoPropertyFlagsActive = psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::FlagsActive);
|
|
// Fix to skip the default return all mechanism, when psuedoPropertyFlagsActive
|
|
const bool psuedoPropertyFlagsButDesiredEmpty = psuedoPropertyFlagsActive && _desiredProperties.isEmpty();
|
|
|
|
if (_created == UNKNOWN_CREATED_TIME && !allowUnknownCreateTime) {
|
|
// No entity properties can have been set so return without setting any default, zero property values.
|
|
return properties;
|
|
}
|
|
|
|
if (_idSet && (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::ID))) {
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_ALWAYS(id, _id.toString());
|
|
}
|
|
if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::Type)) {
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_ALWAYS(type, EntityTypes::getEntityTypeName(_type));
|
|
}
|
|
if ((!skipDefaults || _lifetime != defaultEntityProperties._lifetime) && !strictSemantics) {
|
|
if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::Age)) {
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(age, getAge()); // gettable, but not settable
|
|
}
|
|
if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::AgeAsText)) {
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(ageAsText, formatSecondsElapsed(getAge())); // gettable, but not settable
|
|
}
|
|
}
|
|
if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::LastEdited)) {
|
|
properties.setProperty("lastEdited", convertScriptValue(engine, _lastEdited));
|
|
}
|
|
if (!skipDefaults) {
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_DIMENSIONS, naturalDimensions); // gettable, but not settable
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_POSITION, naturalPosition);
|
|
}
|
|
|
|
// Core properties
|
|
//COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SIMULATION_OWNER, simulationOwner); // not exposed yet
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PARENT_ID, parentID);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PARENT_JOINT_INDEX, parentJointIndex);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_VISIBLE, visible);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_NAME, name);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCKED, locked);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_USER_DATA, userData);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PRIVATE_USER_DATA, privateUserData);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_HREF, href);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_DESCRIPTION, description);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_POSITION, position);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_DIMENSIONS, dimensions);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ROTATION, rotation);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_REGISTRATION_POINT, registrationPoint);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CREATED, created);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LAST_EDITED_BY, lastEditedBy);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_ENTITY_HOST_TYPE, entityHostType, getEntityHostTypeAsString());
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_OWNING_AVATAR_ID, owningAvatarID);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_QUERY_AA_CUBE, queryAACube);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CAN_CAST_SHADOW, canCastShadow);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_VISIBLE_IN_SECONDARY_CAMERA, isVisibleInSecondaryCamera);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_RENDER_LAYER, renderLayer, getRenderLayerAsString());
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_PRIMITIVE_MODE, primitiveMode, getPrimitiveModeAsString());
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_IGNORE_PICK_INTERSECTION, ignorePickIntersection);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_RENDER_WITH_ZONES, renderWithZones);
|
|
_grab.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
|
|
|
// Physics
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_DENSITY, density);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_VELOCITY, velocity);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANGULAR_VELOCITY, angularVelocity);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAVITY, gravity);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ACCELERATION, acceleration);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_DAMPING, damping);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANGULAR_DAMPING, angularDamping);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_RESTITUTION, restitution);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FRICTION, friction);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LIFETIME, lifetime);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLLISIONLESS, collisionless);
|
|
COPY_PROXY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_COLLISIONLESS, collisionless, ignoreForCollisions, getCollisionless()); // legacy support
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLLISION_MASK, collisionMask);
|
|
COPY_PROXY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_COLLISION_MASK, collisionMask, collidesWith, getCollisionMaskAsString());
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_DYNAMIC, dynamic);
|
|
COPY_PROXY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_DYNAMIC, dynamic, collisionsWillMove, getDynamic()); // legacy support
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLLISION_SOUND_URL, collisionSoundURL);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ACTION_DATA, actionData);
|
|
|
|
// Cloning
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CLONEABLE, cloneable);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CLONE_LIFETIME, cloneLifetime);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CLONE_LIMIT, cloneLimit);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CLONE_DYNAMIC, cloneDynamic);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CLONE_AVATAR_ENTITY, cloneAvatarEntity);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CLONE_ORIGIN_ID, cloneOriginID);
|
|
|
|
// Scripts
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SCRIPT, script);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SCRIPT_TIMESTAMP, scriptTimestamp);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SERVER_SCRIPTS, serverScripts);
|
|
|
|
// Certifiable Properties
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ITEM_NAME, itemName);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ITEM_DESCRIPTION, itemDescription);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ITEM_CATEGORIES, itemCategories);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ITEM_ARTIST, itemArtist);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ITEM_LICENSE, itemLicense);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LIMITED_RUN, limitedRun);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MARKETPLACE_ID, marketplaceID);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_EDITION_NUMBER, editionNumber);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ENTITY_INSTANCE_NUMBER, entityInstanceNumber);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CERTIFICATE_ID, certificateID);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CERTIFICATE_TYPE, certificateType);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_STATIC_CERTIFICATE_VERSION, staticCertificateVersion);
|
|
|
|
// Local props for scripts
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_POSITION, localPosition);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_ROTATION, localRotation);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_VELOCITY, localVelocity);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_ANGULAR_VELOCITY, localAngularVelocity);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_DIMENSIONS, localDimensions);
|
|
|
|
// Particles only
|
|
if (_type == EntityTypes::ParticleEffect) {
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_SHAPE_TYPE, shapeType, getShapeTypeAsString());
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COMPOUND_SHAPE_URL, compoundShapeURL);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR, color, u8vec3Color);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA, alpha);
|
|
_pulse.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXTURES, textures);
|
|
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MAX_PARTICLES, maxParticles);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LIFESPAN, lifespan);
|
|
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_EMITTING_PARTICLES, isEmitting);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_EMIT_RATE, emitRate);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_EMIT_SPEED, emitSpeed);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SPEED_SPREAD, speedSpread);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_EMIT_ORIENTATION, emitOrientation);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_EMIT_DIMENSIONS, emitDimensions);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_EMIT_RADIUS_START, emitRadiusStart);
|
|
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_POLAR_START, polarStart);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_POLAR_FINISH, polarFinish);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_AZIMUTH_START, azimuthStart);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_AZIMUTH_FINISH, azimuthFinish);
|
|
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_EMIT_ACCELERATION, emitAcceleration);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ACCELERATION_SPREAD, accelerationSpread);
|
|
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PARTICLE_RADIUS, particleRadius);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_RADIUS_SPREAD, radiusSpread);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_RADIUS_START, radiusStart);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_RADIUS_FINISH, radiusFinish);
|
|
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR_SPREAD, colorSpread, u8vec3Color);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR_START, colorStart, vec3Color);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR_FINISH, colorFinish, vec3Color);
|
|
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA_SPREAD, alphaSpread);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA_START, alphaStart);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA_FINISH, alphaFinish);
|
|
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_EMITTER_SHOULD_TRAIL, emitterShouldTrail);
|
|
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PARTICLE_SPIN, particleSpin);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SPIN_SPREAD, spinSpread);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SPIN_START, spinStart);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SPIN_FINISH, spinFinish);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PARTICLE_ROTATE_WITH_ENTITY, rotateWithEntity);
|
|
}
|
|
|
|
// Models only
|
|
if (_type == EntityTypes::Model) {
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_SHAPE_TYPE, shapeType, getShapeTypeAsString());
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COMPOUND_SHAPE_URL, compoundShapeURL);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR, color, u8vec3Color);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXTURES, textures);
|
|
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MODEL_URL, modelURL);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MODEL_SCALE, modelScale);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_ROTATIONS_SET, jointRotationsSet);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_ROTATIONS, jointRotations);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_TRANSLATIONS_SET, jointTranslationsSet);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_TRANSLATIONS, jointTranslations);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_RELAY_PARENT_JOINTS, relayParentJoints);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_GROUP_CULLED, groupCulled);
|
|
if (!psuedoPropertyFlagsButDesiredEmpty) {
|
|
_animation.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
|
}
|
|
}
|
|
|
|
// FIXME: Shouldn't provide a shapeType property for Box and Sphere entities.
|
|
if (_type == EntityTypes::Box) {
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_SHAPE_TYPE, shapeType, QString("Box"));
|
|
}
|
|
if (_type == EntityTypes::Sphere) {
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_SHAPE_TYPE, shapeType, QString("Sphere"));
|
|
}
|
|
|
|
if (_type == EntityTypes::Box || _type == EntityTypes::Sphere || _type == EntityTypes::Shape) {
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR, color, u8vec3Color);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA, alpha);
|
|
_pulse.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SHAPE, shape);
|
|
}
|
|
|
|
// Lights only
|
|
if (_type == EntityTypes::Light) {
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR, color, u8vec3Color);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_IS_SPOTLIGHT, isSpotlight);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_INTENSITY, intensity);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_EXPONENT, exponent);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CUTOFF, cutoff);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FALLOFF_RADIUS, falloffRadius);
|
|
}
|
|
|
|
// Text only
|
|
if (_type == EntityTypes::Text) {
|
|
_pulse.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_BILLBOARD_MODE, billboardMode, getBillboardModeAsString());
|
|
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXT, text);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_HEIGHT, lineHeight);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_TEXT_COLOR, textColor, u8vec3Color);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXT_ALPHA, textAlpha);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_BACKGROUND_COLOR, backgroundColor, u8vec3Color);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_BACKGROUND_ALPHA, backgroundAlpha);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LEFT_MARGIN, leftMargin);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_RIGHT_MARGIN, rightMargin);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TOP_MARGIN, topMargin);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_BOTTOM_MARGIN, bottomMargin);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_UNLIT, unlit);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FONT, font);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_TEXT_EFFECT, textEffect, getTextEffectAsString());
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_TEXT_EFFECT_COLOR, textEffectColor, u8vec3Color);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXT_EFFECT_THICKNESS, textEffectThickness);
|
|
}
|
|
|
|
// Zones only
|
|
if (_type == EntityTypes::Zone) {
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_SHAPE_TYPE, shapeType, getShapeTypeAsString());
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COMPOUND_SHAPE_URL, compoundShapeURL);
|
|
|
|
if (!psuedoPropertyFlagsButDesiredEmpty) {
|
|
_keyLight.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
|
_ambientLight.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
|
_skybox.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
|
_haze.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
|
_bloom.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
|
}
|
|
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FLYING_ALLOWED, flyingAllowed);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_GHOSTING_ALLOWED, ghostingAllowed);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FILTER_URL, filterURL);
|
|
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_KEY_LIGHT_MODE, keyLightMode, getKeyLightModeAsString());
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_AMBIENT_LIGHT_MODE, ambientLightMode, getAmbientLightModeAsString());
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_SKYBOX_MODE, skyboxMode, getSkyboxModeAsString());
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_HAZE_MODE, hazeMode, getHazeModeAsString());
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_BLOOM_MODE, bloomMode, getBloomModeAsString());
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_AVATAR_PRIORITY, avatarPriority, getAvatarPriorityAsString());
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_SCREENSHARE, screenshare, getScreenshareAsString());
|
|
}
|
|
|
|
// Web only
|
|
if (_type == EntityTypes::Web) {
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR, color, u8vec3Color);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA, alpha);
|
|
_pulse.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_BILLBOARD_MODE, billboardMode, getBillboardModeAsString());
|
|
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SOURCE_URL, sourceUrl);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_DPI, dpi);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SCRIPT_URL, scriptURL);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MAX_FPS, maxFPS);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_INPUT_MODE, inputMode, getInputModeAsString());
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SHOW_KEYBOARD_FOCUS_HIGHLIGHT, showKeyboardFocusHighlight);
|
|
}
|
|
|
|
// PolyVoxel only
|
|
if (_type == EntityTypes::PolyVox) {
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_VOXEL_VOLUME_SIZE, voxelVolumeSize);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_VOXEL_DATA, voxelData);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_VOXEL_SURFACE_STYLE, voxelSurfaceStyle);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_X_TEXTURE_URL, xTextureURL);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_Y_TEXTURE_URL, yTextureURL);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_Z_TEXTURE_URL, zTextureURL);
|
|
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_X_N_NEIGHBOR_ID, xNNeighborID);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_Y_N_NEIGHBOR_ID, yNNeighborID);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_Z_N_NEIGHBOR_ID, zNNeighborID);
|
|
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_X_P_NEIGHBOR_ID, xPNeighborID);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_Y_P_NEIGHBOR_ID, yPNeighborID);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_Z_P_NEIGHBOR_ID, zPNeighborID);
|
|
}
|
|
|
|
// Lines
|
|
if (_type == EntityTypes::Line) {
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR, color, u8vec3Color);
|
|
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_POINTS, linePoints);
|
|
}
|
|
|
|
// Polylines
|
|
if (_type == EntityTypes::PolyLine) {
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR, color, u8vec3Color);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXTURES, textures);
|
|
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_POINTS, linePoints);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_STROKE_WIDTHS, strokeWidths);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_STROKE_NORMALS, normals);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_STROKE_COLORS, strokeColors, qVectorVec3Color);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_IS_UV_MODE_STRETCH, isUVModeStretch);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_GLOW, glow);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_FACE_CAMERA, faceCamera);
|
|
}
|
|
|
|
// Materials
|
|
if (_type == EntityTypes::Material) {
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_URL, materialURL);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_MATERIAL_MAPPING_MODE, materialMappingMode, getMaterialMappingModeAsString());
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_PRIORITY, priority);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PARENT_MATERIAL_NAME, parentMaterialName);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_MAPPING_POS, materialMappingPos);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_MAPPING_SCALE, materialMappingScale);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_MAPPING_ROT, materialMappingRot);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_DATA, materialData);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_REPEAT, materialRepeat);
|
|
}
|
|
|
|
// Image only
|
|
if (_type == EntityTypes::Image) {
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR, color, u8vec3Color);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA, alpha);
|
|
_pulse.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_BILLBOARD_MODE, billboardMode, getBillboardModeAsString());
|
|
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_IMAGE_URL, imageURL);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_EMISSIVE, emissive);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_KEEP_ASPECT_RATIO, keepAspectRatio);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SUB_IMAGE, subImage);
|
|
|
|
// Handle conversions to old 'textures' property from "imageURL"
|
|
if (((!psuedoPropertyFlagsButDesiredEmpty && _desiredProperties.isEmpty()) || _desiredProperties.getHasProperty(PROP_IMAGE_URL)) &&
|
|
(!skipDefaults || defaultEntityProperties._imageURL != _imageURL)) {
|
|
QScriptValue textures = engine->newObject();
|
|
textures.setProperty("tex.picture", _imageURL);
|
|
properties.setProperty("textures", textures);
|
|
}
|
|
}
|
|
|
|
// Grid only
|
|
if (_type == EntityTypes::Grid) {
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR, color, u8vec3Color);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA, alpha);
|
|
_pulse.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
|
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_GRID_FOLLOW_CAMERA, followCamera);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MAJOR_GRID_EVERY, majorGridEvery);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MINOR_GRID_EVERY, minorGridEvery);
|
|
}
|
|
|
|
// Gizmo only
|
|
if (_type == EntityTypes::Gizmo) {
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_GIZMO_TYPE, gizmoType, getGizmoTypeAsString());
|
|
_ring.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
|
}
|
|
|
|
/**jsdoc
|
|
* The axis-aligned bounding box of an entity.
|
|
* @typedef {object} Entities.BoundingBox
|
|
* @property {Vec3} brn - The bottom right near (minimum axes values) corner of the AA box.
|
|
* @property {Vec3} tfl - The top far left (maximum axes values) corner of the AA box.
|
|
* @property {Vec3} center - The center of the AA box.
|
|
* @property {Vec3} dimensions - The dimensions of the AA box.
|
|
*/
|
|
if (!skipDefaults && !strictSemantics &&
|
|
(!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::BoundingBox))) {
|
|
|
|
AABox aaBox = getAABox();
|
|
QScriptValue boundingBox = engine->newObject();
|
|
QScriptValue bottomRightNear = vec3ToScriptValue(engine, aaBox.getCorner());
|
|
QScriptValue topFarLeft = vec3ToScriptValue(engine, aaBox.calcTopFarLeft());
|
|
QScriptValue center = vec3ToScriptValue(engine, aaBox.calcCenter());
|
|
QScriptValue boundingBoxDimensions = vec3ToScriptValue(engine, aaBox.getDimensions());
|
|
boundingBox.setProperty("brn", bottomRightNear);
|
|
boundingBox.setProperty("tfl", topFarLeft);
|
|
boundingBox.setProperty("center", center);
|
|
boundingBox.setProperty("dimensions", boundingBoxDimensions);
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(boundingBox, boundingBox); // gettable, but not settable
|
|
}
|
|
|
|
QString textureNamesStr = QJsonDocument::fromVariant(_textureNames).toJson();
|
|
if (!skipDefaults && !strictSemantics && (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::OriginalTextures))) {
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(originalTextures, textureNamesStr); // gettable, but not settable
|
|
}
|
|
|
|
// Rendering info
|
|
if (!skipDefaults && !strictSemantics &&
|
|
(!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::RenderInfo))) {
|
|
|
|
QScriptValue renderInfo = engine->newObject();
|
|
|
|
/**jsdoc
|
|
* Information on how an entity is rendered. Properties are only filled in for <code>Model</code> entities; other
|
|
* entity types have an empty object, <code>{}</code>.
|
|
* @typedef {object} Entities.RenderInfo
|
|
* @property {number} verticesCount - The number of vertices in the entity.
|
|
* @property {number} texturesCount - The number of textures in the entity.
|
|
* @property {number} texturesSize - The total size of the textures in the entity, in bytes.
|
|
* @property {boolean} hasTransparent - <code>true</code> if any of the textures has transparency, <code>false</code>
|
|
* if none of them do.
|
|
* @property {number} drawCalls - The number of draw calls required to render the entity.
|
|
*/
|
|
// currently only supported by models
|
|
if (_type == EntityTypes::Model) {
|
|
renderInfo.setProperty("verticesCount", (int)getRenderInfoVertexCount()); // FIXME - theoretically the number of vertex could be > max int
|
|
renderInfo.setProperty("texturesSize", (int)getRenderInfoTextureSize()); // FIXME - theoretically the size of textures could be > max int
|
|
renderInfo.setProperty("hasTransparent", getRenderInfoHasTransparent());
|
|
renderInfo.setProperty("drawCalls", getRenderInfoDrawCalls());
|
|
renderInfo.setProperty("texturesCount", getRenderInfoTextureCount());
|
|
}
|
|
|
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(renderInfo, renderInfo); // Gettable but not settable
|
|
}
|
|
|
|
if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::ClientOnly)) {
|
|
properties.setProperty("clientOnly", convertScriptValue(engine, getEntityHostType() == entity::HostType::AVATAR));
|
|
}
|
|
if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::AvatarEntity)) {
|
|
properties.setProperty("avatarEntity", convertScriptValue(engine, getEntityHostType() == entity::HostType::AVATAR));
|
|
}
|
|
if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::LocalEntity)) {
|
|
properties.setProperty("localEntity", convertScriptValue(engine, getEntityHostType() == entity::HostType::LOCAL));
|
|
}
|
|
|
|
if (_type != EntityTypes::PolyLine && (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::FaceCamera))) {
|
|
properties.setProperty("faceCamera", convertScriptValue(engine, getBillboardMode() == BillboardMode::YAW));
|
|
}
|
|
if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::IsFacingAvatar)) {
|
|
properties.setProperty("isFacingAvatar", convertScriptValue(engine, getBillboardMode() == BillboardMode::FULL));
|
|
}
|
|
|
|
return properties;
|
|
}
|
|
|
|
void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool honorReadOnly) {
|
|
QScriptValue typeScriptValue = object.property("type");
|
|
if (typeScriptValue.isValid()) {
|
|
setType(typeScriptValue.toVariant().toString());
|
|
}
|
|
|
|
// Core
|
|
if (!honorReadOnly) {
|
|
// not handled yet
|
|
// COPY_PROPERTY_FROM_QSCRIPTVALUE(simulationOwner, SimulationOwner, setSimulationOwner);
|
|
}
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(parentID, QUuid, setParentID);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(parentJointIndex, quint16, setParentJointIndex);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(visible, bool, setVisible);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(name, QString, setName);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(locked, bool, setLocked);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(userData, QString, setUserData);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(privateUserData, QString, setPrivateUserData);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(href, QString, setHref);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(description, QString, setDescription);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(position, vec3, setPosition);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(dimensions, vec3, setDimensions);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(rotation, quat, setRotation);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(registrationPoint, vec3, setRegistrationPoint);
|
|
if (!honorReadOnly) {
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(created, quint64, setCreated);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(lastEditedBy, QUuid, setLastEditedBy);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(entityHostType, EntityHostType);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(owningAvatarID, QUuid, setOwningAvatarID);
|
|
}
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(queryAACube, AACube, setQueryAACube); // TODO: should scripts be able to set this?
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(canCastShadow, bool, setCanCastShadow);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(isVisibleInSecondaryCamera, bool, setIsVisibleInSecondaryCamera);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(renderLayer, RenderLayer);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(primitiveMode, PrimitiveMode);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(ignorePickIntersection, bool, setIgnorePickIntersection);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(renderWithZones, qVectorQUuid, setRenderWithZones);
|
|
_grab.copyFromScriptValue(object, _defaultSettings);
|
|
|
|
// Physics
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(density, float, setDensity);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(velocity, vec3, setVelocity);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(angularVelocity, vec3, setAngularVelocity);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(gravity, vec3, setGravity);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(acceleration, vec3, setAcceleration);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(damping, float, setDamping);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(angularDamping, float, setAngularDamping);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(restitution, float, setRestitution);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(friction, float, setFriction);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(lifetime, float, setLifetime);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(collisionless, bool, setCollisionless);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(ignoreForCollisions, bool, setCollisionless, getCollisionless); // legacy support
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(collisionMask, uint16_t, setCollisionMask);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(collidesWith, CollisionMask);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(collisionsWillMove, bool, setDynamic, getDynamic); // legacy support
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(dynamic, bool, setDynamic);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(collisionSoundURL, QString, setCollisionSoundURL);
|
|
if (!honorReadOnly) {
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(actionData, QByteArray, setActionData);
|
|
}
|
|
|
|
// Cloning
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(cloneable, bool, setCloneable);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(cloneLifetime, float, setCloneLifetime);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(cloneLimit, float, setCloneLimit);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(cloneDynamic, bool, setCloneDynamic);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(cloneAvatarEntity, bool, setCloneAvatarEntity);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(cloneOriginID, QUuid, setCloneOriginID);
|
|
|
|
// Scripts
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(script, QString, setScript);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(scriptTimestamp, quint64, setScriptTimestamp);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(serverScripts, QString, setServerScripts);
|
|
|
|
// Certifiable Properties
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(itemName, QString, setItemName);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(itemDescription, QString, setItemDescription);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(itemCategories, QString, setItemCategories);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(itemArtist, QString, setItemArtist);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(itemLicense, QString, setItemLicense);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(limitedRun, quint32, setLimitedRun);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(marketplaceID, QString, setMarketplaceID);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(editionNumber, quint32, setEditionNumber);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(entityInstanceNumber, quint32, setEntityInstanceNumber);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(certificateID, QString, setCertificateID);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(certificateType, QString, setCertificateType);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(staticCertificateVersion, quint32, setStaticCertificateVersion);
|
|
|
|
// Script location data
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(localPosition, vec3, setLocalPosition);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(localRotation, quat, setLocalRotation);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(localVelocity, vec3, setLocalVelocity);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(localAngularVelocity, vec3, setLocalAngularVelocity);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(localDimensions, vec3, setLocalDimensions);
|
|
|
|
// Common
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(shapeType, ShapeType);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(compoundShapeURL, QString, setCompoundShapeURL);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(color, u8vec3Color, setColor);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(alpha, float, setAlpha);
|
|
_pulse.copyFromScriptValue(object, _defaultSettings);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(textures, QString, setTextures);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(billboardMode, BillboardMode);
|
|
|
|
// Particles
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(maxParticles, quint32, setMaxParticles);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(lifespan, float, setLifespan);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(isEmitting, bool, setIsEmitting);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(emitRate, float, setEmitRate);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(emitSpeed, float, setEmitSpeed);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(speedSpread, float, setSpeedSpread);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(emitOrientation, quat, setEmitOrientation);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(emitDimensions, vec3, setEmitDimensions);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(emitRadiusStart, float, setEmitRadiusStart);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(polarStart, float, setPolarStart);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(polarFinish, float, setPolarFinish);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(azimuthStart, float, setAzimuthStart);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(azimuthFinish, float, setAzimuthFinish);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(emitAcceleration, vec3, setEmitAcceleration);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(accelerationSpread, vec3, setAccelerationSpread);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(particleRadius, float, setParticleRadius);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusSpread, float, setRadiusSpread);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusStart, float, setRadiusStart);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusFinish, float, setRadiusFinish);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(colorSpread, u8vec3Color, setColorSpread);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(colorStart, vec3Color, setColorStart);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(colorFinish, vec3Color, setColorFinish);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(alphaSpread, float, setAlphaSpread);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(alphaStart, float, setAlphaStart);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(alphaFinish, float, setAlphaFinish);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(emitterShouldTrail, bool, setEmitterShouldTrail);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(particleSpin, float, setParticleSpin);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(spinSpread, float, setSpinSpread);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(spinStart, float, setSpinStart);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(spinFinish, float, setSpinFinish);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(rotateWithEntity, bool, setRotateWithEntity);
|
|
|
|
// Model
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(modelURL, QString, setModelURL);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(modelScale, vec3, setModelScale);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(jointRotationsSet, qVectorBool, setJointRotationsSet);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(jointRotations, qVectorQuat, setJointRotations);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(jointTranslationsSet, qVectorBool, setJointTranslationsSet);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(jointTranslations, qVectorVec3, setJointTranslations);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(relayParentJoints, bool, setRelayParentJoints);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(groupCulled, bool, setGroupCulled);
|
|
_animation.copyFromScriptValue(object, _defaultSettings);
|
|
|
|
// Light
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(isSpotlight, bool, setIsSpotlight);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(intensity, float, setIntensity);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(exponent, float, setExponent);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(cutoff, float, setCutoff);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(falloffRadius, float, setFalloffRadius);
|
|
|
|
// Text
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(text, QString, setText);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(lineHeight, float, setLineHeight);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(textColor, u8vec3Color, setTextColor);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(textAlpha, float, setTextAlpha);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(backgroundColor, u8vec3Color, setBackgroundColor);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(backgroundAlpha, float, setBackgroundAlpha);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(leftMargin, float, setLeftMargin);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(rightMargin, float, setRightMargin);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(topMargin, float, setTopMargin);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(bottomMargin, float, setBottomMargin);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(unlit, bool, setUnlit);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(font, QString, setFont);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(textEffect, TextEffect);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(textEffectColor, u8vec3Color, setTextEffectColor);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(textEffectThickness, float, setTextEffectThickness);
|
|
|
|
// Zone
|
|
_keyLight.copyFromScriptValue(object, _defaultSettings);
|
|
_ambientLight.copyFromScriptValue(object, _defaultSettings);
|
|
_skybox.copyFromScriptValue(object, _defaultSettings);
|
|
_haze.copyFromScriptValue(object, _defaultSettings);
|
|
_bloom.copyFromScriptValue(object, _defaultSettings);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(flyingAllowed, bool, setFlyingAllowed);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(ghostingAllowed, bool, setGhostingAllowed);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(filterURL, QString, setFilterURL);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(keyLightMode, KeyLightMode);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(ambientLightMode, AmbientLightMode);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(skyboxMode, SkyboxMode);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(hazeMode, HazeMode);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(bloomMode, BloomMode);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(avatarPriority, AvatarPriority);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(screenshare, Screenshare);
|
|
|
|
// Polyvox
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(voxelVolumeSize, vec3, setVoxelVolumeSize);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(voxelData, QByteArray, setVoxelData);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(voxelSurfaceStyle, uint16_t, setVoxelSurfaceStyle);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(xTextureURL, QString, setXTextureURL);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(yTextureURL, QString, setYTextureURL);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(zTextureURL, QString, setZTextureURL);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(xNNeighborID, EntityItemID, setXNNeighborID);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(yNNeighborID, EntityItemID, setYNNeighborID);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(zNNeighborID, EntityItemID, setZNNeighborID);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(xPNeighborID, EntityItemID, setXPNeighborID);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(yPNeighborID, EntityItemID, setYPNeighborID);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(zPNeighborID, EntityItemID, setZPNeighborID);
|
|
|
|
// Web
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(sourceUrl, QString, setSourceUrl);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(dpi, uint16_t, setDPI);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(scriptURL, QString, setScriptURL);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(maxFPS, uint8_t, setMaxFPS);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(inputMode, InputMode);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(showKeyboardFocusHighlight, bool, setShowKeyboardFocusHighlight);
|
|
|
|
// Polyline
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(linePoints, qVectorVec3, setLinePoints);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(strokeWidths, qVectorFloat, setStrokeWidths);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(normals, qVectorVec3, setNormals);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(strokeColors, qVectorVec3, setStrokeColors);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(isUVModeStretch, bool, setIsUVModeStretch);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(glow, bool, setGlow);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(faceCamera, bool, setFaceCamera);
|
|
|
|
// Shape
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(shape, QString, setShape);
|
|
|
|
// Material
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(materialURL, QString, setMaterialURL);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(materialMappingMode, MaterialMappingMode);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(priority, quint16, setPriority);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(parentMaterialName, QString, setParentMaterialName);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(materialMappingPos, vec2, setMaterialMappingPos);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(materialMappingScale, vec2, setMaterialMappingScale);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(materialMappingRot, float, setMaterialMappingRot);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(materialData, QString, setMaterialData);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(materialRepeat, bool, setMaterialRepeat);
|
|
|
|
// Image
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(imageURL, QString, setImageURL);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(emissive, bool, setEmissive);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(keepAspectRatio, bool, setKeepAspectRatio);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(subImage, QRect, setSubImage);
|
|
|
|
// Grid
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(followCamera, bool, setFollowCamera);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(majorGridEvery, uint32_t, setMajorGridEvery);
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(minorGridEvery, float, setMinorGridEvery);
|
|
|
|
// Gizmo
|
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(gizmoType, GizmoType);
|
|
_ring.copyFromScriptValue(object, _defaultSettings);
|
|
|
|
// Handle conversions from old 'textures' property to "imageURL"
|
|
{
|
|
QScriptValue V = object.property("textures");
|
|
if (_type == EntityTypes::Image && V.isValid() && !object.property("imageURL").isValid()) {
|
|
bool isValid = false;
|
|
QString textures = QString_convertFromScriptValue(V, isValid);
|
|
if (isValid) {
|
|
QVariantMap texturesMap = parseTexturesToMap(textures, QVariantMap());
|
|
auto texPicture = texturesMap.find("tex.picture");
|
|
if (texPicture != texturesMap.end()) {
|
|
auto imageURL = texPicture.value().toString();
|
|
if (_defaultSettings || imageURL != _imageURL) {
|
|
setImageURL(imageURL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Handle old "faceCamera" and "isFacingAvatar" props
|
|
if (_type != EntityTypes::PolyLine) {
|
|
QScriptValue P = object.property("faceCamera");
|
|
if (P.isValid() && !object.property("billboardMode").isValid()) {
|
|
bool newValue = P.toVariant().toBool();
|
|
bool oldValue = getBillboardMode() == BillboardMode::YAW;
|
|
if (_defaultSettings || newValue != oldValue) {
|
|
setBillboardMode(newValue ? BillboardMode::YAW : BillboardMode::NONE);
|
|
}
|
|
}
|
|
}
|
|
{
|
|
QScriptValue P = object.property("isFacingAvatar");
|
|
if (P.isValid() && !object.property("billboardMode").isValid() && !object.property("faceCamera").isValid()) {
|
|
bool newValue = P.toVariant().toBool();
|
|
bool oldValue = getBillboardMode() == BillboardMode::FULL;
|
|
if (_defaultSettings || newValue != oldValue) {
|
|
setBillboardMode(newValue ? BillboardMode::FULL : BillboardMode::NONE);
|
|
}
|
|
}
|
|
}
|
|
|
|
_lastEdited = usecTimestampNow();
|
|
}
|
|
|
|
void EntityItemProperties::copyFromJSONString(QScriptEngine& scriptEngine, const QString& jsonString) {
|
|
// DANGER: this method is expensive
|
|
QJsonDocument propertiesDoc = QJsonDocument::fromJson(jsonString.toUtf8());
|
|
QJsonObject propertiesObj = propertiesDoc.object();
|
|
QVariant propertiesVariant(propertiesObj);
|
|
QVariantMap propertiesMap = propertiesVariant.toMap();
|
|
QScriptValue propertiesScriptValue = variantMapToScriptValue(propertiesMap, scriptEngine);
|
|
bool honorReadOnly = true;
|
|
copyFromScriptValue(propertiesScriptValue, honorReadOnly);
|
|
}
|
|
|
|
|
|
void EntityItemProperties::merge(const EntityItemProperties& other) {
|
|
// Core
|
|
COPY_PROPERTY_IF_CHANGED(simulationOwner);
|
|
COPY_PROPERTY_IF_CHANGED(parentID);
|
|
COPY_PROPERTY_IF_CHANGED(parentJointIndex);
|
|
COPY_PROPERTY_IF_CHANGED(visible);
|
|
COPY_PROPERTY_IF_CHANGED(name);
|
|
COPY_PROPERTY_IF_CHANGED(locked);
|
|
COPY_PROPERTY_IF_CHANGED(userData);
|
|
COPY_PROPERTY_IF_CHANGED(privateUserData);
|
|
COPY_PROPERTY_IF_CHANGED(href);
|
|
COPY_PROPERTY_IF_CHANGED(description);
|
|
COPY_PROPERTY_IF_CHANGED(position);
|
|
COPY_PROPERTY_IF_CHANGED(dimensions);
|
|
COPY_PROPERTY_IF_CHANGED(rotation);
|
|
COPY_PROPERTY_IF_CHANGED(registrationPoint);
|
|
COPY_PROPERTY_IF_CHANGED(created);
|
|
COPY_PROPERTY_IF_CHANGED(lastEditedBy);
|
|
COPY_PROPERTY_IF_CHANGED(entityHostType);
|
|
COPY_PROPERTY_IF_CHANGED(owningAvatarID);
|
|
COPY_PROPERTY_IF_CHANGED(queryAACube);
|
|
COPY_PROPERTY_IF_CHANGED(canCastShadow);
|
|
COPY_PROPERTY_IF_CHANGED(isVisibleInSecondaryCamera);
|
|
COPY_PROPERTY_IF_CHANGED(renderLayer);
|
|
COPY_PROPERTY_IF_CHANGED(primitiveMode);
|
|
COPY_PROPERTY_IF_CHANGED(ignorePickIntersection);
|
|
COPY_PROPERTY_IF_CHANGED(renderWithZones);
|
|
_grab.merge(other._grab);
|
|
|
|
// Physics
|
|
COPY_PROPERTY_IF_CHANGED(density);
|
|
COPY_PROPERTY_IF_CHANGED(velocity);
|
|
COPY_PROPERTY_IF_CHANGED(angularVelocity);
|
|
COPY_PROPERTY_IF_CHANGED(gravity);
|
|
COPY_PROPERTY_IF_CHANGED(acceleration);
|
|
COPY_PROPERTY_IF_CHANGED(damping);
|
|
COPY_PROPERTY_IF_CHANGED(angularDamping);
|
|
COPY_PROPERTY_IF_CHANGED(restitution);
|
|
COPY_PROPERTY_IF_CHANGED(friction);
|
|
COPY_PROPERTY_IF_CHANGED(lifetime);
|
|
COPY_PROPERTY_IF_CHANGED(collisionless);
|
|
COPY_PROPERTY_IF_CHANGED(collisionMask);
|
|
COPY_PROPERTY_IF_CHANGED(dynamic);
|
|
COPY_PROPERTY_IF_CHANGED(collisionSoundURL);
|
|
COPY_PROPERTY_IF_CHANGED(actionData);
|
|
|
|
// Cloning
|
|
COPY_PROPERTY_IF_CHANGED(cloneable);
|
|
COPY_PROPERTY_IF_CHANGED(cloneLifetime);
|
|
COPY_PROPERTY_IF_CHANGED(cloneLimit);
|
|
COPY_PROPERTY_IF_CHANGED(cloneDynamic);
|
|
COPY_PROPERTY_IF_CHANGED(cloneAvatarEntity);
|
|
COPY_PROPERTY_IF_CHANGED(cloneOriginID);
|
|
|
|
// Scripts
|
|
COPY_PROPERTY_IF_CHANGED(script);
|
|
COPY_PROPERTY_IF_CHANGED(scriptTimestamp);
|
|
COPY_PROPERTY_IF_CHANGED(serverScripts);
|
|
|
|
// Certifiable Properties
|
|
COPY_PROPERTY_IF_CHANGED(itemName);
|
|
COPY_PROPERTY_IF_CHANGED(itemDescription);
|
|
COPY_PROPERTY_IF_CHANGED(itemCategories);
|
|
COPY_PROPERTY_IF_CHANGED(itemArtist);
|
|
COPY_PROPERTY_IF_CHANGED(itemLicense);
|
|
COPY_PROPERTY_IF_CHANGED(limitedRun);
|
|
COPY_PROPERTY_IF_CHANGED(marketplaceID);
|
|
COPY_PROPERTY_IF_CHANGED(editionNumber);
|
|
COPY_PROPERTY_IF_CHANGED(entityInstanceNumber);
|
|
COPY_PROPERTY_IF_CHANGED(certificateID);
|
|
COPY_PROPERTY_IF_CHANGED(certificateType);
|
|
COPY_PROPERTY_IF_CHANGED(staticCertificateVersion);
|
|
|
|
// Local props for scripts
|
|
COPY_PROPERTY_IF_CHANGED(localPosition);
|
|
COPY_PROPERTY_IF_CHANGED(localRotation);
|
|
COPY_PROPERTY_IF_CHANGED(localVelocity);
|
|
COPY_PROPERTY_IF_CHANGED(localAngularVelocity);
|
|
COPY_PROPERTY_IF_CHANGED(localDimensions);
|
|
|
|
// Common
|
|
COPY_PROPERTY_IF_CHANGED(shapeType);
|
|
COPY_PROPERTY_IF_CHANGED(compoundShapeURL);
|
|
COPY_PROPERTY_IF_CHANGED(color);
|
|
COPY_PROPERTY_IF_CHANGED(alpha);
|
|
_pulse.merge(other._pulse);
|
|
COPY_PROPERTY_IF_CHANGED(textures);
|
|
COPY_PROPERTY_IF_CHANGED(billboardMode);
|
|
|
|
// Particles
|
|
COPY_PROPERTY_IF_CHANGED(maxParticles);
|
|
COPY_PROPERTY_IF_CHANGED(lifespan);
|
|
COPY_PROPERTY_IF_CHANGED(isEmitting);
|
|
COPY_PROPERTY_IF_CHANGED(emitRate);
|
|
COPY_PROPERTY_IF_CHANGED(emitSpeed);
|
|
COPY_PROPERTY_IF_CHANGED(speedSpread);
|
|
COPY_PROPERTY_IF_CHANGED(emitOrientation);
|
|
COPY_PROPERTY_IF_CHANGED(emitDimensions);
|
|
COPY_PROPERTY_IF_CHANGED(emitRadiusStart);
|
|
COPY_PROPERTY_IF_CHANGED(polarStart);
|
|
COPY_PROPERTY_IF_CHANGED(polarFinish);
|
|
COPY_PROPERTY_IF_CHANGED(azimuthStart);
|
|
COPY_PROPERTY_IF_CHANGED(azimuthFinish);
|
|
COPY_PROPERTY_IF_CHANGED(emitAcceleration);
|
|
COPY_PROPERTY_IF_CHANGED(accelerationSpread);
|
|
COPY_PROPERTY_IF_CHANGED(particleRadius);
|
|
COPY_PROPERTY_IF_CHANGED(radiusSpread);
|
|
COPY_PROPERTY_IF_CHANGED(radiusStart);
|
|
COPY_PROPERTY_IF_CHANGED(radiusFinish);
|
|
COPY_PROPERTY_IF_CHANGED(colorSpread);
|
|
COPY_PROPERTY_IF_CHANGED(colorStart);
|
|
COPY_PROPERTY_IF_CHANGED(colorFinish);
|
|
COPY_PROPERTY_IF_CHANGED(alphaSpread);
|
|
COPY_PROPERTY_IF_CHANGED(alphaStart);
|
|
COPY_PROPERTY_IF_CHANGED(alphaFinish);
|
|
COPY_PROPERTY_IF_CHANGED(emitterShouldTrail);
|
|
COPY_PROPERTY_IF_CHANGED(particleSpin);
|
|
COPY_PROPERTY_IF_CHANGED(spinSpread);
|
|
COPY_PROPERTY_IF_CHANGED(spinStart);
|
|
COPY_PROPERTY_IF_CHANGED(spinFinish);
|
|
COPY_PROPERTY_IF_CHANGED(rotateWithEntity);
|
|
|
|
// Model
|
|
COPY_PROPERTY_IF_CHANGED(modelURL);
|
|
COPY_PROPERTY_IF_CHANGED(modelScale);
|
|
COPY_PROPERTY_IF_CHANGED(jointRotationsSet);
|
|
COPY_PROPERTY_IF_CHANGED(jointRotations);
|
|
COPY_PROPERTY_IF_CHANGED(jointTranslationsSet);
|
|
COPY_PROPERTY_IF_CHANGED(jointTranslations);
|
|
COPY_PROPERTY_IF_CHANGED(relayParentJoints);
|
|
COPY_PROPERTY_IF_CHANGED(groupCulled);
|
|
_animation.merge(other._animation);
|
|
|
|
// Light
|
|
COPY_PROPERTY_IF_CHANGED(isSpotlight);
|
|
COPY_PROPERTY_IF_CHANGED(intensity);
|
|
COPY_PROPERTY_IF_CHANGED(exponent);
|
|
COPY_PROPERTY_IF_CHANGED(cutoff);
|
|
COPY_PROPERTY_IF_CHANGED(falloffRadius);
|
|
|
|
// Text
|
|
COPY_PROPERTY_IF_CHANGED(text);
|
|
COPY_PROPERTY_IF_CHANGED(lineHeight);
|
|
COPY_PROPERTY_IF_CHANGED(textColor);
|
|
COPY_PROPERTY_IF_CHANGED(textAlpha);
|
|
COPY_PROPERTY_IF_CHANGED(backgroundColor);
|
|
COPY_PROPERTY_IF_CHANGED(backgroundAlpha);
|
|
COPY_PROPERTY_IF_CHANGED(leftMargin);
|
|
COPY_PROPERTY_IF_CHANGED(rightMargin);
|
|
COPY_PROPERTY_IF_CHANGED(topMargin);
|
|
COPY_PROPERTY_IF_CHANGED(bottomMargin);
|
|
COPY_PROPERTY_IF_CHANGED(unlit);
|
|
COPY_PROPERTY_IF_CHANGED(font);
|
|
COPY_PROPERTY_IF_CHANGED(textEffect);
|
|
COPY_PROPERTY_IF_CHANGED(textEffectColor);
|
|
COPY_PROPERTY_IF_CHANGED(textEffectThickness);
|
|
|
|
// Zone
|
|
_keyLight.merge(other._keyLight);
|
|
_ambientLight.merge(other._ambientLight);
|
|
_skybox.merge(other._skybox);
|
|
_haze.merge(other._haze);
|
|
_bloom.merge(other._bloom);
|
|
COPY_PROPERTY_IF_CHANGED(flyingAllowed);
|
|
COPY_PROPERTY_IF_CHANGED(ghostingAllowed);
|
|
COPY_PROPERTY_IF_CHANGED(filterURL);
|
|
COPY_PROPERTY_IF_CHANGED(keyLightMode);
|
|
COPY_PROPERTY_IF_CHANGED(ambientLightMode);
|
|
COPY_PROPERTY_IF_CHANGED(skyboxMode);
|
|
COPY_PROPERTY_IF_CHANGED(hazeMode);
|
|
COPY_PROPERTY_IF_CHANGED(bloomMode);
|
|
COPY_PROPERTY_IF_CHANGED(avatarPriority);
|
|
COPY_PROPERTY_IF_CHANGED(screenshare);
|
|
|
|
// Polyvox
|
|
COPY_PROPERTY_IF_CHANGED(voxelVolumeSize);
|
|
COPY_PROPERTY_IF_CHANGED(voxelData);
|
|
COPY_PROPERTY_IF_CHANGED(voxelSurfaceStyle);
|
|
COPY_PROPERTY_IF_CHANGED(xTextureURL);
|
|
COPY_PROPERTY_IF_CHANGED(yTextureURL);
|
|
COPY_PROPERTY_IF_CHANGED(zTextureURL);
|
|
COPY_PROPERTY_IF_CHANGED(xNNeighborID);
|
|
COPY_PROPERTY_IF_CHANGED(yNNeighborID);
|
|
COPY_PROPERTY_IF_CHANGED(zNNeighborID);
|
|
COPY_PROPERTY_IF_CHANGED(xPNeighborID);
|
|
COPY_PROPERTY_IF_CHANGED(yPNeighborID);
|
|
COPY_PROPERTY_IF_CHANGED(zPNeighborID);
|
|
|
|
// Web
|
|
COPY_PROPERTY_IF_CHANGED(sourceUrl);
|
|
COPY_PROPERTY_IF_CHANGED(dpi);
|
|
COPY_PROPERTY_IF_CHANGED(scriptURL);
|
|
COPY_PROPERTY_IF_CHANGED(maxFPS);
|
|
COPY_PROPERTY_IF_CHANGED(inputMode);
|
|
COPY_PROPERTY_IF_CHANGED(showKeyboardFocusHighlight);
|
|
|
|
// Polyline
|
|
COPY_PROPERTY_IF_CHANGED(linePoints);
|
|
COPY_PROPERTY_IF_CHANGED(strokeWidths);
|
|
COPY_PROPERTY_IF_CHANGED(normals);
|
|
COPY_PROPERTY_IF_CHANGED(strokeColors);
|
|
COPY_PROPERTY_IF_CHANGED(isUVModeStretch);
|
|
COPY_PROPERTY_IF_CHANGED(glow);
|
|
COPY_PROPERTY_IF_CHANGED(faceCamera);
|
|
|
|
// Shape
|
|
COPY_PROPERTY_IF_CHANGED(shape);
|
|
|
|
// Material
|
|
COPY_PROPERTY_IF_CHANGED(materialURL);
|
|
COPY_PROPERTY_IF_CHANGED(materialMappingMode);
|
|
COPY_PROPERTY_IF_CHANGED(priority);
|
|
COPY_PROPERTY_IF_CHANGED(parentMaterialName);
|
|
COPY_PROPERTY_IF_CHANGED(materialMappingPos);
|
|
COPY_PROPERTY_IF_CHANGED(materialMappingScale);
|
|
COPY_PROPERTY_IF_CHANGED(materialMappingRot);
|
|
COPY_PROPERTY_IF_CHANGED(materialData);
|
|
COPY_PROPERTY_IF_CHANGED(materialRepeat);
|
|
|
|
// Image
|
|
COPY_PROPERTY_IF_CHANGED(imageURL);
|
|
COPY_PROPERTY_IF_CHANGED(emissive);
|
|
COPY_PROPERTY_IF_CHANGED(keepAspectRatio);
|
|
COPY_PROPERTY_IF_CHANGED(subImage);
|
|
|
|
// Grid
|
|
COPY_PROPERTY_IF_CHANGED(followCamera);
|
|
COPY_PROPERTY_IF_CHANGED(majorGridEvery);
|
|
COPY_PROPERTY_IF_CHANGED(minorGridEvery);
|
|
|
|
// Gizmo
|
|
COPY_PROPERTY_IF_CHANGED(gizmoType);
|
|
_ring.merge(other._ring);
|
|
|
|
_lastEdited = usecTimestampNow();
|
|
}
|
|
|
|
QScriptValue EntityItemPropertiesToScriptValue(QScriptEngine* engine, const EntityItemProperties& properties) {
|
|
return properties.copyToScriptValue(engine, false);
|
|
}
|
|
|
|
QScriptValue EntityItemNonDefaultPropertiesToScriptValue(QScriptEngine* engine, const EntityItemProperties& properties) {
|
|
return properties.copyToScriptValue(engine, true);
|
|
}
|
|
|
|
void EntityItemPropertiesFromScriptValueIgnoreReadOnly(const QScriptValue &object, EntityItemProperties& properties) {
|
|
properties.copyFromScriptValue(object, false);
|
|
}
|
|
|
|
void EntityItemPropertiesFromScriptValueHonorReadOnly(const QScriptValue &object, EntityItemProperties& properties) {
|
|
properties.copyFromScriptValue(object, true);
|
|
}
|
|
|
|
QScriptValue EntityPropertyFlagsToScriptValue(QScriptEngine* engine, const EntityPropertyFlags& flags) {
|
|
return EntityItemProperties::entityPropertyFlagsToScriptValue(engine, flags);
|
|
}
|
|
|
|
void EntityPropertyFlagsFromScriptValue(const QScriptValue& object, EntityPropertyFlags& flags) {
|
|
EntityItemProperties::entityPropertyFlagsFromScriptValue(object, flags);
|
|
}
|
|
|
|
|
|
QScriptValue EntityItemProperties::entityPropertyFlagsToScriptValue(QScriptEngine* engine, const EntityPropertyFlags& flags) {
|
|
QScriptValue result = engine->newObject();
|
|
return result;
|
|
}
|
|
|
|
void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue& object, EntityPropertyFlags& flags) {
|
|
if (object.isString()) {
|
|
EntityPropertyInfo propertyInfo;
|
|
if (getPropertyInfo(object.toString(), propertyInfo)) {
|
|
flags << propertyInfo.propertyEnum;
|
|
}
|
|
}
|
|
else if (object.isArray()) {
|
|
quint32 length = object.property("length").toInt32();
|
|
for (quint32 i = 0; i < length; i++) {
|
|
QString propertyName = object.property(i).toString();
|
|
EntityPropertyInfo propertyInfo;
|
|
if (getPropertyInfo(propertyName, propertyInfo)) {
|
|
flags << propertyInfo.propertyEnum;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static QHash<QString, EntityPropertyInfo> _propertyInfos;
|
|
static QHash<EntityPropertyList, QString> _enumsToPropertyStrings;
|
|
|
|
bool EntityItemProperties::getPropertyInfo(const QString& propertyName, EntityPropertyInfo& propertyInfo) {
|
|
|
|
static std::once_flag initMap;
|
|
|
|
std::call_once(initMap, []() {
|
|
// Core
|
|
ADD_PROPERTY_TO_MAP(PROP_SIMULATION_OWNER, SimulationOwner, simulationOwner, SimulationOwner);
|
|
ADD_PROPERTY_TO_MAP(PROP_PARENT_ID, ParentID, parentID, QUuid);
|
|
ADD_PROPERTY_TO_MAP(PROP_PARENT_JOINT_INDEX, ParentJointIndex, parentJointIndex, uint16_t);
|
|
ADD_PROPERTY_TO_MAP(PROP_VISIBLE, Visible, visible, bool);
|
|
ADD_PROPERTY_TO_MAP(PROP_NAME, Name, name, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_LOCKED, Locked, locked, bool);
|
|
ADD_PROPERTY_TO_MAP(PROP_USER_DATA, UserData, userData, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_PRIVATE_USER_DATA, PrivateUserData, privateUserData, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_HREF, Href, href, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_DESCRIPTION, Description, description, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_POSITION, Position, position, vec3);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_DIMENSIONS, Dimensions, dimensions, vec3, ENTITY_ITEM_MIN_DIMENSION, FLT_MAX);
|
|
ADD_PROPERTY_TO_MAP(PROP_ROTATION, Rotation, rotation, quat);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_REGISTRATION_POINT, RegistrationPoint, registrationPoint, vec3,
|
|
ENTITY_ITEM_MIN_REGISTRATION_POINT, ENTITY_ITEM_MAX_REGISTRATION_POINT);
|
|
ADD_PROPERTY_TO_MAP(PROP_CREATED, Created, created, quint64);
|
|
ADD_PROPERTY_TO_MAP(PROP_LAST_EDITED_BY, LastEditedBy, lastEditedBy, QUuid);
|
|
ADD_PROPERTY_TO_MAP(PROP_ENTITY_HOST_TYPE, EntityHostType, entityHostType, entity::HostType);
|
|
ADD_PROPERTY_TO_MAP(PROP_OWNING_AVATAR_ID, OwningAvatarID, owningAvatarID, QUuid);
|
|
ADD_PROPERTY_TO_MAP(PROP_QUERY_AA_CUBE, QueryAACube, queryAACube, AACube);
|
|
ADD_PROPERTY_TO_MAP(PROP_CAN_CAST_SHADOW, CanCastShadow, canCastShadow, bool);
|
|
ADD_PROPERTY_TO_MAP(PROP_VISIBLE_IN_SECONDARY_CAMERA, IsVisibleInSecondaryCamera, isVisibleInSecondaryCamera, bool);
|
|
ADD_PROPERTY_TO_MAP(PROP_RENDER_LAYER, RenderLayer, renderLayer, RenderLayer);
|
|
ADD_PROPERTY_TO_MAP(PROP_PRIMITIVE_MODE, PrimitiveMode, primitiveMode, PrimitiveMode);
|
|
ADD_PROPERTY_TO_MAP(PROP_IGNORE_PICK_INTERSECTION, IgnorePickIntersection, ignorePickIntersection, bool);
|
|
ADD_PROPERTY_TO_MAP(PROP_RENDER_WITH_ZONES, RenderWithZones, renderWithZones, QVector<QUuid>);
|
|
{ // Grab
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_GRABBABLE, Grab, grab, Grabbable, grabbable);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_KINEMATIC, Grab, grab, GrabKinematic, grabKinematic);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_FOLLOWS_CONTROLLER, Grab, grab, GrabFollowsController, grabFollowsController);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_TRIGGERABLE, Grab, grab, Triggerable, triggerable);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_EQUIPPABLE, Grab, grab, Equippable, equippable);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_DELEGATE_TO_PARENT, Grab, grab, GrabDelegateToParent, grabDelegateToParent);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET, Grab, grab,
|
|
EquippableLeftPosition, equippableLeftPosition);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET, Grab, grab,
|
|
EquippableLeftRotation, equippableLeftRotation);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET, Grab, grab,
|
|
EquippableRightPosition, equippableRightPosition);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET, Grab, grab,
|
|
EquippableRightRotation, equippableRightRotation);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_EQUIPPABLE_INDICATOR_URL, Grab, grab,
|
|
EquippableIndicatorURL, equippableIndicatorURL);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, Grab, grab,
|
|
EquippableIndicatorScale, equippableIndicatorScale);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET, Grab, grab,
|
|
EquippableIndicatorOffset, equippableIndicatorOffset);
|
|
}
|
|
|
|
// Physics
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_DENSITY, Density, density, float,
|
|
ENTITY_ITEM_MIN_DENSITY, ENTITY_ITEM_MAX_DENSITY);
|
|
ADD_PROPERTY_TO_MAP(PROP_VELOCITY, Velocity, velocity, vec3);
|
|
ADD_PROPERTY_TO_MAP(PROP_ANGULAR_VELOCITY, AngularVelocity, angularVelocity, vec3);
|
|
ADD_PROPERTY_TO_MAP(PROP_GRAVITY, Gravity, gravity, vec3);
|
|
ADD_PROPERTY_TO_MAP(PROP_ACCELERATION, Acceleration, acceleration, vec3);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_DAMPING, Damping, damping, float,
|
|
ENTITY_ITEM_MIN_DAMPING, ENTITY_ITEM_MAX_DAMPING);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_ANGULAR_DAMPING, AngularDamping, angularDamping, float,
|
|
ENTITY_ITEM_MIN_DAMPING, ENTITY_ITEM_MAX_DAMPING);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_RESTITUTION, Restitution, restitution, float,
|
|
ENTITY_ITEM_MIN_RESTITUTION, ENTITY_ITEM_MAX_RESTITUTION);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_FRICTION, Friction, friction, float,
|
|
ENTITY_ITEM_MIN_FRICTION, ENTITY_ITEM_MAX_FRICTION);
|
|
ADD_PROPERTY_TO_MAP(PROP_LIFETIME, Lifetime, lifetime, float);
|
|
ADD_PROPERTY_TO_MAP(PROP_COLLISIONLESS, Collisionless, collisionless, bool);
|
|
ADD_PROPERTY_TO_MAP(PROP_COLLISIONLESS, unused, ignoreForCollisions, bool); // legacy support
|
|
ADD_PROPERTY_TO_MAP(PROP_COLLISION_MASK, unused, collisionMask, uint16_t);
|
|
ADD_PROPERTY_TO_MAP(PROP_COLLISION_MASK, unused, collidesWith, uint16_t);
|
|
ADD_PROPERTY_TO_MAP(PROP_DYNAMIC, unused, collisionsWillMove, bool); // legacy support
|
|
ADD_PROPERTY_TO_MAP(PROP_DYNAMIC, unused, dynamic, bool);
|
|
ADD_PROPERTY_TO_MAP(PROP_COLLISION_SOUND_URL, CollisionSoundURL, collisionSoundURL, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_ACTION_DATA, ActionData, actionData, QByteArray);
|
|
|
|
// Cloning
|
|
ADD_PROPERTY_TO_MAP(PROP_CLONEABLE, Cloneable, cloneable, bool);
|
|
ADD_PROPERTY_TO_MAP(PROP_CLONE_LIFETIME, CloneLifetime, cloneLifetime, float);
|
|
ADD_PROPERTY_TO_MAP(PROP_CLONE_LIMIT, CloneLimit, cloneLimit, float);
|
|
ADD_PROPERTY_TO_MAP(PROP_CLONE_DYNAMIC, CloneDynamic, cloneDynamic, bool);
|
|
ADD_PROPERTY_TO_MAP(PROP_CLONE_AVATAR_ENTITY, CloneAvatarEntity, cloneAvatarEntity, bool);
|
|
ADD_PROPERTY_TO_MAP(PROP_CLONE_ORIGIN_ID, CloneOriginID, cloneOriginID, QUuid);
|
|
|
|
// Scripts
|
|
ADD_PROPERTY_TO_MAP(PROP_SCRIPT, Script, script, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_SCRIPT_TIMESTAMP, ScriptTimestamp, scriptTimestamp, quint64);
|
|
ADD_PROPERTY_TO_MAP(PROP_SERVER_SCRIPTS, ServerScripts, serverScripts, QString);
|
|
|
|
// Certifiable Properties
|
|
ADD_PROPERTY_TO_MAP(PROP_ITEM_NAME, ItemName, itemName, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_ITEM_DESCRIPTION, ItemDescription, itemDescription, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_ITEM_CATEGORIES, ItemCategories, itemCategories, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_ITEM_ARTIST, ItemArtist, itemArtist, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_ITEM_LICENSE, ItemLicense, itemLicense, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_LIMITED_RUN, LimitedRun, limitedRun, quint32);
|
|
ADD_PROPERTY_TO_MAP(PROP_MARKETPLACE_ID, MarketplaceID, marketplaceID, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_EDITION_NUMBER, EditionNumber, editionNumber, quint32);
|
|
ADD_PROPERTY_TO_MAP(PROP_ENTITY_INSTANCE_NUMBER, EntityInstanceNumber, entityInstanceNumber, quint32);
|
|
ADD_PROPERTY_TO_MAP(PROP_CERTIFICATE_ID, CertificateID, certificateID, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_CERTIFICATE_TYPE, CertificateType, certificateType, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_STATIC_CERTIFICATE_VERSION, StaticCertificateVersion, staticCertificateVersion, quint32);
|
|
|
|
// Local script props
|
|
ADD_PROPERTY_TO_MAP(PROP_LOCAL_POSITION, LocalPosition, localPosition, vec3);
|
|
ADD_PROPERTY_TO_MAP(PROP_LOCAL_ROTATION, LocalRotation, localRotation, quat);
|
|
ADD_PROPERTY_TO_MAP(PROP_LOCAL_VELOCITY, LocalVelocity, localVelocity, vec3);
|
|
ADD_PROPERTY_TO_MAP(PROP_LOCAL_ANGULAR_VELOCITY, LocalAngularVelocity, localAngularVelocity, vec3);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_LOCAL_DIMENSIONS, LocalDimensions, localDimensions, vec3,
|
|
ENTITY_ITEM_MIN_DIMENSION, FLT_MAX);
|
|
|
|
// Common
|
|
ADD_PROPERTY_TO_MAP(PROP_SHAPE_TYPE, ShapeType, shapeType, ShapeType);
|
|
ADD_PROPERTY_TO_MAP(PROP_COMPOUND_SHAPE_URL, CompoundShapeURL, compoundShapeURL, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_COLOR, Color, color, u8vec3Color);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_ALPHA, Alpha, alpha, float, particle::MINIMUM_ALPHA, particle::MAXIMUM_ALPHA);
|
|
{ // Pulse
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_PULSE_MIN, Pulse, pulse, Min, min);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_PULSE_MAX, Pulse, pulse, Max, max);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_PULSE_PERIOD, Pulse, pulse, Period, period);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_PULSE_COLOR_MODE, Pulse, pulse, ColorMode, colorMode);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_PULSE_ALPHA_MODE, Pulse, pulse, AlphaMode, alphaMode);
|
|
}
|
|
ADD_PROPERTY_TO_MAP(PROP_TEXTURES, Textures, textures, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_BILLBOARD_MODE, BillboardMode, billboardMode, BillboardMode);
|
|
|
|
// Particles
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_MAX_PARTICLES, MaxParticles, maxParticles, quint32,
|
|
particle::MINIMUM_MAX_PARTICLES, particle::MAXIMUM_MAX_PARTICLES);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_LIFESPAN, Lifespan, lifespan, float,
|
|
particle::MINIMUM_LIFESPAN, particle::MAXIMUM_LIFESPAN);
|
|
ADD_PROPERTY_TO_MAP(PROP_EMITTING_PARTICLES, IsEmitting, isEmitting, bool);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_EMIT_RATE, EmitRate, emitRate, float,
|
|
particle::MINIMUM_EMIT_RATE, particle::MAXIMUM_EMIT_RATE);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_EMIT_SPEED, EmitSpeed, emitSpeed, vec3,
|
|
particle::MINIMUM_EMIT_SPEED, particle::MAXIMUM_EMIT_SPEED);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_SPEED_SPREAD, SpeedSpread, speedSpread, vec3,
|
|
particle::MINIMUM_EMIT_SPEED, particle::MAXIMUM_EMIT_SPEED);
|
|
ADD_PROPERTY_TO_MAP(PROP_EMIT_ORIENTATION, EmitOrientation, emitOrientation, quat);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_EMIT_DIMENSIONS, EmitDimensions, emitDimensions, vec3,
|
|
particle::MINIMUM_EMIT_DIMENSION, particle::MAXIMUM_EMIT_DIMENSION);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_EMIT_RADIUS_START, EmitRadiusStart, emitRadiusStart, float,
|
|
particle::MINIMUM_EMIT_RADIUS_START, particle::MAXIMUM_EMIT_RADIUS_START);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_POLAR_START, EmitPolarStart, polarStart, float,
|
|
particle::MINIMUM_POLAR, particle::MAXIMUM_POLAR);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_POLAR_FINISH, EmitPolarFinish, polarFinish, float,
|
|
particle::MINIMUM_POLAR, particle::MAXIMUM_POLAR);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_AZIMUTH_START, EmitAzimuthStart, azimuthStart, float,
|
|
particle::MINIMUM_AZIMUTH, particle::MAXIMUM_AZIMUTH);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_AZIMUTH_FINISH, EmitAzimuthFinish, azimuthFinish, float,
|
|
particle::MINIMUM_AZIMUTH, particle::MAXIMUM_AZIMUTH);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_EMIT_ACCELERATION, EmitAcceleration, emitAcceleration, vec3,
|
|
particle::MINIMUM_EMIT_ACCELERATION, particle::MAXIMUM_EMIT_ACCELERATION);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_ACCELERATION_SPREAD, AccelerationSpread, accelerationSpread, vec3,
|
|
particle::MINIMUM_ACCELERATION_SPREAD, particle::MAXIMUM_ACCELERATION_SPREAD);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_PARTICLE_RADIUS, ParticleRadius, particleRadius, float,
|
|
particle::MINIMUM_PARTICLE_RADIUS, particle::MAXIMUM_PARTICLE_RADIUS);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_RADIUS_SPREAD, RadiusSpread, radiusSpread, float,
|
|
particle::MINIMUM_PARTICLE_RADIUS, particle::MAXIMUM_PARTICLE_RADIUS);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_RADIUS_START, RadiusStart, radiusStart, float,
|
|
particle::MINIMUM_PARTICLE_RADIUS, particle::MAXIMUM_PARTICLE_RADIUS);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_RADIUS_FINISH, RadiusFinish, radiusFinish, float,
|
|
particle::MINIMUM_PARTICLE_RADIUS, particle::MAXIMUM_PARTICLE_RADIUS);
|
|
ADD_PROPERTY_TO_MAP(PROP_COLOR_SPREAD, ColorSpread, colorSpread, u8vec3Color);
|
|
ADD_PROPERTY_TO_MAP(PROP_COLOR_START, ColorStart, colorStart, vec3Color);
|
|
ADD_PROPERTY_TO_MAP(PROP_COLOR_FINISH, ColorFinish, colorFinish, vec3Color);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_ALPHA_SPREAD, AlphaSpread, alphaSpread, float,
|
|
particle::MINIMUM_ALPHA, particle::MAXIMUM_ALPHA);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_ALPHA_START, AlphaStart, alphaStart, float,
|
|
particle::MINIMUM_ALPHA, particle::MAXIMUM_ALPHA);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_ALPHA_FINISH, AlphaFinish, alphaFinish, float,
|
|
particle::MINIMUM_ALPHA, particle::MAXIMUM_ALPHA);
|
|
ADD_PROPERTY_TO_MAP(PROP_EMITTER_SHOULD_TRAIL, EmitterShouldTrail, emitterShouldTrail, bool);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_PARTICLE_SPIN, ParticleSpin, particleSpin, float,
|
|
particle::MINIMUM_PARTICLE_SPIN, particle::MAXIMUM_PARTICLE_SPIN);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_SPIN_SPREAD, SpinSpread, spinSpread, float,
|
|
particle::MINIMUM_PARTICLE_SPIN, particle::MAXIMUM_PARTICLE_SPIN);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_SPIN_START, SpinStart, spinStart, float,
|
|
particle::MINIMUM_PARTICLE_SPIN, particle::MAXIMUM_PARTICLE_SPIN);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_SPIN_FINISH, SpinFinish, spinFinish, float,
|
|
particle::MINIMUM_PARTICLE_SPIN, particle::MAXIMUM_PARTICLE_SPIN);
|
|
ADD_PROPERTY_TO_MAP(PROP_PARTICLE_ROTATE_WITH_ENTITY, RotateWithEntity, rotateWithEntity, float);
|
|
|
|
// Model
|
|
ADD_PROPERTY_TO_MAP(PROP_MODEL_URL, ModelURL, modelURL, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_MODEL_SCALE, ModelScale, modelScale, vec3);
|
|
ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS_SET, JointRotationsSet, jointRotationsSet, QVector<bool>);
|
|
ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector<quat>);
|
|
ADD_PROPERTY_TO_MAP(PROP_JOINT_TRANSLATIONS_SET, JointTranslationsSet, jointTranslationsSet, QVector<bool>);
|
|
ADD_PROPERTY_TO_MAP(PROP_JOINT_TRANSLATIONS, JointTranslations, jointTranslations, QVector<vec3>);
|
|
ADD_PROPERTY_TO_MAP(PROP_RELAY_PARENT_JOINTS, RelayParentJoints, relayParentJoints, bool);
|
|
ADD_PROPERTY_TO_MAP(PROP_GROUP_CULLED, GroupCulled, groupCulled, bool);
|
|
{ // Animation
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_URL, Animation, animation, URL, url);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_ALLOW_TRANSLATION, Animation, animation, AllowTranslation, allowTranslation);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_FPS, Animation, animation, FPS, fps);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_FRAME_INDEX, Animation, animation, CurrentFrame, currentFrame);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_PLAYING, Animation, animation, Running, running);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_LOOP, Animation, animation, Loop, loop);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold);
|
|
}
|
|
|
|
// Light
|
|
ADD_PROPERTY_TO_MAP(PROP_IS_SPOTLIGHT, IsSpotlight, isSpotlight, bool);
|
|
ADD_PROPERTY_TO_MAP(PROP_INTENSITY, Intensity, intensity, float);
|
|
ADD_PROPERTY_TO_MAP(PROP_EXPONENT, Exponent, exponent, float);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_CUTOFF, Cutoff, cutoff, float,
|
|
LightEntityItem::MIN_CUTOFF, LightEntityItem::MAX_CUTOFF);
|
|
ADD_PROPERTY_TO_MAP(PROP_FALLOFF_RADIUS, FalloffRadius, falloffRadius, float);
|
|
|
|
// Text
|
|
ADD_PROPERTY_TO_MAP(PROP_TEXT, Text, text, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_LINE_HEIGHT, LineHeight, lineHeight, float);
|
|
ADD_PROPERTY_TO_MAP(PROP_TEXT_COLOR, TextColor, textColor, u8vec3Color);
|
|
ADD_PROPERTY_TO_MAP(PROP_TEXT_ALPHA, TextAlpha, textAlpha, float);
|
|
ADD_PROPERTY_TO_MAP(PROP_BACKGROUND_COLOR, BackgroundColor, backgroundColor, u8vec3Color);
|
|
ADD_PROPERTY_TO_MAP(PROP_BACKGROUND_ALPHA, BackgroundAlpha, backgroundAlpha, float);
|
|
ADD_PROPERTY_TO_MAP(PROP_LEFT_MARGIN, LeftMargin, leftMargin, float);
|
|
ADD_PROPERTY_TO_MAP(PROP_RIGHT_MARGIN, RightMargin, rightMargin, float);
|
|
ADD_PROPERTY_TO_MAP(PROP_TOP_MARGIN, TopMargin, topMargin, float);
|
|
ADD_PROPERTY_TO_MAP(PROP_BOTTOM_MARGIN, BottomMargin, bottomMargin, float);
|
|
ADD_PROPERTY_TO_MAP(PROP_UNLIT, Unlit, unlit, bool);
|
|
ADD_PROPERTY_TO_MAP(PROP_FONT, Font, font, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_TEXT_EFFECT, TextEffect, textEffect, TextEffect);
|
|
ADD_PROPERTY_TO_MAP(PROP_TEXT_EFFECT_COLOR, TextEffectColor, textEffectColor, u8vec3Color);
|
|
ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_TEXT_EFFECT_THICKNESS, TextEffectThickness, textEffectThickness, float, 0.0, 0.5);
|
|
|
|
// Zone
|
|
{ // Keylight
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_KEYLIGHT_COLOR, KeyLight, keyLight, Color, color);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_KEYLIGHT_INTENSITY, KeyLight, keyLight, Intensity, intensity);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_KEYLIGHT_DIRECTION, KeyLight, keylight, Direction, direction);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_KEYLIGHT_CAST_SHADOW, KeyLight, keyLight, CastShadows, castShadows);
|
|
ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_KEYLIGHT_SHADOW_BIAS, KeyLight, keyLight, ShadowBias, shadowBias, 0.0f, 1.0f);
|
|
ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_KEYLIGHT_SHADOW_MAX_DISTANCE, KeyLight, keyLight, ShadowMaxDistance, shadowMaxDistance, 1.0f, 250.0f);
|
|
}
|
|
{ // Ambient light
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_AMBIENT_LIGHT_INTENSITY, AmbientLight, ambientLight, Intensity, intensity);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_AMBIENT_LIGHT_URL, AmbientLight, ambientLight, URL, url);
|
|
}
|
|
{ // Skybox
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_SKYBOX_COLOR, Skybox, skybox, Color, color);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_SKYBOX_URL, Skybox, skybox, URL, url);
|
|
}
|
|
{ // Haze
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_RANGE, Haze, haze, HazeRange, hazeRange);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_COLOR, Haze, haze, HazeColor, hazeColor);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_GLARE_COLOR, Haze, haze, HazeGlareColor, hazeGlareColor);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_ENABLE_GLARE, Haze, haze, HazeEnableGlare, hazeEnableGlare);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_GLARE_ANGLE, Haze, haze, HazeGlareAngle, hazeGlareAngle);
|
|
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_ALTITUDE_EFFECT, Haze, haze, HazeAltitudeEffect, hazeAltitudeEfect);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_CEILING, Haze, haze, HazeCeiling, hazeCeiling);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_BASE_REF, Haze, haze, HazeBaseRef, hazeBaseRef);
|
|
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_BACKGROUND_BLEND, Haze, haze, HazeBackgroundBlend, hazeBackgroundBlend);
|
|
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_ATTENUATE_KEYLIGHT, Haze, haze, HazeAttenuateKeyLight, hazeAttenuateKeyLight);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_KEYLIGHT_RANGE, Haze, haze, HazeKeyLightRange, hazeKeyLightRange);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_KEYLIGHT_ALTITUDE, Haze, haze, HazeKeyLightAltitude, hazeKeyLightAltitude);
|
|
}
|
|
{ // Bloom
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_BLOOM_INTENSITY, Bloom, bloom, BloomIntensity, bloomIntensity);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_BLOOM_THRESHOLD, Bloom, bloom, BloomThreshold, bloomThreshold);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_BLOOM_SIZE, Bloom, bloom, BloomSize, bloomSize);
|
|
}
|
|
ADD_PROPERTY_TO_MAP(PROP_FLYING_ALLOWED, FlyingAllowed, flyingAllowed, bool);
|
|
ADD_PROPERTY_TO_MAP(PROP_GHOSTING_ALLOWED, GhostingAllowed, ghostingAllowed, bool);
|
|
ADD_PROPERTY_TO_MAP(PROP_FILTER_URL, FilterURL, filterURL, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_KEY_LIGHT_MODE, KeyLightMode, keyLightMode, uint32_t);
|
|
ADD_PROPERTY_TO_MAP(PROP_AMBIENT_LIGHT_MODE, AmbientLightMode, ambientLightMode, uint32_t);
|
|
ADD_PROPERTY_TO_MAP(PROP_SKYBOX_MODE, SkyboxMode, skyboxMode, uint32_t);
|
|
ADD_PROPERTY_TO_MAP(PROP_HAZE_MODE, HazeMode, hazeMode, uint32_t);
|
|
ADD_PROPERTY_TO_MAP(PROP_BLOOM_MODE, BloomMode, bloomMode, uint32_t);
|
|
ADD_PROPERTY_TO_MAP(PROP_AVATAR_PRIORITY, AvatarPriority, avatarPriority, uint32_t);
|
|
ADD_PROPERTY_TO_MAP(PROP_SCREENSHARE, Screenshare, screenshare, uint32_t);
|
|
|
|
// Polyvox
|
|
ADD_PROPERTY_TO_MAP(PROP_VOXEL_VOLUME_SIZE, VoxelVolumeSize, voxelVolumeSize, vec3);
|
|
ADD_PROPERTY_TO_MAP(PROP_VOXEL_DATA, VoxelData, voxelData, QByteArray);
|
|
ADD_PROPERTY_TO_MAP(PROP_VOXEL_SURFACE_STYLE, VoxelSurfaceStyle, voxelSurfaceStyle, uint16_t);
|
|
ADD_PROPERTY_TO_MAP(PROP_X_TEXTURE_URL, XTextureURL, xTextureURL, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_Y_TEXTURE_URL, YTextureURL, yTextureURL, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_Z_TEXTURE_URL, ZTextureURL, zTextureURL, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_X_N_NEIGHBOR_ID, XNNeighborID, xNNeighborID, EntityItemID);
|
|
ADD_PROPERTY_TO_MAP(PROP_Y_N_NEIGHBOR_ID, YNNeighborID, yNNeighborID, EntityItemID);
|
|
ADD_PROPERTY_TO_MAP(PROP_Z_N_NEIGHBOR_ID, ZNNeighborID, zNNeighborID, EntityItemID);
|
|
ADD_PROPERTY_TO_MAP(PROP_X_P_NEIGHBOR_ID, XPNeighborID, xPNeighborID, EntityItemID);
|
|
ADD_PROPERTY_TO_MAP(PROP_Y_P_NEIGHBOR_ID, YPNeighborID, yPNeighborID, EntityItemID);
|
|
ADD_PROPERTY_TO_MAP(PROP_Z_P_NEIGHBOR_ID, ZPNeighborID, zPNeighborID, EntityItemID);
|
|
|
|
// Web
|
|
ADD_PROPERTY_TO_MAP(PROP_SOURCE_URL, SourceUrl, sourceUrl, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_DPI, DPI, dpi, uint16_t);
|
|
ADD_PROPERTY_TO_MAP(PROP_SCRIPT_URL, ScriptURL, scriptURL, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_MAX_FPS, MaxFPS, maxFPS, uint8_t);
|
|
ADD_PROPERTY_TO_MAP(PROP_INPUT_MODE, InputMode, inputMode, WebInputMode);
|
|
ADD_PROPERTY_TO_MAP(PROP_SHOW_KEYBOARD_FOCUS_HIGHLIGHT, ShowKeyboardFocusHighlight, showKeyboardFocusHighlight, bool);
|
|
|
|
// Polyline
|
|
ADD_PROPERTY_TO_MAP(PROP_LINE_POINTS, LinePoints, linePoints, QVector<vec3>);
|
|
ADD_PROPERTY_TO_MAP(PROP_STROKE_WIDTHS, StrokeWidths, strokeWidths, QVector<float>);
|
|
ADD_PROPERTY_TO_MAP(PROP_STROKE_NORMALS, Normals, normals, QVector<vec3>);
|
|
ADD_PROPERTY_TO_MAP(PROP_STROKE_COLORS, StrokeColors, strokeColors, QVector<vec3>);
|
|
ADD_PROPERTY_TO_MAP(PROP_IS_UV_MODE_STRETCH, IsUVModeStretch, isUVModeStretch, QVector<float>);
|
|
ADD_PROPERTY_TO_MAP(PROP_LINE_GLOW, Glow, glow, bool);
|
|
ADD_PROPERTY_TO_MAP(PROP_LINE_FACE_CAMERA, FaceCamera, faceCamera, bool);
|
|
|
|
// Shape
|
|
ADD_PROPERTY_TO_MAP(PROP_SHAPE, Shape, shape, QString);
|
|
|
|
// Material
|
|
ADD_PROPERTY_TO_MAP(PROP_MATERIAL_URL, MaterialURL, materialURL, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_MATERIAL_MAPPING_MODE, MaterialMappingMode, materialMappingMode, MaterialMappingMode);
|
|
ADD_PROPERTY_TO_MAP(PROP_MATERIAL_PRIORITY, Priority, priority, quint16);
|
|
ADD_PROPERTY_TO_MAP(PROP_PARENT_MATERIAL_NAME, ParentMaterialName, parentMaterialName, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_MATERIAL_MAPPING_POS, MaterialMappingPos, materialMappingPos, vec2);
|
|
ADD_PROPERTY_TO_MAP(PROP_MATERIAL_MAPPING_SCALE, MaterialMappingScale, materialMappingScale, vec2);
|
|
ADD_PROPERTY_TO_MAP(PROP_MATERIAL_MAPPING_ROT, MaterialMappingRot, materialMappingRot, float);
|
|
ADD_PROPERTY_TO_MAP(PROP_MATERIAL_DATA, MaterialData, materialData, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_MATERIAL_REPEAT, MaterialRepeat, materialRepeat, bool);
|
|
|
|
// Image
|
|
ADD_PROPERTY_TO_MAP(PROP_IMAGE_URL, ImageURL, imageURL, QString);
|
|
ADD_PROPERTY_TO_MAP(PROP_EMISSIVE, Emissive, emissive, bool);
|
|
ADD_PROPERTY_TO_MAP(PROP_KEEP_ASPECT_RATIO, KeepAspectRatio, keepAspectRatio, bool);
|
|
ADD_PROPERTY_TO_MAP(PROP_SUB_IMAGE, SubImage, subImage, QRect);
|
|
|
|
// Grid
|
|
ADD_PROPERTY_TO_MAP(PROP_GRID_FOLLOW_CAMERA, FollowCamera, followCamera, bool);
|
|
ADD_PROPERTY_TO_MAP(PROP_MAJOR_GRID_EVERY, MajorGridEvery, majorGridEvery, uint32_t);
|
|
ADD_PROPERTY_TO_MAP(PROP_MINOR_GRID_EVERY, MinorGridEvery, minorGridEvery, float);
|
|
|
|
// Gizmo
|
|
ADD_PROPERTY_TO_MAP(PROP_GIZMO_TYPE, GizmoType, gizmoType, GizmoType);
|
|
{ // RingGizmo
|
|
ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_START_ANGLE, Ring, ring, StartAngle, startAngle, RingGizmoPropertyGroup::MIN_ANGLE, RingGizmoPropertyGroup::MAX_ANGLE);
|
|
ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_END_ANGLE, Ring, ring, EndAngle, endAngle, RingGizmoPropertyGroup::MIN_ANGLE, RingGizmoPropertyGroup::MAX_ANGLE);
|
|
ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_INNER_RADIUS, Ring, ring, InnerRadius, innerRadius, RingGizmoPropertyGroup::MIN_RADIUS, RingGizmoPropertyGroup::MAX_RADIUS);
|
|
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_INNER_START_COLOR, Ring, ring, InnerStartColor, innerStartColor);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_INNER_END_COLOR, Ring, ring, InnerEndColor, innerEndColor);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_OUTER_START_COLOR, Ring, ring, OuterStartColor, outerStartColor);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_OUTER_END_COLOR, Ring, ring, OuterEndColor, outerEndColor);
|
|
|
|
ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_INNER_START_ALPHA, Ring, ring, InnerStartAlpha, innerStartAlpha, RingGizmoPropertyGroup::MIN_ALPHA, RingGizmoPropertyGroup::MAX_ALPHA);
|
|
ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_INNER_END_ALPHA, Ring, ring, InnerEndAlpha, innerEndAlpha, RingGizmoPropertyGroup::MIN_ALPHA, RingGizmoPropertyGroup::MAX_ALPHA);
|
|
ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_OUTER_START_ALPHA, Ring, ring, OuterStartAlpha, outerStartAlpha, RingGizmoPropertyGroup::MIN_ALPHA, RingGizmoPropertyGroup::MAX_ALPHA);
|
|
ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_OUTER_END_ALPHA, Ring, ring, OuterEndAlpha, outerEndAlpha, RingGizmoPropertyGroup::MIN_ALPHA, RingGizmoPropertyGroup::MAX_ALPHA);
|
|
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAS_TICK_MARKS, Ring, ring, HasTickMarks, hasTickMarks);
|
|
ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_MAJOR_TICK_MARKS_ANGLE, Ring, ring, MajorTickMarksAngle, majorTickMarksAngle, RingGizmoPropertyGroup::MIN_ANGLE, RingGizmoPropertyGroup::MAX_ANGLE);
|
|
ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(PROP_MINOR_TICK_MARKS_ANGLE, Ring, ring, MinorTickMarksAngle, minorTickMarksAngle, RingGizmoPropertyGroup::MIN_ANGLE, RingGizmoPropertyGroup::MAX_ANGLE);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_MAJOR_TICK_MARKS_LENGTH, Ring, ring, MajorTickMarksLength, majorTickMarksLength);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_MINOR_TICK_MARKS_LENGTH, Ring, ring, MinorTickMarksLength, minorTickMarksLength);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_MAJOR_TICK_MARKS_COLOR, Ring, ring, MajorTickMarksColor, majorTickMarksColor);
|
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_MINOR_TICK_MARKS_COLOR, Ring, ring, MinorTickMarksColor, minorTickMarksColor);
|
|
}
|
|
});
|
|
|
|
auto iter = _propertyInfos.find(propertyName);
|
|
if (iter != _propertyInfos.end()) {
|
|
propertyInfo = *iter;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**jsdoc
|
|
* Information about an entity property.
|
|
* @typedef {object} Entities.EntityPropertyInfo
|
|
* @property {number} propertyEnum - The internal number of the property.
|
|
* @property {string} minimum - The minimum numerical value the property may have, if available, otherwise <code>""</code>.
|
|
* @property {string} maximum - The maximum numerical value the property may have, if available, otherwise <code>""</code>.
|
|
*/
|
|
QScriptValue EntityPropertyInfoToScriptValue(QScriptEngine* engine, const EntityPropertyInfo& propertyInfo) {
|
|
QScriptValue obj = engine->newObject();
|
|
obj.setProperty("propertyEnum", propertyInfo.propertyEnum);
|
|
obj.setProperty("minimum", propertyInfo.minimum.toString());
|
|
obj.setProperty("maximum", propertyInfo.maximum.toString());
|
|
return obj;
|
|
}
|
|
|
|
void EntityPropertyInfoFromScriptValue(const QScriptValue& object, EntityPropertyInfo& propertyInfo) {
|
|
propertyInfo.propertyEnum = (EntityPropertyList)object.property("propertyEnum").toVariant().toUInt();
|
|
propertyInfo.minimum = object.property("minimum").toVariant();
|
|
propertyInfo.maximum = object.property("maximum").toVariant();
|
|
}
|
|
|
|
// TODO: Implement support for edit packets that can span an MTU sized buffer. We need to implement a mechanism for the
|
|
// encodeEntityEditPacket() method to communicate the the caller which properties couldn't fit in the buffer. Similar
|
|
// to how we handle this in the Octree streaming case.
|
|
//
|
|
// TODO: Right now, all possible properties for all subclasses are handled here. Ideally we'd prefer
|
|
// to handle this in a more generic way. Allowing subclasses of EntityItem to register their properties
|
|
//
|
|
// TODO: There's a lot of repeated patterns in the code below to handle each property. It would be nice if the property
|
|
// registration mechanism allowed us to collapse these repeated sections of code into a single implementation that
|
|
// utilized the registration table to shorten up and simplify this code.
|
|
//
|
|
// TODO: Implement support for paged properties, spanning MTU, and custom properties
|
|
//
|
|
// TODO: Implement support for script and visible properties.
|
|
//
|
|
OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItemID id, const EntityItemProperties& properties,
|
|
QByteArray& buffer, EntityPropertyFlags requestedProperties, EntityPropertyFlags& didntFitProperties) {
|
|
|
|
OctreePacketData ourDataPacket(false, buffer.size()); // create a packetData object to add out packet details too.
|
|
OctreePacketData* packetData = &ourDataPacket; // we want a pointer to this so we can use our APPEND_ENTITY_PROPERTY macro
|
|
|
|
bool success = true; // assume the best
|
|
OctreeElement::AppendState appendState = OctreeElement::COMPLETED; // assume the best
|
|
|
|
// TODO: We need to review how jurisdictions should be handled for entities. (The old Models and Particles code
|
|
// didn't do anything special for jurisdictions, so we're keeping that same behavior here.)
|
|
//
|
|
// Always include the root octcode. This is only because the OctreeEditPacketSender will check these octcodes
|
|
// to determine which server to send the changes to in the case of multiple jurisdictions. The root will be sent
|
|
// to all servers.
|
|
vec3 rootPosition(0);
|
|
float rootScale = 0.5f;
|
|
unsigned char* octcode = pointToOctalCode(rootPosition.x, rootPosition.y, rootPosition.z, rootScale);
|
|
|
|
success = packetData->startSubTree(octcode);
|
|
delete[] octcode;
|
|
|
|
// assuming we have room to fit our octalCode, proceed...
|
|
if (success) {
|
|
|
|
// Now add our edit content details...
|
|
|
|
// id
|
|
// encode our ID as a byte count coded byte stream
|
|
QByteArray encodedID = id.toRfc4122(); // NUM_BYTES_RFC4122_UUID
|
|
|
|
// encode our ID as a byte count coded byte stream
|
|
ByteCountCoded<quint32> tokenCoder;
|
|
QByteArray encodedToken;
|
|
|
|
// encode our type as a byte count coded byte stream
|
|
ByteCountCoded<quint32> typeCoder = (quint32)properties.getType();
|
|
QByteArray encodedType = typeCoder;
|
|
|
|
quint64 updateDelta = 0; // this is an edit so by definition, it's update is in sync
|
|
ByteCountCoded<quint64> updateDeltaCoder = updateDelta;
|
|
QByteArray encodedUpdateDelta = updateDeltaCoder;
|
|
|
|
EntityPropertyFlags propertyFlags(PROP_LAST_ITEM);
|
|
EntityPropertyFlags propertiesDidntFit = requestedProperties;
|
|
|
|
LevelDetails entityLevel = packetData->startLevel();
|
|
|
|
// Last Edited quint64 always first, before any other details, which allows us easy access to adjusting this
|
|
// timestamp for clock skew
|
|
quint64 lastEdited = properties.getLastEdited();
|
|
bool successLastEditedFits = packetData->appendValue(lastEdited);
|
|
|
|
bool successIDFits = packetData->appendRawData(encodedID);
|
|
if (successIDFits) {
|
|
successIDFits = packetData->appendRawData(encodedToken);
|
|
}
|
|
bool successTypeFits = packetData->appendRawData(encodedType);
|
|
|
|
// NOTE: We intentionally do not send "created" times in edit messages. This is because:
|
|
// 1) if the edit is to an existing entity, the created time can not be changed
|
|
// 2) if the edit is to a new entity, the created time is the last edited time
|
|
|
|
// TODO: Should we get rid of this in this in edit packets, since this has to always be 0?
|
|
bool successLastUpdatedFits = packetData->appendRawData(encodedUpdateDelta);
|
|
|
|
int propertyFlagsOffset = packetData->getUncompressedByteOffset();
|
|
QByteArray encodedPropertyFlags = propertyFlags;
|
|
int oldPropertyFlagsLength = encodedPropertyFlags.length();
|
|
bool successPropertyFlagsFits = packetData->appendRawData(encodedPropertyFlags);
|
|
int propertyCount = 0;
|
|
|
|
bool headerFits = successIDFits && successTypeFits && successLastEditedFits &&
|
|
successLastUpdatedFits && successPropertyFlagsFits;
|
|
|
|
int startOfEntityItemData = packetData->getUncompressedByteOffset();
|
|
|
|
if (headerFits) {
|
|
bool successPropertyFits;
|
|
propertyFlags -= PROP_LAST_ITEM; // clear the last item for now, we may or may not set it as the actual item
|
|
|
|
// These items would go here once supported....
|
|
// PROP_PAGED_PROPERTY,
|
|
// PROP_CUSTOM_PROPERTIES_INCLUDED,
|
|
|
|
|
|
APPEND_ENTITY_PROPERTY(PROP_SIMULATION_OWNER, properties._simulationOwner.toByteArray());
|
|
APPEND_ENTITY_PROPERTY(PROP_PARENT_ID, properties.getParentID());
|
|
APPEND_ENTITY_PROPERTY(PROP_PARENT_JOINT_INDEX, properties.getParentJointIndex());
|
|
APPEND_ENTITY_PROPERTY(PROP_VISIBLE, properties.getVisible());
|
|
APPEND_ENTITY_PROPERTY(PROP_NAME, properties.getName());
|
|
APPEND_ENTITY_PROPERTY(PROP_LOCKED, properties.getLocked());
|
|
APPEND_ENTITY_PROPERTY(PROP_USER_DATA, properties.getUserData());
|
|
APPEND_ENTITY_PROPERTY(PROP_PRIVATE_USER_DATA, properties.getPrivateUserData());
|
|
APPEND_ENTITY_PROPERTY(PROP_HREF, properties.getHref());
|
|
APPEND_ENTITY_PROPERTY(PROP_DESCRIPTION, properties.getDescription());
|
|
APPEND_ENTITY_PROPERTY(PROP_POSITION, properties.getPosition());
|
|
APPEND_ENTITY_PROPERTY(PROP_DIMENSIONS, properties.getDimensions());
|
|
APPEND_ENTITY_PROPERTY(PROP_ROTATION, properties.getRotation());
|
|
APPEND_ENTITY_PROPERTY(PROP_REGISTRATION_POINT, properties.getRegistrationPoint());
|
|
APPEND_ENTITY_PROPERTY(PROP_CREATED, properties.getCreated());
|
|
APPEND_ENTITY_PROPERTY(PROP_LAST_EDITED_BY, properties.getLastEditedBy());
|
|
// APPEND_ENTITY_PROPERTY(PROP_ENTITY_HOST_TYPE, (uint32_t)properties.getEntityHostType()); // not sent over the wire
|
|
// APPEND_ENTITY_PROPERTY(PROP_OWNING_AVATAR_ID, properties.getOwningAvatarID()); // not sent over the wire
|
|
APPEND_ENTITY_PROPERTY(PROP_QUERY_AA_CUBE, properties.getQueryAACube());
|
|
APPEND_ENTITY_PROPERTY(PROP_CAN_CAST_SHADOW, properties.getCanCastShadow());
|
|
// APPEND_ENTITY_PROPERTY(PROP_VISIBLE_IN_SECONDARY_CAMERA, properties.getIsVisibleInSecondaryCamera()); // not sent over the wire
|
|
APPEND_ENTITY_PROPERTY(PROP_RENDER_LAYER, (uint32_t)properties.getRenderLayer());
|
|
APPEND_ENTITY_PROPERTY(PROP_PRIMITIVE_MODE, (uint32_t)properties.getPrimitiveMode());
|
|
APPEND_ENTITY_PROPERTY(PROP_IGNORE_PICK_INTERSECTION, properties.getIgnorePickIntersection());
|
|
APPEND_ENTITY_PROPERTY(PROP_RENDER_WITH_ZONES, properties.getRenderWithZones());
|
|
_staticGrab.setProperties(properties);
|
|
_staticGrab.appendToEditPacket(packetData, requestedProperties, propertyFlags,
|
|
propertiesDidntFit, propertyCount, appendState);
|
|
|
|
// Physics
|
|
APPEND_ENTITY_PROPERTY(PROP_DENSITY, properties.getDensity());
|
|
APPEND_ENTITY_PROPERTY(PROP_VELOCITY, properties.getVelocity());
|
|
APPEND_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, properties.getAngularVelocity());
|
|
APPEND_ENTITY_PROPERTY(PROP_GRAVITY, properties.getGravity());
|
|
APPEND_ENTITY_PROPERTY(PROP_ACCELERATION, properties.getAcceleration());
|
|
APPEND_ENTITY_PROPERTY(PROP_DAMPING, properties.getDamping());
|
|
APPEND_ENTITY_PROPERTY(PROP_ANGULAR_DAMPING, properties.getAngularDamping());
|
|
APPEND_ENTITY_PROPERTY(PROP_RESTITUTION, properties.getRestitution());
|
|
APPEND_ENTITY_PROPERTY(PROP_FRICTION, properties.getFriction());
|
|
APPEND_ENTITY_PROPERTY(PROP_LIFETIME, properties.getLifetime());
|
|
APPEND_ENTITY_PROPERTY(PROP_COLLISIONLESS, properties.getCollisionless());
|
|
APPEND_ENTITY_PROPERTY(PROP_COLLISION_MASK, properties.getCollisionMask());
|
|
APPEND_ENTITY_PROPERTY(PROP_DYNAMIC, properties.getDynamic());
|
|
APPEND_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, properties.getCollisionSoundURL());
|
|
APPEND_ENTITY_PROPERTY(PROP_ACTION_DATA, properties.getActionData());
|
|
|
|
// Cloning
|
|
APPEND_ENTITY_PROPERTY(PROP_CLONEABLE, properties.getCloneable());
|
|
APPEND_ENTITY_PROPERTY(PROP_CLONE_LIFETIME, properties.getCloneLifetime());
|
|
APPEND_ENTITY_PROPERTY(PROP_CLONE_LIMIT, properties.getCloneLimit());
|
|
APPEND_ENTITY_PROPERTY(PROP_CLONE_DYNAMIC, properties.getCloneDynamic());
|
|
APPEND_ENTITY_PROPERTY(PROP_CLONE_AVATAR_ENTITY, properties.getCloneAvatarEntity());
|
|
APPEND_ENTITY_PROPERTY(PROP_CLONE_ORIGIN_ID, properties.getCloneOriginID());
|
|
|
|
// Scripts
|
|
APPEND_ENTITY_PROPERTY(PROP_SCRIPT, properties.getScript());
|
|
APPEND_ENTITY_PROPERTY(PROP_SCRIPT_TIMESTAMP, properties.getScriptTimestamp());
|
|
APPEND_ENTITY_PROPERTY(PROP_SERVER_SCRIPTS, properties.getServerScripts());
|
|
|
|
// Certifiable Properties
|
|
APPEND_ENTITY_PROPERTY(PROP_ITEM_NAME, properties.getItemName());
|
|
APPEND_ENTITY_PROPERTY(PROP_ITEM_DESCRIPTION, properties.getItemDescription());
|
|
APPEND_ENTITY_PROPERTY(PROP_ITEM_CATEGORIES, properties.getItemCategories());
|
|
APPEND_ENTITY_PROPERTY(PROP_ITEM_ARTIST, properties.getItemArtist());
|
|
APPEND_ENTITY_PROPERTY(PROP_ITEM_LICENSE, properties.getItemLicense());
|
|
APPEND_ENTITY_PROPERTY(PROP_LIMITED_RUN, properties.getLimitedRun());
|
|
APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, properties.getMarketplaceID());
|
|
APPEND_ENTITY_PROPERTY(PROP_EDITION_NUMBER, properties.getEditionNumber());
|
|
APPEND_ENTITY_PROPERTY(PROP_ENTITY_INSTANCE_NUMBER, properties.getEntityInstanceNumber());
|
|
APPEND_ENTITY_PROPERTY(PROP_CERTIFICATE_ID, properties.getCertificateID());
|
|
APPEND_ENTITY_PROPERTY(PROP_CERTIFICATE_TYPE, properties.getCertificateType());
|
|
APPEND_ENTITY_PROPERTY(PROP_STATIC_CERTIFICATE_VERSION, properties.getStaticCertificateVersion());
|
|
|
|
if (properties.getType() == EntityTypes::ParticleEffect) {
|
|
APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)(properties.getShapeType()));
|
|
APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, properties.getCompoundShapeURL());
|
|
APPEND_ENTITY_PROPERTY(PROP_COLOR, properties.getColor());
|
|
APPEND_ENTITY_PROPERTY(PROP_ALPHA, properties.getAlpha());
|
|
_staticPulse.setProperties(properties);
|
|
_staticPulse.appendToEditPacket(packetData, requestedProperties, propertyFlags,
|
|
propertiesDidntFit, propertyCount, appendState);
|
|
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, properties.getTextures());
|
|
|
|
APPEND_ENTITY_PROPERTY(PROP_MAX_PARTICLES, properties.getMaxParticles());
|
|
APPEND_ENTITY_PROPERTY(PROP_LIFESPAN, properties.getLifespan());
|
|
|
|
APPEND_ENTITY_PROPERTY(PROP_EMITTING_PARTICLES, properties.getIsEmitting());
|
|
APPEND_ENTITY_PROPERTY(PROP_EMIT_RATE, properties.getEmitRate());
|
|
APPEND_ENTITY_PROPERTY(PROP_EMIT_SPEED, properties.getEmitSpeed());
|
|
APPEND_ENTITY_PROPERTY(PROP_SPEED_SPREAD, properties.getSpeedSpread());
|
|
APPEND_ENTITY_PROPERTY(PROP_EMIT_ORIENTATION, properties.getEmitOrientation());
|
|
APPEND_ENTITY_PROPERTY(PROP_EMIT_DIMENSIONS, properties.getEmitDimensions());
|
|
APPEND_ENTITY_PROPERTY(PROP_EMIT_RADIUS_START, properties.getEmitRadiusStart());
|
|
|
|
APPEND_ENTITY_PROPERTY(PROP_POLAR_START, properties.getPolarStart());
|
|
APPEND_ENTITY_PROPERTY(PROP_POLAR_FINISH, properties.getPolarFinish());
|
|
APPEND_ENTITY_PROPERTY(PROP_AZIMUTH_START, properties.getAzimuthStart());
|
|
APPEND_ENTITY_PROPERTY(PROP_AZIMUTH_FINISH, properties.getAzimuthFinish());
|
|
|
|
APPEND_ENTITY_PROPERTY(PROP_EMIT_ACCELERATION, properties.getEmitAcceleration());
|
|
APPEND_ENTITY_PROPERTY(PROP_ACCELERATION_SPREAD, properties.getAccelerationSpread());
|
|
|
|
APPEND_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, properties.getParticleRadius());
|
|
APPEND_ENTITY_PROPERTY(PROP_RADIUS_SPREAD, properties.getRadiusSpread());
|
|
APPEND_ENTITY_PROPERTY(PROP_RADIUS_START, properties.getRadiusStart());
|
|
APPEND_ENTITY_PROPERTY(PROP_RADIUS_FINISH, properties.getRadiusFinish());
|
|
|
|
APPEND_ENTITY_PROPERTY(PROP_COLOR_SPREAD, properties.getColorSpread());
|
|
APPEND_ENTITY_PROPERTY(PROP_COLOR_START, properties.getColorStart());
|
|
APPEND_ENTITY_PROPERTY(PROP_COLOR_FINISH, properties.getColorFinish());
|
|
|
|
APPEND_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, properties.getAlphaSpread());
|
|
APPEND_ENTITY_PROPERTY(PROP_ALPHA_START, properties.getAlphaStart());
|
|
APPEND_ENTITY_PROPERTY(PROP_ALPHA_FINISH, properties.getAlphaFinish());
|
|
|
|
APPEND_ENTITY_PROPERTY(PROP_EMITTER_SHOULD_TRAIL, properties.getEmitterShouldTrail());
|
|
|
|
APPEND_ENTITY_PROPERTY(PROP_PARTICLE_SPIN, properties.getParticleSpin());
|
|
APPEND_ENTITY_PROPERTY(PROP_SPIN_SPREAD, properties.getSpinSpread());
|
|
APPEND_ENTITY_PROPERTY(PROP_SPIN_START, properties.getSpinStart());
|
|
APPEND_ENTITY_PROPERTY(PROP_SPIN_FINISH, properties.getSpinFinish());
|
|
APPEND_ENTITY_PROPERTY(PROP_PARTICLE_ROTATE_WITH_ENTITY, properties.getRotateWithEntity())
|
|
}
|
|
|
|
if (properties.getType() == EntityTypes::Model) {
|
|
APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)(properties.getShapeType()));
|
|
APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, properties.getCompoundShapeURL());
|
|
APPEND_ENTITY_PROPERTY(PROP_COLOR, properties.getColor());
|
|
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, properties.getTextures());
|
|
|
|
APPEND_ENTITY_PROPERTY(PROP_MODEL_URL, properties.getModelURL());
|
|
APPEND_ENTITY_PROPERTY(PROP_MODEL_SCALE, properties.getModelScale());
|
|
APPEND_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS_SET, properties.getJointRotationsSet());
|
|
APPEND_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS, properties.getJointRotations());
|
|
APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS_SET, properties.getJointTranslationsSet());
|
|
APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS, properties.getJointTranslations());
|
|
APPEND_ENTITY_PROPERTY(PROP_RELAY_PARENT_JOINTS, properties.getRelayParentJoints());
|
|
APPEND_ENTITY_PROPERTY(PROP_GROUP_CULLED, properties.getGroupCulled());
|
|
|
|
_staticAnimation.setProperties(properties);
|
|
_staticAnimation.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
|
}
|
|
|
|
if (properties.getType() == EntityTypes::Light) {
|
|
APPEND_ENTITY_PROPERTY(PROP_COLOR, properties.getColor());
|
|
APPEND_ENTITY_PROPERTY(PROP_IS_SPOTLIGHT, properties.getIsSpotlight());
|
|
APPEND_ENTITY_PROPERTY(PROP_INTENSITY, properties.getIntensity());
|
|
APPEND_ENTITY_PROPERTY(PROP_EXPONENT, properties.getExponent());
|
|
APPEND_ENTITY_PROPERTY(PROP_CUTOFF, properties.getCutoff());
|
|
APPEND_ENTITY_PROPERTY(PROP_FALLOFF_RADIUS, properties.getFalloffRadius());
|
|
}
|
|
|
|
if (properties.getType() == EntityTypes::Text) {
|
|
_staticPulse.setProperties(properties);
|
|
_staticPulse.appendToEditPacket(packetData, requestedProperties, propertyFlags,
|
|
propertiesDidntFit, propertyCount, appendState);
|
|
APPEND_ENTITY_PROPERTY(PROP_BILLBOARD_MODE, (uint32_t)properties.getBillboardMode());
|
|
|
|
APPEND_ENTITY_PROPERTY(PROP_TEXT, properties.getText());
|
|
APPEND_ENTITY_PROPERTY(PROP_LINE_HEIGHT, properties.getLineHeight());
|
|
APPEND_ENTITY_PROPERTY(PROP_TEXT_COLOR, properties.getTextColor());
|
|
APPEND_ENTITY_PROPERTY(PROP_TEXT_ALPHA, properties.getTextAlpha());
|
|
APPEND_ENTITY_PROPERTY(PROP_BACKGROUND_COLOR, properties.getBackgroundColor());
|
|
APPEND_ENTITY_PROPERTY(PROP_BACKGROUND_ALPHA, properties.getBackgroundAlpha());
|
|
APPEND_ENTITY_PROPERTY(PROP_LEFT_MARGIN, properties.getLeftMargin());
|
|
APPEND_ENTITY_PROPERTY(PROP_RIGHT_MARGIN, properties.getRightMargin());
|
|
APPEND_ENTITY_PROPERTY(PROP_TOP_MARGIN, properties.getTopMargin());
|
|
APPEND_ENTITY_PROPERTY(PROP_BOTTOM_MARGIN, properties.getBottomMargin());
|
|
APPEND_ENTITY_PROPERTY(PROP_UNLIT, properties.getUnlit());
|
|
APPEND_ENTITY_PROPERTY(PROP_FONT, properties.getFont());
|
|
APPEND_ENTITY_PROPERTY(PROP_TEXT_EFFECT, (uint32_t)properties.getTextEffect());
|
|
APPEND_ENTITY_PROPERTY(PROP_TEXT_EFFECT_COLOR, properties.getTextEffectColor());
|
|
APPEND_ENTITY_PROPERTY(PROP_TEXT_EFFECT_THICKNESS, properties.getTextEffectThickness());
|
|
}
|
|
|
|
if (properties.getType() == EntityTypes::Zone) {
|
|
APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)properties.getShapeType());
|
|
APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, properties.getCompoundShapeURL());
|
|
|
|
_staticKeyLight.setProperties(properties);
|
|
_staticKeyLight.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
|
|
|
_staticAmbientLight.setProperties(properties);
|
|
_staticAmbientLight.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
|
|
|
_staticSkybox.setProperties(properties);
|
|
_staticSkybox.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
|
|
|
_staticHaze.setProperties(properties);
|
|
_staticHaze.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
|
|
|
_staticBloom.setProperties(properties);
|
|
_staticBloom.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
|
|
|
APPEND_ENTITY_PROPERTY(PROP_FLYING_ALLOWED, properties.getFlyingAllowed());
|
|
APPEND_ENTITY_PROPERTY(PROP_GHOSTING_ALLOWED, properties.getGhostingAllowed());
|
|
APPEND_ENTITY_PROPERTY(PROP_FILTER_URL, properties.getFilterURL());
|
|
|
|
APPEND_ENTITY_PROPERTY(PROP_KEY_LIGHT_MODE, (uint32_t)properties.getKeyLightMode());
|
|
APPEND_ENTITY_PROPERTY(PROP_AMBIENT_LIGHT_MODE, (uint32_t)properties.getAmbientLightMode());
|
|
APPEND_ENTITY_PROPERTY(PROP_SKYBOX_MODE, (uint32_t)properties.getSkyboxMode());
|
|
APPEND_ENTITY_PROPERTY(PROP_HAZE_MODE, (uint32_t)properties.getHazeMode());
|
|
APPEND_ENTITY_PROPERTY(PROP_BLOOM_MODE, (uint32_t)properties.getBloomMode());
|
|
APPEND_ENTITY_PROPERTY(PROP_AVATAR_PRIORITY, (uint32_t)properties.getAvatarPriority());
|
|
APPEND_ENTITY_PROPERTY(PROP_SCREENSHARE, (uint32_t)properties.getScreenshare());
|
|
}
|
|
|
|
if (properties.getType() == EntityTypes::PolyVox) {
|
|
APPEND_ENTITY_PROPERTY(PROP_VOXEL_VOLUME_SIZE, properties.getVoxelVolumeSize());
|
|
APPEND_ENTITY_PROPERTY(PROP_VOXEL_DATA, properties.getVoxelData());
|
|
APPEND_ENTITY_PROPERTY(PROP_VOXEL_SURFACE_STYLE, properties.getVoxelSurfaceStyle());
|
|
APPEND_ENTITY_PROPERTY(PROP_X_TEXTURE_URL, properties.getXTextureURL());
|
|
APPEND_ENTITY_PROPERTY(PROP_Y_TEXTURE_URL, properties.getYTextureURL());
|
|
APPEND_ENTITY_PROPERTY(PROP_Z_TEXTURE_URL, properties.getZTextureURL());
|
|
APPEND_ENTITY_PROPERTY(PROP_X_N_NEIGHBOR_ID, properties.getXNNeighborID());
|
|
APPEND_ENTITY_PROPERTY(PROP_Y_N_NEIGHBOR_ID, properties.getYNNeighborID());
|
|
APPEND_ENTITY_PROPERTY(PROP_Z_N_NEIGHBOR_ID, properties.getZNNeighborID());
|
|
APPEND_ENTITY_PROPERTY(PROP_X_P_NEIGHBOR_ID, properties.getXPNeighborID());
|
|
APPEND_ENTITY_PROPERTY(PROP_Y_P_NEIGHBOR_ID, properties.getYPNeighborID());
|
|
APPEND_ENTITY_PROPERTY(PROP_Z_P_NEIGHBOR_ID, properties.getZPNeighborID());
|
|
}
|
|
|
|
if (properties.getType() == EntityTypes::Web) {
|
|
APPEND_ENTITY_PROPERTY(PROP_COLOR, properties.getColor());
|
|
APPEND_ENTITY_PROPERTY(PROP_ALPHA, properties.getAlpha());
|
|
_staticPulse.setProperties(properties);
|
|
_staticPulse.appendToEditPacket(packetData, requestedProperties, propertyFlags,
|
|
propertiesDidntFit, propertyCount, appendState);
|
|
APPEND_ENTITY_PROPERTY(PROP_BILLBOARD_MODE, (uint32_t)properties.getBillboardMode());
|
|
|
|
APPEND_ENTITY_PROPERTY(PROP_SOURCE_URL, properties.getSourceUrl());
|
|
APPEND_ENTITY_PROPERTY(PROP_DPI, properties.getDPI());
|
|
APPEND_ENTITY_PROPERTY(PROP_SCRIPT_URL, properties.getScriptURL());
|
|
APPEND_ENTITY_PROPERTY(PROP_MAX_FPS, properties.getMaxFPS());
|
|
APPEND_ENTITY_PROPERTY(PROP_INPUT_MODE, (uint32_t)properties.getInputMode());
|
|
APPEND_ENTITY_PROPERTY(PROP_SHOW_KEYBOARD_FOCUS_HIGHLIGHT, properties.getShowKeyboardFocusHighlight());
|
|
}
|
|
|
|
if (properties.getType() == EntityTypes::Line) {
|
|
APPEND_ENTITY_PROPERTY(PROP_COLOR, properties.getColor());
|
|
|
|
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, properties.getLinePoints());
|
|
}
|
|
|
|
if (properties.getType() == EntityTypes::PolyLine) {
|
|
APPEND_ENTITY_PROPERTY(PROP_COLOR, properties.getColor());
|
|
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, properties.getTextures());
|
|
|
|
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, properties.getLinePoints());
|
|
APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, properties.getStrokeWidths());
|
|
APPEND_ENTITY_PROPERTY(PROP_STROKE_NORMALS, properties.getPackedNormals());
|
|
APPEND_ENTITY_PROPERTY(PROP_STROKE_COLORS, properties.getPackedStrokeColors());
|
|
APPEND_ENTITY_PROPERTY(PROP_IS_UV_MODE_STRETCH, properties.getIsUVModeStretch());
|
|
APPEND_ENTITY_PROPERTY(PROP_LINE_GLOW, properties.getGlow());
|
|
APPEND_ENTITY_PROPERTY(PROP_LINE_FACE_CAMERA, properties.getFaceCamera());
|
|
}
|
|
|
|
// NOTE: Spheres and Boxes are just special cases of Shape, and they need to include their PROP_SHAPE
|
|
// when encoding/decoding edits because otherwise they can't polymorph to other shape types
|
|
if (properties.getType() == EntityTypes::Shape ||
|
|
properties.getType() == EntityTypes::Box ||
|
|
properties.getType() == EntityTypes::Sphere) {
|
|
APPEND_ENTITY_PROPERTY(PROP_COLOR, properties.getColor());
|
|
APPEND_ENTITY_PROPERTY(PROP_ALPHA, properties.getAlpha());
|
|
_staticPulse.setProperties(properties);
|
|
_staticPulse.appendToEditPacket(packetData, requestedProperties, propertyFlags,
|
|
propertiesDidntFit, propertyCount, appendState);
|
|
APPEND_ENTITY_PROPERTY(PROP_SHAPE, properties.getShape());
|
|
}
|
|
|
|
// Materials
|
|
if (properties.getType() == EntityTypes::Material) {
|
|
APPEND_ENTITY_PROPERTY(PROP_MATERIAL_URL, properties.getMaterialURL());
|
|
APPEND_ENTITY_PROPERTY(PROP_MATERIAL_MAPPING_MODE, (uint32_t)properties.getMaterialMappingMode());
|
|
APPEND_ENTITY_PROPERTY(PROP_MATERIAL_PRIORITY, properties.getPriority());
|
|
APPEND_ENTITY_PROPERTY(PROP_PARENT_MATERIAL_NAME, properties.getParentMaterialName());
|
|
APPEND_ENTITY_PROPERTY(PROP_MATERIAL_MAPPING_POS, properties.getMaterialMappingPos());
|
|
APPEND_ENTITY_PROPERTY(PROP_MATERIAL_MAPPING_SCALE, properties.getMaterialMappingScale());
|
|
APPEND_ENTITY_PROPERTY(PROP_MATERIAL_MAPPING_ROT, properties.getMaterialMappingRot());
|
|
APPEND_ENTITY_PROPERTY(PROP_MATERIAL_DATA, properties.getMaterialData());
|
|
APPEND_ENTITY_PROPERTY(PROP_MATERIAL_REPEAT, properties.getMaterialRepeat());
|
|
}
|
|
|
|
// Image
|
|
if (properties.getType() == EntityTypes::Image) {
|
|
APPEND_ENTITY_PROPERTY(PROP_COLOR, properties.getColor());
|
|
APPEND_ENTITY_PROPERTY(PROP_ALPHA, properties.getAlpha());
|
|
_staticPulse.setProperties(properties);
|
|
_staticPulse.appendToEditPacket(packetData, requestedProperties, propertyFlags,
|
|
propertiesDidntFit, propertyCount, appendState);
|
|
APPEND_ENTITY_PROPERTY(PROP_BILLBOARD_MODE, (uint32_t)properties.getBillboardMode());
|
|
|
|
APPEND_ENTITY_PROPERTY(PROP_IMAGE_URL, properties.getImageURL());
|
|
APPEND_ENTITY_PROPERTY(PROP_EMISSIVE, properties.getEmissive());
|
|
APPEND_ENTITY_PROPERTY(PROP_KEEP_ASPECT_RATIO, properties.getKeepAspectRatio());
|
|
APPEND_ENTITY_PROPERTY(PROP_SUB_IMAGE, properties.getSubImage());
|
|
}
|
|
|
|
// Grid
|
|
if (properties.getType() == EntityTypes::Grid) {
|
|
APPEND_ENTITY_PROPERTY(PROP_COLOR, properties.getColor());
|
|
APPEND_ENTITY_PROPERTY(PROP_ALPHA, properties.getAlpha());
|
|
_staticPulse.setProperties(properties);
|
|
_staticPulse.appendToEditPacket(packetData, requestedProperties, propertyFlags,
|
|
propertiesDidntFit, propertyCount, appendState);
|
|
|
|
APPEND_ENTITY_PROPERTY(PROP_GRID_FOLLOW_CAMERA, properties.getFollowCamera());
|
|
APPEND_ENTITY_PROPERTY(PROP_MAJOR_GRID_EVERY, properties.getMajorGridEvery());
|
|
APPEND_ENTITY_PROPERTY(PROP_MINOR_GRID_EVERY, properties.getMinorGridEvery());
|
|
}
|
|
|
|
if (properties.getType() == EntityTypes::Gizmo) {
|
|
APPEND_ENTITY_PROPERTY(PROP_GIZMO_TYPE, (uint32_t)properties.getGizmoType());
|
|
_staticRing.setProperties(properties);
|
|
_staticRing.appendToEditPacket(packetData, requestedProperties, propertyFlags,
|
|
propertiesDidntFit, propertyCount, appendState);
|
|
}
|
|
}
|
|
|
|
if (propertyCount > 0) {
|
|
int endOfEntityItemData = packetData->getUncompressedByteOffset();
|
|
|
|
encodedPropertyFlags = propertyFlags;
|
|
int newPropertyFlagsLength = encodedPropertyFlags.length();
|
|
packetData->updatePriorBytes(propertyFlagsOffset, (const unsigned char*)encodedPropertyFlags.constData(),
|
|
encodedPropertyFlags.length());
|
|
|
|
// if the size of the PropertyFlags shrunk, we need to shift everything down to front of packet.
|
|
if (newPropertyFlagsLength < oldPropertyFlagsLength) {
|
|
int oldSize = packetData->getUncompressedSize();
|
|
|
|
const unsigned char* modelItemData = packetData->getUncompressedData(propertyFlagsOffset + oldPropertyFlagsLength);
|
|
int modelItemDataLength = endOfEntityItemData - startOfEntityItemData;
|
|
int newEntityItemDataStart = propertyFlagsOffset + newPropertyFlagsLength;
|
|
packetData->updatePriorBytes(newEntityItemDataStart, modelItemData, modelItemDataLength);
|
|
|
|
int newSize = oldSize - (oldPropertyFlagsLength - newPropertyFlagsLength);
|
|
packetData->setUncompressedSize(newSize);
|
|
|
|
} else {
|
|
assert(newPropertyFlagsLength == oldPropertyFlagsLength); // should not have grown
|
|
}
|
|
|
|
packetData->endLevel(entityLevel);
|
|
} else {
|
|
packetData->discardLevel(entityLevel);
|
|
appendState = OctreeElement::NONE; // if we got here, then we didn't include the item
|
|
}
|
|
|
|
// If any part of the model items didn't fit, then the element is considered partial
|
|
if (appendState != OctreeElement::COMPLETED) {
|
|
didntFitProperties = propertiesDidntFit;
|
|
}
|
|
|
|
packetData->endSubTree();
|
|
|
|
const char* finalizedData = reinterpret_cast<const char*>(packetData->getFinalizedData());
|
|
int finalizedSize = packetData->getFinalizedSize();
|
|
|
|
if (finalizedSize <= buffer.size()) {
|
|
buffer.replace(0, finalizedSize, finalizedData, finalizedSize);
|
|
buffer.resize(finalizedSize);
|
|
} else {
|
|
qCDebug(entities) << "ERROR - encoded edit message doesn't fit in output buffer.";
|
|
appendState = OctreeElement::NONE; // if we got here, then we didn't include the item
|
|
// maybe we should assert!!!
|
|
}
|
|
} else {
|
|
packetData->discardSubTree();
|
|
}
|
|
|
|
return appendState;
|
|
}
|
|
|
|
QByteArray EntityItemProperties::getPackedNormals() const {
|
|
return packNormals(getNormals());
|
|
}
|
|
|
|
QByteArray EntityItemProperties::packNormals(const QVector<vec3>& normals) const {
|
|
int normalsSize = normals.size();
|
|
QByteArray packedNormals = QByteArray(normalsSize * 6 + 1, '0');
|
|
// add size of the array
|
|
packedNormals[0] = ((uint8_t)normalsSize);
|
|
|
|
int index = 1;
|
|
for (int i = 0; i < normalsSize; i++) {
|
|
int numBytes = packFloatVec3ToSignedTwoByteFixed((unsigned char*)packedNormals.data() + index, normals[i], 15);
|
|
index += numBytes;
|
|
}
|
|
return packedNormals;
|
|
}
|
|
|
|
QByteArray EntityItemProperties::getPackedStrokeColors() const {
|
|
return packStrokeColors(getStrokeColors());
|
|
}
|
|
QByteArray EntityItemProperties::packStrokeColors(const QVector<vec3>& strokeColors) const {
|
|
int strokeColorsSize = strokeColors.size();
|
|
QByteArray packedStrokeColors = QByteArray(strokeColorsSize * 3 + 1, '0');
|
|
|
|
// add size of the array
|
|
packedStrokeColors[0] = ((uint8_t)strokeColorsSize);
|
|
|
|
|
|
for (int i = 0; i < strokeColorsSize; i++) {
|
|
// add the color to the QByteArray
|
|
packedStrokeColors[i * 3 + 1] = strokeColors[i].x * 255;
|
|
packedStrokeColors[i * 3 + 2] = strokeColors[i].y * 255;
|
|
packedStrokeColors[i * 3 + 3] = strokeColors[i].z * 255;
|
|
}
|
|
return packedStrokeColors;
|
|
}
|
|
|
|
// TODO:
|
|
// how to handle lastEdited?
|
|
// how to handle lastUpdated?
|
|
// consider handling case where no properties are included... we should just ignore this packet...
|
|
//
|
|
// TODO: Right now, all possible properties for all subclasses are handled here. Ideally we'd prefer
|
|
// to handle this in a more generic way. Allowing subclasses of EntityItem to register their properties
|
|
//
|
|
// TODO: There's a lot of repeated patterns in the code below to handle each property. It would be nice if the property
|
|
// registration mechanism allowed us to collapse these repeated sections of code into a single implementation that
|
|
// utilized the registration table to shorten up and simplify this code.
|
|
//
|
|
// TODO: Implement support for paged properties, spanning MTU, and custom properties
|
|
//
|
|
// TODO: Implement support for script and visible properties.
|
|
//
|
|
bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int bytesToRead, int& processedBytes,
|
|
EntityItemID& entityID, EntityItemProperties& properties) {
|
|
bool valid = false;
|
|
|
|
const unsigned char* dataAt = data;
|
|
processedBytes = 0;
|
|
|
|
// the first part of the data is an octcode, this is a required element of the edit packet format, but we don't
|
|
// actually use it, we do need to skip it and read to the actual data we care about.
|
|
int octets = numberOfThreeBitSectionsInCode(data);
|
|
int bytesToReadOfOctcode = (int)bytesRequiredForCodeLength(octets);
|
|
|
|
// we don't actually do anything with this octcode...
|
|
dataAt += bytesToReadOfOctcode;
|
|
processedBytes += bytesToReadOfOctcode;
|
|
|
|
// Edit packets have a last edited time stamp immediately following the octcode.
|
|
// NOTE: the edit times have been set by the editor to match out clock, so we don't need to adjust
|
|
// these times for clock skew at this point.
|
|
quint64 lastEdited;
|
|
memcpy(&lastEdited, dataAt, sizeof(lastEdited));
|
|
dataAt += sizeof(lastEdited);
|
|
processedBytes += sizeof(lastEdited);
|
|
properties.setLastEdited(lastEdited);
|
|
|
|
// encoded id
|
|
QUuid editID = QUuid::fromRfc4122(QByteArray::fromRawData(reinterpret_cast<const char*>(dataAt), NUM_BYTES_RFC4122_UUID));
|
|
dataAt += NUM_BYTES_RFC4122_UUID;
|
|
processedBytes += NUM_BYTES_RFC4122_UUID;
|
|
|
|
entityID = editID;
|
|
valid = true;
|
|
|
|
// Entity Type...
|
|
QByteArray encodedType((const char*)dataAt, (bytesToRead - processedBytes));
|
|
ByteCountCoded<quint32> typeCoder = encodedType;
|
|
quint32 entityTypeCode = typeCoder;
|
|
properties.setType((EntityTypes::EntityType)entityTypeCode);
|
|
encodedType = typeCoder; // determine true bytesToRead
|
|
dataAt += encodedType.size();
|
|
processedBytes += encodedType.size();
|
|
|
|
// Update Delta - when was this item updated relative to last edit... this really should be 0
|
|
// TODO: Should we get rid of this in this in edit packets, since this has to always be 0?
|
|
// TODO: do properties need to handle lastupdated???
|
|
|
|
// last updated is stored as ByteCountCoded delta from lastEdited
|
|
QByteArray encodedUpdateDelta((const char*)dataAt, (bytesToRead - processedBytes));
|
|
ByteCountCoded<quint64> updateDeltaCoder = encodedUpdateDelta;
|
|
encodedUpdateDelta = updateDeltaCoder; // determine true bytesToRead
|
|
dataAt += encodedUpdateDelta.size();
|
|
processedBytes += encodedUpdateDelta.size();
|
|
|
|
// TODO: Do we need this lastUpdated?? We don't seem to use it.
|
|
//quint64 updateDelta = updateDeltaCoder;
|
|
//quint64 lastUpdated = lastEdited + updateDelta; // don't adjust for clock skew since we already did that for lastEdited
|
|
|
|
// Property Flags...
|
|
QByteArray encodedPropertyFlags((const char*)dataAt, (bytesToRead - processedBytes));
|
|
EntityPropertyFlags propertyFlags = encodedPropertyFlags;
|
|
dataAt += propertyFlags.getEncodedLength();
|
|
processedBytes += propertyFlags.getEncodedLength();
|
|
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SIMULATION_OWNER, QByteArray, setSimulationOwner);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARENT_ID, QUuid, setParentID);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARENT_JOINT_INDEX, quint16, setParentJointIndex);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VISIBLE, bool, setVisible);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NAME, QString, setName);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LOCKED, bool, setLocked);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_USER_DATA, QString, setUserData);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PRIVATE_USER_DATA, QString, setPrivateUserData);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_HREF, QString, setHref);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_DESCRIPTION, QString, setDescription);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_POSITION, vec3, setPosition);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_DIMENSIONS, vec3, setDimensions);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ROTATION, quat, setRotation);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_REGISTRATION_POINT, vec3, setRegistrationPoint);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CREATED, quint64, setCreated);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LAST_EDITED_BY, QUuid, setLastEditedBy);
|
|
// READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ENTITY_HOST_TYPE, entity::HostType, setEntityHostType); // not sent over the wire
|
|
// READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_OWNING_AVATAR_ID, QUuid, setOwningAvatarID); // not sent over the wire
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_QUERY_AA_CUBE, AACube, setQueryAACube);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CAN_CAST_SHADOW, bool, setCanCastShadow);
|
|
// READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VISIBLE_IN_SECONDARY_CAMERA, bool, setIsVisibleInSecondaryCamera); // not sent over the wire
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RENDER_LAYER, RenderLayer, setRenderLayer);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PRIMITIVE_MODE, PrimitiveMode, setPrimitiveMode);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_IGNORE_PICK_INTERSECTION, bool, setIgnorePickIntersection);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RENDER_WITH_ZONES, QVector<QUuid>, setRenderWithZones);
|
|
properties.getGrab().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
|
|
|
// Physics
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_DENSITY, float, setDensity);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VELOCITY, vec3, setVelocity);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANGULAR_VELOCITY, vec3, setAngularVelocity);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_GRAVITY, vec3, setGravity);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ACCELERATION, vec3, setAcceleration);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_DAMPING, float, setDamping);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANGULAR_DAMPING, float, setAngularDamping);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RESTITUTION, float, setRestitution);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_FRICTION, float, setFriction);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LIFETIME, float, setLifetime);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLLISIONLESS, bool, setCollisionless);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLLISION_MASK, uint16_t, setCollisionMask);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_DYNAMIC, bool, setDynamic);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLLISION_SOUND_URL, QString, setCollisionSoundURL);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ACTION_DATA, QByteArray, setActionData);
|
|
|
|
// Cloning
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CLONEABLE, bool, setCloneable);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CLONE_LIFETIME, float, setCloneLifetime);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CLONE_LIMIT, float, setCloneLimit);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CLONE_DYNAMIC, bool, setCloneDynamic);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CLONE_AVATAR_ENTITY, bool, setCloneAvatarEntity);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CLONE_ORIGIN_ID, QUuid, setCloneOriginID);
|
|
|
|
// Scripts
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SCRIPT, QString, setScript);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SCRIPT_TIMESTAMP, quint64, setScriptTimestamp);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SERVER_SCRIPTS, QString, setServerScripts);
|
|
|
|
// Certifiable Properties
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ITEM_NAME, QString, setItemName);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ITEM_DESCRIPTION, QString, setItemDescription);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ITEM_CATEGORIES, QString, setItemCategories);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ITEM_ARTIST, QString, setItemArtist);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ITEM_LICENSE, QString, setItemLicense);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LIMITED_RUN, quint32, setLimitedRun);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MARKETPLACE_ID, QString, setMarketplaceID);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EDITION_NUMBER, quint32, setEditionNumber);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ENTITY_INSTANCE_NUMBER, quint32, setEntityInstanceNumber);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CERTIFICATE_ID, QString, setCertificateID);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CERTIFICATE_TYPE, QString, setCertificateType);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STATIC_CERTIFICATE_VERSION, quint32, setStaticCertificateVersion);
|
|
|
|
if (properties.getType() == EntityTypes::ParticleEffect) {
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SHAPE_TYPE, ShapeType, setShapeType);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR, u8vec3Color, setColor);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA, float, setAlpha);
|
|
properties.getPulse().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures);
|
|
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MAX_PARTICLES, quint32, setMaxParticles);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LIFESPAN, float, setLifespan);
|
|
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMITTING_PARTICLES, bool, setIsEmitting);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_RATE, float, setEmitRate);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_SPEED, float, setEmitSpeed);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SPEED_SPREAD, float, setSpeedSpread);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_ORIENTATION, quat, setEmitOrientation);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_DIMENSIONS, vec3, setEmitDimensions);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_RADIUS_START, float, setEmitRadiusStart);
|
|
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_POLAR_START, float, setPolarStart);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_POLAR_FINISH, float, setPolarFinish);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_AZIMUTH_START, float, setAzimuthStart);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_AZIMUTH_FINISH, float, setAzimuthFinish);
|
|
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_ACCELERATION, vec3, setEmitAcceleration);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ACCELERATION_SPREAD, vec3, setAccelerationSpread);
|
|
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARTICLE_RADIUS, float, setParticleRadius);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RADIUS_SPREAD, float, setRadiusSpread);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RADIUS_START, float, setRadiusStart);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RADIUS_FINISH, float, setRadiusFinish);
|
|
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR_SPREAD, u8vec3Color, setColorSpread);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR_START, vec3Color, setColorStart);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR_FINISH, vec3Color, setColorFinish);
|
|
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_SPREAD, float, setAlphaSpread);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_START, float, setAlphaStart);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_FINISH, float, setAlphaFinish);
|
|
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMITTER_SHOULD_TRAIL, bool, setEmitterShouldTrail);
|
|
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARTICLE_SPIN, float, setParticleSpin);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SPIN_SPREAD, float, setSpinSpread);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SPIN_START, float, setSpinStart);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SPIN_FINISH, float, setSpinFinish);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARTICLE_ROTATE_WITH_ENTITY, bool, setRotateWithEntity);
|
|
}
|
|
|
|
if (properties.getType() == EntityTypes::Model) {
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SHAPE_TYPE, ShapeType, setShapeType);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR, u8vec3Color, setColor);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures);
|
|
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MODEL_URL, QString, setModelURL);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MODEL_SCALE, vec3, setModelScale);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_ROTATIONS_SET, QVector<bool>, setJointRotationsSet);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_ROTATIONS, QVector<quat>, setJointRotations);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_TRANSLATIONS_SET, QVector<bool>, setJointTranslationsSet);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_TRANSLATIONS, QVector<vec3>, setJointTranslations);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RELAY_PARENT_JOINTS, bool, setRelayParentJoints);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_GROUP_CULLED, bool, setGroupCulled);
|
|
|
|
properties.getAnimation().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
|
}
|
|
|
|
if (properties.getType() == EntityTypes::Light) {
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR, u8vec3Color, setColor);
|
|
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_IS_SPOTLIGHT, bool, setIsSpotlight);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_INTENSITY, float, setIntensity);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EXPONENT, float, setExponent);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CUTOFF, float, setCutoff);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_FALLOFF_RADIUS, float, setFalloffRadius);
|
|
}
|
|
|
|
if (properties.getType() == EntityTypes::Text) {
|
|
properties.getPulse().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_BILLBOARD_MODE, BillboardMode, setBillboardMode);
|
|
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXT, QString, setText);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_HEIGHT, float, setLineHeight);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXT_COLOR, u8vec3Color, setTextColor);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXT_ALPHA, float, setTextAlpha);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_BACKGROUND_COLOR, u8vec3Color, setBackgroundColor);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_BACKGROUND_ALPHA, float, setBackgroundAlpha);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LEFT_MARGIN, float, setLeftMargin);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RIGHT_MARGIN, float, setRightMargin);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TOP_MARGIN, float, setTopMargin);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_BOTTOM_MARGIN, float, setBottomMargin);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_UNLIT, bool, setUnlit);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_FONT, QString, setFont);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXT_EFFECT, TextEffect, setTextEffect);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXT_EFFECT_COLOR, u8vec3Color, setTextEffectColor);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXT_EFFECT_THICKNESS, float, setTextEffectThickness);
|
|
}
|
|
|
|
if (properties.getType() == EntityTypes::Zone) {
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SHAPE_TYPE, ShapeType, setShapeType);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL);
|
|
|
|
properties.getKeyLight().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
|
properties.getAmbientLight().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
|
properties.getSkybox().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
|
properties.getHaze().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
|
properties.getBloom().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
|
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_FLYING_ALLOWED, bool, setFlyingAllowed);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_GHOSTING_ALLOWED, bool, setGhostingAllowed);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_FILTER_URL, QString, setFilterURL);
|
|
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_KEY_LIGHT_MODE, uint32_t, setKeyLightMode);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_AMBIENT_LIGHT_MODE, uint32_t, setAmbientLightMode);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SKYBOX_MODE, uint32_t, setSkyboxMode);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_HAZE_MODE, uint32_t, setHazeMode);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_BLOOM_MODE, uint32_t, setBloomMode);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_AVATAR_PRIORITY, uint32_t, setAvatarPriority);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SCREENSHARE, uint32_t, setScreenshare);
|
|
}
|
|
|
|
if (properties.getType() == EntityTypes::PolyVox) {
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VOXEL_VOLUME_SIZE, vec3, setVoxelVolumeSize);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VOXEL_DATA, QByteArray, setVoxelData);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VOXEL_SURFACE_STYLE, uint16_t, setVoxelSurfaceStyle);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_X_TEXTURE_URL, QString, setXTextureURL);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_Y_TEXTURE_URL, QString, setYTextureURL);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_Z_TEXTURE_URL, QString, setZTextureURL);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_X_N_NEIGHBOR_ID, EntityItemID, setXNNeighborID);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_Y_N_NEIGHBOR_ID, EntityItemID, setYNNeighborID);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_Z_N_NEIGHBOR_ID, EntityItemID, setZNNeighborID);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_X_P_NEIGHBOR_ID, EntityItemID, setXPNeighborID);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_Y_P_NEIGHBOR_ID, EntityItemID, setYPNeighborID);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_Z_P_NEIGHBOR_ID, EntityItemID, setZPNeighborID);
|
|
}
|
|
|
|
if (properties.getType() == EntityTypes::Web) {
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR, u8vec3Color, setColor);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA, float, setAlpha);
|
|
properties.getPulse().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_BILLBOARD_MODE, BillboardMode, setBillboardMode);
|
|
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SOURCE_URL, QString, setSourceUrl);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_DPI, uint16_t, setDPI);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SCRIPT_URL, QString, setScriptURL);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MAX_FPS, uint8_t, setMaxFPS);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_INPUT_MODE, WebInputMode, setInputMode);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SHOW_KEYBOARD_FOCUS_HIGHLIGHT, bool, setShowKeyboardFocusHighlight);
|
|
}
|
|
|
|
if (properties.getType() == EntityTypes::Line) {
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR, u8vec3Color, setColor);
|
|
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_POINTS, QVector<vec3>, setLinePoints);
|
|
}
|
|
|
|
if (properties.getType() == EntityTypes::PolyLine) {
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR, u8vec3Color, setColor);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures);
|
|
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_POINTS, QVector<vec3>, setLinePoints);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STROKE_WIDTHS, QVector<float>, setStrokeWidths);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STROKE_NORMALS, QByteArray, setPackedNormals);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STROKE_COLORS, QByteArray, setPackedStrokeColors);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_IS_UV_MODE_STRETCH, bool, setIsUVModeStretch);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_GLOW, bool, setGlow);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_FACE_CAMERA, bool, setFaceCamera);
|
|
}
|
|
|
|
// NOTE: Spheres and Boxes are just special cases of Shape, and they need to include their PROP_SHAPE
|
|
// when encoding/decoding edits because otherwise they can't polymorph to other shape types
|
|
if (properties.getType() == EntityTypes::Shape ||
|
|
properties.getType() == EntityTypes::Box ||
|
|
properties.getType() == EntityTypes::Sphere) {
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR, u8vec3Color, setColor);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA, float, setAlpha);
|
|
properties.getPulse().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
|
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SHAPE, QString, setShape);
|
|
}
|
|
|
|
// Materials
|
|
if (properties.getType() == EntityTypes::Material) {
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_URL, QString, setMaterialURL);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_MAPPING_MODE, MaterialMappingMode, setMaterialMappingMode);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_PRIORITY, quint16, setPriority);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARENT_MATERIAL_NAME, QString, setParentMaterialName);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_MAPPING_POS, vec2, setMaterialMappingPos);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_MAPPING_SCALE, vec2, setMaterialMappingScale);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_MAPPING_ROT, float, setMaterialMappingRot);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_DATA, QString, setMaterialData);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_REPEAT, bool, setMaterialRepeat);
|
|
}
|
|
|
|
// Image
|
|
if (properties.getType() == EntityTypes::Image) {
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR, u8vec3Color, setColor);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA, float, setAlpha);
|
|
properties.getPulse().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_BILLBOARD_MODE, BillboardMode, setBillboardMode);
|
|
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_IMAGE_URL, QString, setImageURL);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMISSIVE, bool, setEmissive);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_KEEP_ASPECT_RATIO, bool, setKeepAspectRatio);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SUB_IMAGE, QRect, setSubImage);
|
|
}
|
|
|
|
// Grid
|
|
if (properties.getType() == EntityTypes::Grid) {
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR, u8vec3Color, setColor);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA, float, setAlpha);
|
|
properties.getPulse().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
|
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_GRID_FOLLOW_CAMERA, bool, setFollowCamera);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MAJOR_GRID_EVERY, uint32_t, setMajorGridEvery);
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MINOR_GRID_EVERY, float, setMinorGridEvery);
|
|
}
|
|
|
|
if (properties.getType() == EntityTypes::Gizmo) {
|
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_GIZMO_TYPE, GizmoType, setGizmoType);
|
|
properties.getRing().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
|
}
|
|
|
|
return valid;
|
|
}
|
|
|
|
void EntityItemProperties::setPackedNormals(const QByteArray& value) {
|
|
setNormals(unpackNormals(value));
|
|
}
|
|
|
|
QVector<vec3> EntityItemProperties::unpackNormals(const QByteArray& normals) {
|
|
// the size of the vector is packed first
|
|
QVector<vec3> unpackedNormals = QVector<vec3>((int)normals[0]);
|
|
|
|
if ((int)normals[0] == normals.size() / 6) {
|
|
int j = 0;
|
|
for (int i = 1; i < normals.size();) {
|
|
vec3 aux = vec3();
|
|
i += unpackFloatVec3FromSignedTwoByteFixed((unsigned char*)normals.data() + i, aux, 15);
|
|
unpackedNormals[j] = aux;
|
|
j++;
|
|
}
|
|
} else {
|
|
qCDebug(entities) << "WARNING - Expected received size for normals does not match. Expected: " << (int)normals[0]
|
|
<< " Received: " << (normals.size() / 6);
|
|
}
|
|
return unpackedNormals;
|
|
}
|
|
|
|
void EntityItemProperties::setPackedStrokeColors(const QByteArray& value) {
|
|
setStrokeColors(unpackStrokeColors(value));
|
|
}
|
|
|
|
QVector<vec3> EntityItemProperties::unpackStrokeColors(const QByteArray& strokeColors) {
|
|
// the size of the vector is packed first
|
|
QVector<vec3> unpackedStrokeColors = QVector<vec3>((int)strokeColors[0]);
|
|
|
|
if ((int)strokeColors[0] == strokeColors.size() / 3) {
|
|
int j = 0;
|
|
for (int i = 1; i < strokeColors.size();) {
|
|
|
|
float r = (uint8_t)strokeColors[i++] / 255.0f;
|
|
float g = (uint8_t)strokeColors[i++] / 255.0f;
|
|
float b = (uint8_t)strokeColors[i++] / 255.0f;
|
|
unpackedStrokeColors[j++] = vec3(r, g, b);
|
|
}
|
|
} else {
|
|
qCDebug(entities) << "WARNING - Expected received size for stroke colors does not match. Expected: "
|
|
<< (int)strokeColors[0] << " Received: " << (strokeColors.size() / 3);
|
|
}
|
|
|
|
return unpackedStrokeColors;
|
|
}
|
|
|
|
// NOTE: This version will only encode the portion of the edit message immediately following the
|
|
// header it does not include the send times and sequence number because that is handled by the
|
|
// edit packet sender...
|
|
bool EntityItemProperties::encodeEraseEntityMessage(const EntityItemID& entityItemID, QByteArray& buffer) {
|
|
|
|
char* copyAt = buffer.data();
|
|
uint16_t numberOfIds = 1; // only one entity ID in this message
|
|
|
|
int outputLength = 0;
|
|
|
|
if (buffer.size() < (int)(sizeof(numberOfIds) + NUM_BYTES_RFC4122_UUID)) {
|
|
qCDebug(entities) << "ERROR - encodeEraseEntityMessage() called with buffer that is too small!";
|
|
return false;
|
|
}
|
|
|
|
memcpy(copyAt, &numberOfIds, sizeof(numberOfIds));
|
|
copyAt += sizeof(numberOfIds);
|
|
outputLength = sizeof(numberOfIds);
|
|
|
|
memcpy(copyAt, entityItemID.toRfc4122().constData(), NUM_BYTES_RFC4122_UUID);
|
|
outputLength += NUM_BYTES_RFC4122_UUID;
|
|
|
|
buffer.resize(outputLength);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool EntityItemProperties::encodeCloneEntityMessage(const EntityItemID& entityIDToClone, const EntityItemID& newEntityID, QByteArray& buffer) {
|
|
char* copyAt = buffer.data();
|
|
int outputLength = 0;
|
|
|
|
if (buffer.size() < (int)(NUM_BYTES_RFC4122_UUID * 2)) {
|
|
qCDebug(entities) << "ERROR - encodeCloneEntityMessage() called with buffer that is too small!";
|
|
return false;
|
|
}
|
|
|
|
memcpy(copyAt, entityIDToClone.toRfc4122().constData(), NUM_BYTES_RFC4122_UUID);
|
|
copyAt += NUM_BYTES_RFC4122_UUID;
|
|
outputLength += NUM_BYTES_RFC4122_UUID;
|
|
|
|
memcpy(copyAt, newEntityID.toRfc4122().constData(), NUM_BYTES_RFC4122_UUID);
|
|
outputLength += NUM_BYTES_RFC4122_UUID;
|
|
|
|
buffer.resize(outputLength);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool EntityItemProperties::decodeCloneEntityMessage(const QByteArray& buffer, int& processedBytes, EntityItemID& entityIDToClone, EntityItemID& newEntityID) {
|
|
const unsigned char* packetData = (const unsigned char*)buffer.constData();
|
|
const unsigned char* dataAt = packetData;
|
|
size_t packetLength = buffer.size();
|
|
processedBytes = 0;
|
|
|
|
if (NUM_BYTES_RFC4122_UUID * 2 > packetLength) {
|
|
qCDebug(entities) << "EntityItemProperties::decodeCloneEntityMessage().... bailing because not enough bytes in buffer";
|
|
return false; // bail to prevent buffer overflow
|
|
}
|
|
|
|
QByteArray encodedID = buffer.mid((int)processedBytes, NUM_BYTES_RFC4122_UUID);
|
|
entityIDToClone = QUuid::fromRfc4122(encodedID);
|
|
dataAt += encodedID.size();
|
|
processedBytes += encodedID.size();
|
|
|
|
encodedID = buffer.mid((int)processedBytes, NUM_BYTES_RFC4122_UUID);
|
|
newEntityID = QUuid::fromRfc4122(encodedID);
|
|
dataAt += encodedID.size();
|
|
processedBytes += encodedID.size();
|
|
|
|
return true;
|
|
}
|
|
|
|
void EntityItemProperties::markAllChanged() {
|
|
// Core
|
|
_simulationOwnerChanged = true;
|
|
_parentIDChanged = true;
|
|
_parentJointIndexChanged = true;
|
|
_visibleChanged = true;
|
|
_nameChanged = true;
|
|
_lockedChanged = true;
|
|
_userDataChanged = true;
|
|
_privateUserDataChanged = true;
|
|
_hrefChanged = true;
|
|
_descriptionChanged = true;
|
|
_positionChanged = true;
|
|
_dimensionsChanged = true;
|
|
_rotationChanged = true;
|
|
_registrationPointChanged = true;
|
|
_createdChanged = true;
|
|
_lastEditedByChanged = true;
|
|
_entityHostTypeChanged = true;
|
|
_owningAvatarIDChanged = true;
|
|
_queryAACubeChanged = true;
|
|
_canCastShadowChanged = true;
|
|
_isVisibleInSecondaryCameraChanged = true;
|
|
_renderLayerChanged = true;
|
|
_primitiveModeChanged = true;
|
|
_ignorePickIntersectionChanged = true;
|
|
_renderWithZonesChanged = true;
|
|
_grab.markAllChanged();
|
|
|
|
// Physics
|
|
_densityChanged = true;
|
|
_velocityChanged = true;
|
|
_angularVelocityChanged = true;
|
|
_gravityChanged = true;
|
|
_accelerationChanged = true;
|
|
_dampingChanged = true;
|
|
_angularDampingChanged = true;
|
|
_restitutionChanged = true;
|
|
_frictionChanged = true;
|
|
_lifetimeChanged = true;
|
|
_collisionlessChanged = true;
|
|
_collisionMaskChanged = true;
|
|
_dynamicChanged = true;
|
|
_collisionSoundURLChanged = true;
|
|
_actionDataChanged = true;
|
|
|
|
// Cloning
|
|
_cloneableChanged = true;
|
|
_cloneLifetimeChanged = true;
|
|
_cloneLimitChanged = true;
|
|
_cloneDynamicChanged = true;
|
|
_cloneAvatarEntityChanged = true;
|
|
_cloneOriginIDChanged = true;
|
|
|
|
// Scripts
|
|
_scriptChanged = true;
|
|
_scriptTimestampChanged = true;
|
|
_serverScriptsChanged = true;
|
|
|
|
// Certifiable Properties
|
|
_itemNameChanged = true;
|
|
_itemDescriptionChanged = true;
|
|
_itemCategoriesChanged = true;
|
|
_itemArtistChanged = true;
|
|
_itemLicenseChanged = true;
|
|
_limitedRunChanged = true;
|
|
_marketplaceIDChanged = true;
|
|
_editionNumberChanged = true;
|
|
_entityInstanceNumberChanged = true;
|
|
_certificateIDChanged = true;
|
|
_certificateTypeChanged = true;
|
|
_staticCertificateVersionChanged = true;
|
|
|
|
// Common
|
|
_shapeTypeChanged = true;
|
|
_compoundShapeURLChanged = true;
|
|
_colorChanged = true;
|
|
_alphaChanged = true;
|
|
_pulse.markAllChanged();
|
|
_texturesChanged = true;
|
|
_billboardModeChanged = true;
|
|
|
|
// Particles
|
|
_maxParticlesChanged = true;
|
|
_lifespanChanged = true;
|
|
_isEmittingChanged = true;
|
|
_emitRateChanged = true;
|
|
_emitSpeedChanged = true;
|
|
_speedSpreadChanged = true;
|
|
_emitOrientationChanged = true;
|
|
_emitDimensionsChanged = true;
|
|
_emitRadiusStartChanged = true;
|
|
_polarStartChanged = true;
|
|
_polarFinishChanged = true;
|
|
_azimuthStartChanged = true;
|
|
_azimuthFinishChanged = true;
|
|
_emitAccelerationChanged = true;
|
|
_accelerationSpreadChanged = true;
|
|
_particleRadiusChanged = true;
|
|
_radiusSpreadChanged = true;
|
|
_radiusStartChanged = true;
|
|
_radiusFinishChanged = true;
|
|
_colorSpreadChanged = true;
|
|
_colorStartChanged = true;
|
|
_colorFinishChanged = true;
|
|
_alphaSpreadChanged = true;
|
|
_alphaStartChanged = true;
|
|
_alphaFinishChanged = true;
|
|
_emitterShouldTrailChanged = true;
|
|
_particleSpinChanged = true;
|
|
_spinStartChanged = true;
|
|
_spinFinishChanged = true;
|
|
_spinSpreadChanged = true;
|
|
_rotateWithEntityChanged = true;
|
|
|
|
// Model
|
|
_modelURLChanged = true;
|
|
_modelScaleChanged = true;
|
|
_jointRotationsSetChanged = true;
|
|
_jointRotationsChanged = true;
|
|
_jointTranslationsSetChanged = true;
|
|
_jointTranslationsChanged = true;
|
|
_relayParentJointsChanged = true;
|
|
_groupCulledChanged = true;
|
|
_animation.markAllChanged();
|
|
|
|
// Light
|
|
_isSpotlightChanged = true;
|
|
_intensityChanged = true;
|
|
_exponentChanged = true;
|
|
_cutoffChanged = true;
|
|
_falloffRadiusChanged = true;
|
|
|
|
// Text
|
|
_textChanged = true;
|
|
_lineHeightChanged = true;
|
|
_textColorChanged = true;
|
|
_textAlphaChanged = true;
|
|
_backgroundColorChanged = true;
|
|
_backgroundAlphaChanged = true;
|
|
_leftMarginChanged = true;
|
|
_rightMarginChanged = true;
|
|
_topMarginChanged = true;
|
|
_bottomMarginChanged = true;
|
|
_unlitChanged = true;
|
|
_fontChanged = true;
|
|
_textEffectChanged = true;
|
|
_textEffectColorChanged = true;
|
|
_textEffectThicknessChanged = true;
|
|
|
|
// Zone
|
|
_keyLight.markAllChanged();
|
|
_ambientLight.markAllChanged();
|
|
_skybox.markAllChanged();
|
|
_haze.markAllChanged();
|
|
_bloom.markAllChanged();
|
|
_flyingAllowedChanged = true;
|
|
_ghostingAllowedChanged = true;
|
|
_filterURLChanged = true;
|
|
_keyLightModeChanged = true;
|
|
_ambientLightModeChanged = true;
|
|
_skyboxModeChanged = true;
|
|
_hazeModeChanged = true;
|
|
_bloomModeChanged = true;
|
|
_avatarPriorityChanged = true;
|
|
_screenshareChanged = true;
|
|
|
|
// Polyvox
|
|
_voxelVolumeSizeChanged = true;
|
|
_voxelDataChanged = true;
|
|
_voxelSurfaceStyleChanged = true;
|
|
_xTextureURLChanged = true;
|
|
_yTextureURLChanged = true;
|
|
_zTextureURLChanged = true;
|
|
_xNNeighborIDChanged = true;
|
|
_yNNeighborIDChanged = true;
|
|
_zNNeighborIDChanged = true;
|
|
_xPNeighborIDChanged = true;
|
|
_yPNeighborIDChanged = true;
|
|
_zPNeighborIDChanged = true;
|
|
|
|
// Web
|
|
_sourceUrlChanged = true;
|
|
_dpiChanged = true;
|
|
_scriptURLChanged = true;
|
|
_maxFPSChanged = true;
|
|
_inputModeChanged = true;
|
|
_showKeyboardFocusHighlightChanged = true;
|
|
|
|
// Polyline
|
|
_linePointsChanged = true;
|
|
_strokeWidthsChanged = true;
|
|
_normalsChanged = true;
|
|
_strokeColorsChanged = true;
|
|
_isUVModeStretchChanged = true;
|
|
_glowChanged = true;
|
|
_faceCameraChanged = true;
|
|
|
|
// Shape
|
|
_shapeChanged = true;
|
|
|
|
// Material
|
|
_materialURLChanged = true;
|
|
_materialMappingModeChanged = true;
|
|
_priorityChanged = true;
|
|
_parentMaterialNameChanged = true;
|
|
_materialMappingPosChanged = true;
|
|
_materialMappingScaleChanged = true;
|
|
_materialMappingRotChanged = true;
|
|
_materialDataChanged = true;
|
|
_materialRepeatChanged = true;
|
|
|
|
// Image
|
|
_imageURLChanged = true;
|
|
_emissiveChanged = true;
|
|
_keepAspectRatioChanged = true;
|
|
_subImageChanged = true;
|
|
|
|
// Grid
|
|
_followCameraChanged = true;
|
|
_majorGridEveryChanged = true;
|
|
_minorGridEveryChanged = true;
|
|
|
|
// Gizmo
|
|
_gizmoTypeChanged = true;
|
|
_ring.markAllChanged();
|
|
}
|
|
|
|
// The minimum bounding box for the entity.
|
|
AABox EntityItemProperties::getAABox() const {
|
|
|
|
// _position represents the position of the registration point.
|
|
vec3 registrationRemainder = vec3(1.0f) - _registrationPoint;
|
|
|
|
vec3 unrotatedMinRelativeToEntity = -(_dimensions * _registrationPoint);
|
|
vec3 unrotatedMaxRelativeToEntity = _dimensions * registrationRemainder;
|
|
Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity };
|
|
Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(_rotation);
|
|
|
|
// shift the extents to be relative to the position/registration point
|
|
rotatedExtentsRelativeToRegistrationPoint.shiftBy(_position);
|
|
|
|
return AABox(rotatedExtentsRelativeToRegistrationPoint);
|
|
}
|
|
|
|
bool EntityItemProperties::hasTransformOrVelocityChanges() const {
|
|
return _positionChanged || _localPositionChanged
|
|
|| _rotationChanged || _localRotationChanged
|
|
|| _velocityChanged || _localVelocityChanged
|
|
|| _angularVelocityChanged || _localAngularVelocityChanged
|
|
|| _accelerationChanged;
|
|
}
|
|
|
|
void EntityItemProperties::clearTransformOrVelocityChanges() {
|
|
_positionChanged = false;
|
|
_localPositionChanged = false;
|
|
_rotationChanged = false;
|
|
_localRotationChanged = false;
|
|
_velocityChanged = false;
|
|
_localVelocityChanged = false;
|
|
_angularVelocityChanged = false;
|
|
_localAngularVelocityChanged = false;
|
|
_accelerationChanged = false;
|
|
}
|
|
|
|
bool EntityItemProperties::hasMiscPhysicsChanges() const {
|
|
return _gravityChanged || _dimensionsChanged || _densityChanged || _frictionChanged
|
|
|| _restitutionChanged || _dampingChanged || _angularDampingChanged || _registrationPointChanged ||
|
|
_compoundShapeURLChanged || _dynamicChanged || _collisionlessChanged || _collisionMaskChanged;
|
|
}
|
|
|
|
bool EntityItemProperties::hasSimulationRestrictedChanges() const {
|
|
return _positionChanged || _localPositionChanged
|
|
|| _rotationChanged || _localRotationChanged
|
|
|| _velocityChanged || _localVelocityChanged
|
|
|| _localDimensionsChanged || _dimensionsChanged
|
|
|| _angularVelocityChanged || _localAngularVelocityChanged
|
|
|| _accelerationChanged
|
|
|| _parentIDChanged || _parentJointIndexChanged;
|
|
}
|
|
|
|
void EntityItemProperties::copySimulationRestrictedProperties(const EntityItemPointer& entity) {
|
|
if (!_parentIDChanged) {
|
|
setParentID(entity->getParentID());
|
|
}
|
|
if (!_parentJointIndexChanged) {
|
|
setParentJointIndex(entity->getParentJointIndex());
|
|
}
|
|
if (!_localPositionChanged && !_positionChanged) {
|
|
setPosition(entity->getWorldPosition());
|
|
}
|
|
if (!_localRotationChanged && !_rotationChanged) {
|
|
setRotation(entity->getWorldOrientation());
|
|
}
|
|
if (!_localVelocityChanged && !_velocityChanged) {
|
|
setVelocity(entity->getWorldVelocity());
|
|
}
|
|
if (!_localAngularVelocityChanged && !_angularVelocityChanged) {
|
|
setAngularVelocity(entity->getWorldAngularVelocity());
|
|
}
|
|
if (!_accelerationChanged) {
|
|
setAcceleration(entity->getAcceleration());
|
|
}
|
|
if (!_localDimensionsChanged && !_dimensionsChanged) {
|
|
setLocalDimensions(entity->getScaledDimensions());
|
|
}
|
|
}
|
|
|
|
void EntityItemProperties::clearSimulationRestrictedProperties() {
|
|
_positionChanged = false;
|
|
_localPositionChanged = false;
|
|
_rotationChanged = false;
|
|
_localRotationChanged = false;
|
|
_velocityChanged = false;
|
|
_localVelocityChanged = false;
|
|
_angularVelocityChanged = false;
|
|
_localAngularVelocityChanged = false;
|
|
_accelerationChanged = false;
|
|
_parentIDChanged = false;
|
|
_parentJointIndexChanged = false;
|
|
}
|
|
|
|
void EntityItemProperties::clearSimulationOwner() {
|
|
_simulationOwner.clear();
|
|
_simulationOwnerChanged = true;
|
|
}
|
|
|
|
void EntityItemProperties::setSimulationOwner(const QUuid& id, uint8_t priority) {
|
|
if (!_simulationOwner.matchesValidID(id) || _simulationOwner.getPriority() != priority) {
|
|
_simulationOwner.set(id, priority);
|
|
_simulationOwnerChanged = true;
|
|
}
|
|
}
|
|
|
|
void EntityItemProperties::setSimulationOwner(const QByteArray& data) {
|
|
if (_simulationOwner.fromByteArray(data)) {
|
|
_simulationOwnerChanged = true;
|
|
}
|
|
}
|
|
|
|
uint8_t EntityItemProperties::computeSimulationBidPriority() const {
|
|
uint8_t priority = 0;
|
|
if (_parentIDChanged || _parentJointIndexChanged) {
|
|
// we need higher simulation ownership priority to chang parenting info
|
|
priority = SCRIPT_GRAB_SIMULATION_PRIORITY;
|
|
} else if (_positionChanged || _localPositionChanged
|
|
|| _rotationChanged || _localRotationChanged
|
|
|| _velocityChanged || _localVelocityChanged
|
|
|| _angularVelocityChanged || _localAngularVelocityChanged) {
|
|
priority = SCRIPT_POKE_SIMULATION_PRIORITY;
|
|
}
|
|
return priority;
|
|
}
|
|
|
|
QList<QString> EntityItemProperties::listChangedProperties() {
|
|
QList<QString> out;
|
|
|
|
// Core
|
|
if (simulationOwnerChanged()) {
|
|
out += "simulationOwner";
|
|
}
|
|
if (parentIDChanged()) {
|
|
out += "parentID";
|
|
}
|
|
if (parentJointIndexChanged()) {
|
|
out += "parentJointIndex";
|
|
}
|
|
if (visibleChanged()) {
|
|
out += "visible";
|
|
}
|
|
if (nameChanged()) {
|
|
out += "name";
|
|
}
|
|
if (lockedChanged()) {
|
|
out += "locked";
|
|
}
|
|
if (userDataChanged()) {
|
|
out += "userData";
|
|
}
|
|
if (privateUserDataChanged()) {
|
|
out += "privateUserData";
|
|
}
|
|
if (hrefChanged()) {
|
|
out += "href";
|
|
}
|
|
if (descriptionChanged()) {
|
|
out += "description";
|
|
}
|
|
if (containsPositionChange()) {
|
|
out += "position";
|
|
}
|
|
if (dimensionsChanged()) {
|
|
out += "dimensions";
|
|
}
|
|
if (rotationChanged()) {
|
|
out += "rotation";
|
|
}
|
|
if (registrationPointChanged()) {
|
|
out += "registrationPoint";
|
|
}
|
|
if (createdChanged()) {
|
|
out += "created";
|
|
}
|
|
if (lastEditedByChanged()) {
|
|
out += "lastEditedBy";
|
|
}
|
|
if (entityHostTypeChanged()) {
|
|
out += "entityHostType";
|
|
}
|
|
if (owningAvatarIDChanged()) {
|
|
out += "owningAvatarID";
|
|
}
|
|
if (queryAACubeChanged()) {
|
|
out += "queryAACube";
|
|
}
|
|
if (canCastShadowChanged()) {
|
|
out += "canCastShadow";
|
|
}
|
|
if (isVisibleInSecondaryCameraChanged()) {
|
|
out += "isVisibleInSecondaryCamera";
|
|
}
|
|
if (renderLayerChanged()) {
|
|
out += "renderLayer";
|
|
}
|
|
if (primitiveModeChanged()) {
|
|
out += "primitiveMode";
|
|
}
|
|
if (ignorePickIntersectionChanged()) {
|
|
out += "ignorePickIntersection";
|
|
}
|
|
if (renderWithZonesChanged()) {
|
|
out += "renderWithZones";
|
|
}
|
|
getGrab().listChangedProperties(out);
|
|
|
|
// Physics
|
|
if (densityChanged()) {
|
|
out += "density";
|
|
}
|
|
if (velocityChanged()) {
|
|
out += "velocity";
|
|
}
|
|
if (angularVelocityChanged()) {
|
|
out += "angularVelocity";
|
|
}
|
|
if (gravityChanged()) {
|
|
out += "gravity";
|
|
}
|
|
if (accelerationChanged()) {
|
|
out += "acceleration";
|
|
}
|
|
if (dampingChanged()) {
|
|
out += "damping";
|
|
}
|
|
if (angularDampingChanged()) {
|
|
out += "angularDamping";
|
|
}
|
|
if (restitutionChanged()) {
|
|
out += "restitution";
|
|
}
|
|
if (frictionChanged()) {
|
|
out += "friction";
|
|
}
|
|
if (lifetimeChanged()) {
|
|
out += "lifetime";
|
|
}
|
|
if (collisionlessChanged()) {
|
|
out += "collisionless";
|
|
}
|
|
if (collisionMaskChanged()) {
|
|
out += "collisionMask";
|
|
}
|
|
if (dynamicChanged()) {
|
|
out += "dynamic";
|
|
}
|
|
if (collisionSoundURLChanged()) {
|
|
out += "collisionSoundURL";
|
|
}
|
|
if (actionDataChanged()) {
|
|
out += "actionData";
|
|
}
|
|
|
|
// Cloning
|
|
if (cloneableChanged()) {
|
|
out += "cloneable";
|
|
}
|
|
if (cloneLifetimeChanged()) {
|
|
out += "cloneLifetime";
|
|
}
|
|
if (cloneLimitChanged()) {
|
|
out += "cloneLimit";
|
|
}
|
|
if (cloneDynamicChanged()) {
|
|
out += "cloneDynamic";
|
|
}
|
|
if (cloneAvatarEntityChanged()) {
|
|
out += "cloneAvatarEntity";
|
|
}
|
|
if (cloneOriginIDChanged()) {
|
|
out += "cloneOriginID";
|
|
}
|
|
|
|
// Scripts
|
|
if (scriptChanged()) {
|
|
out += "script";
|
|
}
|
|
if (scriptTimestampChanged()) {
|
|
out += "scriptTimestamp";
|
|
}
|
|
if (serverScriptsChanged()) {
|
|
out += "serverScripts";
|
|
}
|
|
|
|
// Certifiable Properties
|
|
if (itemNameChanged()) {
|
|
out += "itemName";
|
|
}
|
|
if (itemDescriptionChanged()) {
|
|
out += "itemDescription";
|
|
}
|
|
if (itemCategoriesChanged()) {
|
|
out += "itemCategories";
|
|
}
|
|
if (itemArtistChanged()) {
|
|
out += "itemArtist";
|
|
}
|
|
if (itemLicenseChanged()) {
|
|
out += "itemLicense";
|
|
}
|
|
if (limitedRunChanged()) {
|
|
out += "limitedRun";
|
|
}
|
|
if (marketplaceIDChanged()) {
|
|
out += "marketplaceID";
|
|
}
|
|
if (editionNumberChanged()) {
|
|
out += "editionNumber";
|
|
}
|
|
if (entityInstanceNumberChanged()) {
|
|
out += "entityInstanceNumber";
|
|
}
|
|
if (certificateIDChanged()) {
|
|
out += "certificateID";
|
|
}
|
|
if (certificateTypeChanged()) {
|
|
out += "certificateType";
|
|
}
|
|
if (staticCertificateVersionChanged()) {
|
|
out += "staticCertificateVersion";
|
|
}
|
|
|
|
// Common
|
|
if (shapeTypeChanged()) {
|
|
out += "shapeType";
|
|
}
|
|
if (compoundShapeURLChanged()) {
|
|
out += "compoundShapeURL";
|
|
}
|
|
if (colorChanged()) {
|
|
out += "color";
|
|
}
|
|
if (alphaChanged()) {
|
|
out += "alpha";
|
|
}
|
|
getPulse().listChangedProperties(out);
|
|
if (texturesChanged()) {
|
|
out += "textures";
|
|
}
|
|
if (billboardModeChanged()) {
|
|
out += "billboardMode";
|
|
}
|
|
|
|
// Particles
|
|
if (maxParticlesChanged()) {
|
|
out += "maxParticles";
|
|
}
|
|
if (lifespanChanged()) {
|
|
out += "lifespan";
|
|
}
|
|
if (isEmittingChanged()) {
|
|
out += "isEmitting";
|
|
}
|
|
if (emitRateChanged()) {
|
|
out += "emitRate";
|
|
}
|
|
if (emitSpeedChanged()) {
|
|
out += "emitSpeed";
|
|
}
|
|
if (speedSpreadChanged()) {
|
|
out += "speedSpread";
|
|
}
|
|
if (emitOrientationChanged()) {
|
|
out += "emitOrientation";
|
|
}
|
|
if (emitDimensionsChanged()) {
|
|
out += "emitDimensions";
|
|
}
|
|
if (emitRadiusStartChanged()) {
|
|
out += "emitRadiusStart";
|
|
}
|
|
if (polarStartChanged()) {
|
|
out += "polarStart";
|
|
}
|
|
if (polarFinishChanged()) {
|
|
out += "polarFinish";
|
|
}
|
|
if (azimuthStartChanged()) {
|
|
out += "azimuthStart";
|
|
}
|
|
if (azimuthFinishChanged()) {
|
|
out += "azimuthFinish";
|
|
}
|
|
if (emitAccelerationChanged()) {
|
|
out += "emitAcceleration";
|
|
}
|
|
if (accelerationSpreadChanged()) {
|
|
out += "accelerationSpread";
|
|
}
|
|
if (particleRadiusChanged()) {
|
|
out += "particleRadius";
|
|
}
|
|
if (radiusSpreadChanged()) {
|
|
out += "radiusSpread";
|
|
}
|
|
if (radiusStartChanged()) {
|
|
out += "radiusStart";
|
|
}
|
|
if (radiusFinishChanged()) {
|
|
out += "radiusFinish";
|
|
}
|
|
if (colorSpreadChanged()) {
|
|
out += "colorSpread";
|
|
}
|
|
if (colorStartChanged()) {
|
|
out += "colorStart";
|
|
}
|
|
if (colorFinishChanged()) {
|
|
out += "colorFinish";
|
|
}
|
|
if (alphaSpreadChanged()) {
|
|
out += "alphaSpread";
|
|
}
|
|
if (alphaStartChanged()) {
|
|
out += "alphaStart";
|
|
}
|
|
if (alphaFinishChanged()) {
|
|
out += "alphaFinish";
|
|
}
|
|
if (emitterShouldTrailChanged()) {
|
|
out += "emitterShouldTrail";
|
|
}
|
|
if (particleSpinChanged()) {
|
|
out += "particleSpin";
|
|
}
|
|
if (spinSpreadChanged()) {
|
|
out += "spinSpread";
|
|
}
|
|
if (spinStartChanged()) {
|
|
out += "spinStart";
|
|
}
|
|
if (spinFinishChanged()) {
|
|
out += "spinFinish";
|
|
}
|
|
if (rotateWithEntityChanged()) {
|
|
out += "rotateWithEntity";
|
|
}
|
|
|
|
// Model
|
|
if (modelURLChanged()) {
|
|
out += "modelURL";
|
|
}
|
|
if (modelScaleChanged()) {
|
|
out += "scale";
|
|
}
|
|
if (jointRotationsSetChanged()) {
|
|
out += "jointRotationsSet";
|
|
}
|
|
if (jointRotationsChanged()) {
|
|
out += "jointRotations";
|
|
}
|
|
if (jointTranslationsSetChanged()) {
|
|
out += "jointTranslationsSet";
|
|
}
|
|
if (jointTranslationsChanged()) {
|
|
out += "jointTranslations";
|
|
}
|
|
if (relayParentJointsChanged()) {
|
|
out += "relayParentJoints";
|
|
}
|
|
if (groupCulledChanged()) {
|
|
out += "groupCulled";
|
|
}
|
|
getAnimation().listChangedProperties(out);
|
|
|
|
// Light
|
|
if (isSpotlightChanged()) {
|
|
out += "isSpotlight";
|
|
}
|
|
if (intensityChanged()) {
|
|
out += "intensity";
|
|
}
|
|
if (exponentChanged()) {
|
|
out += "exponent";
|
|
}
|
|
if (cutoffChanged()) {
|
|
out += "cutoff";
|
|
}
|
|
if (falloffRadiusChanged()) {
|
|
out += "falloffRadius";
|
|
}
|
|
|
|
// Text
|
|
if (textChanged()) {
|
|
out += "text";
|
|
}
|
|
if (lineHeightChanged()) {
|
|
out += "lineHeight";
|
|
}
|
|
if (textColorChanged()) {
|
|
out += "textColor";
|
|
}
|
|
if (textAlphaChanged()) {
|
|
out += "textAlpha";
|
|
}
|
|
if (backgroundColorChanged()) {
|
|
out += "backgroundColor";
|
|
}
|
|
if (backgroundAlphaChanged()) {
|
|
out += "backgroundAlpha";
|
|
}
|
|
if (leftMarginChanged()) {
|
|
out += "leftMargin";
|
|
}
|
|
if (rightMarginChanged()) {
|
|
out += "rightMargin";
|
|
}
|
|
if (topMarginChanged()) {
|
|
out += "topMargin";
|
|
}
|
|
if (bottomMarginChanged()) {
|
|
out += "bottomMargin";
|
|
}
|
|
if (unlitChanged()) {
|
|
out += "unlit";
|
|
}
|
|
if (fontChanged()) {
|
|
out += "font";
|
|
}
|
|
if (textEffectChanged()) {
|
|
out += "textEffect";
|
|
}
|
|
if (textEffectColorChanged()) {
|
|
out += "textEffectColor";
|
|
}
|
|
if (textEffectThicknessChanged()) {
|
|
out += "textEffectThickness";
|
|
}
|
|
|
|
// Zone
|
|
getKeyLight().listChangedProperties(out);
|
|
getAmbientLight().listChangedProperties(out);
|
|
getSkybox().listChangedProperties(out);
|
|
getHaze().listChangedProperties(out);
|
|
getBloom().listChangedProperties(out);
|
|
if (flyingAllowedChanged()) {
|
|
out += "flyingAllowed";
|
|
}
|
|
if (ghostingAllowedChanged()) {
|
|
out += "ghostingAllowed";
|
|
}
|
|
if (filterURLChanged()) {
|
|
out += "filterURL";
|
|
}
|
|
if (keyLightModeChanged()) {
|
|
out += "keyLightMode";
|
|
}
|
|
if (ambientLightModeChanged()) {
|
|
out += "ambientLightMode";
|
|
}
|
|
if (skyboxModeChanged()) {
|
|
out += "skyboxMode";
|
|
}
|
|
if (hazeModeChanged()) {
|
|
out += "hazeMode";
|
|
}
|
|
if (bloomModeChanged()) {
|
|
out += "bloomMode";
|
|
}
|
|
if (avatarPriorityChanged()) {
|
|
out += "avatarPriority";
|
|
}
|
|
if (screenshareChanged()) {
|
|
out += "screenshare";
|
|
}
|
|
|
|
// Polyvox
|
|
if (voxelVolumeSizeChanged()) {
|
|
out += "voxelVolumeSize";
|
|
}
|
|
if (voxelDataChanged()) {
|
|
out += "voxelData";
|
|
}
|
|
if (voxelSurfaceStyleChanged()) {
|
|
out += "voxelSurfaceStyle";
|
|
}
|
|
if (xTextureURLChanged()) {
|
|
out += "xTextureURL";
|
|
}
|
|
if (yTextureURLChanged()) {
|
|
out += "yTextureURL";
|
|
}
|
|
if (zTextureURLChanged()) {
|
|
out += "zTextureURL";
|
|
}
|
|
if (xNNeighborIDChanged()) {
|
|
out += "xNNeighborID";
|
|
}
|
|
if (yNNeighborIDChanged()) {
|
|
out += "yNNeighborID";
|
|
}
|
|
if (zNNeighborIDChanged()) {
|
|
out += "zNNeighborID";
|
|
}
|
|
if (xPNeighborIDChanged()) {
|
|
out += "xPNeighborID";
|
|
}
|
|
if (yPNeighborIDChanged()) {
|
|
out += "yPNeighborID";
|
|
}
|
|
if (zPNeighborIDChanged()) {
|
|
out += "zPNeighborID";
|
|
}
|
|
|
|
// Web
|
|
if (sourceUrlChanged()) {
|
|
out += "sourceUrl";
|
|
}
|
|
if (dpiChanged()) {
|
|
out += "dpi";
|
|
}
|
|
if (scriptURLChanged()) {
|
|
out += "scriptURL";
|
|
}
|
|
if (maxFPSChanged()) {
|
|
out += "maxFPS";
|
|
}
|
|
if (inputModeChanged()) {
|
|
out += "inputMode";
|
|
}
|
|
|
|
// Polyline
|
|
if (linePointsChanged()) {
|
|
out += "linePoints";
|
|
}
|
|
if (strokeWidthsChanged()) {
|
|
out += "strokeWidths";
|
|
}
|
|
if (normalsChanged()) {
|
|
out += "normals";
|
|
}
|
|
if (strokeColorsChanged()) {
|
|
out += "strokeColors";
|
|
}
|
|
if (isUVModeStretchChanged()) {
|
|
out += "isUVModeStretch";
|
|
}
|
|
if (glowChanged()) {
|
|
out += "glow";
|
|
}
|
|
if (faceCameraChanged()) {
|
|
out += "faceCamera";
|
|
}
|
|
if (showKeyboardFocusHighlightChanged()) {
|
|
out += "showKeyboardFocusHighlight";
|
|
}
|
|
|
|
// Shape
|
|
if (shapeChanged()) {
|
|
out += "shape";
|
|
}
|
|
|
|
// Material
|
|
if (materialURLChanged()) {
|
|
out += "materialURL";
|
|
}
|
|
if (materialMappingModeChanged()) {
|
|
out += "materialMappingMode";
|
|
}
|
|
if (priorityChanged()) {
|
|
out += "priority";
|
|
}
|
|
if (parentMaterialNameChanged()) {
|
|
out += "parentMaterialName";
|
|
}
|
|
if (materialMappingPosChanged()) {
|
|
out += "materialMappingPos";
|
|
}
|
|
if (materialMappingScaleChanged()) {
|
|
out += "materialMappingScale";
|
|
}
|
|
if (materialMappingRotChanged()) {
|
|
out += "materialMappingRot";
|
|
}
|
|
if (materialDataChanged()) {
|
|
out += "materialData";
|
|
}
|
|
if (materialRepeatChanged()) {
|
|
out += "materialRepeat";
|
|
}
|
|
|
|
// Image
|
|
if (imageURLChanged()) {
|
|
out += "imageURL";
|
|
}
|
|
if (emissiveChanged()) {
|
|
out += "emissive";
|
|
}
|
|
if (keepAspectRatioChanged()) {
|
|
out += "keepAspectRatio";
|
|
}
|
|
if (subImageChanged()) {
|
|
out += "subImage";
|
|
}
|
|
|
|
// Grid
|
|
if (followCameraChanged()) {
|
|
out += "followCamera";
|
|
}
|
|
if (majorGridEveryChanged()) {
|
|
out += "majorGridEvery";
|
|
}
|
|
if (minorGridEveryChanged()) {
|
|
out += "minorGridEvery";
|
|
}
|
|
|
|
// Gizmo
|
|
if (gizmoTypeChanged()) {
|
|
out += "gizmoType";
|
|
}
|
|
getRing().listChangedProperties(out);
|
|
|
|
return out;
|
|
}
|
|
|
|
bool EntityItemProperties::transformChanged() const {
|
|
return positionChanged() || rotationChanged() ||
|
|
localPositionChanged() || localRotationChanged();
|
|
}
|
|
|
|
bool EntityItemProperties::getScalesWithParent() const {
|
|
// keep this logic the same as in EntityItem::getScalesWithParent
|
|
bool scalesWithParent { false };
|
|
if (parentIDChanged()) {
|
|
bool success;
|
|
SpatiallyNestablePointer parent = SpatiallyNestable::findByID(getParentID(), success);
|
|
if (success && parent) {
|
|
bool avatarAncestor = (parent->getNestableType() == NestableType::Avatar ||
|
|
parent->hasAncestorOfType(NestableType::Avatar));
|
|
scalesWithParent = getEntityHostType() == entity::HostType::AVATAR && avatarAncestor;
|
|
}
|
|
}
|
|
return scalesWithParent;
|
|
}
|
|
|
|
bool EntityItemProperties::parentRelatedPropertyChanged() const {
|
|
return positionChanged() || rotationChanged() ||
|
|
localPositionChanged() || localRotationChanged() ||
|
|
localDimensionsChanged() ||
|
|
parentIDChanged() || parentJointIndexChanged();
|
|
}
|
|
|
|
bool EntityItemProperties::queryAACubeRelatedPropertyChanged() const {
|
|
return parentRelatedPropertyChanged() || dimensionsChanged();
|
|
}
|
|
|
|
bool EntityItemProperties::grabbingRelatedPropertyChanged() const {
|
|
const GrabPropertyGroup& grabProperties = getGrab();
|
|
return grabProperties.triggerableChanged() || grabProperties.grabbableChanged() ||
|
|
grabProperties.grabFollowsControllerChanged() || grabProperties.grabKinematicChanged() ||
|
|
grabProperties.equippableChanged() || grabProperties.equippableLeftPositionChanged() ||
|
|
grabProperties.equippableRightPositionChanged() || grabProperties.equippableLeftRotationChanged() ||
|
|
grabProperties.equippableRightRotationChanged() || grabProperties.equippableIndicatorURLChanged() ||
|
|
grabProperties.equippableIndicatorScaleChanged() || grabProperties.equippableIndicatorOffsetChanged();
|
|
}
|
|
|
|
// Checking Certifiable Properties
|
|
#define ADD_STRING_PROPERTY(n, N) if (!get##N().isEmpty()) json[#n] = get##N()
|
|
#define ADD_ENUM_PROPERTY(n, N) json[#n] = get##N##AsString()
|
|
#define ADD_INT_PROPERTY(n, N) if (get##N() != 0) json[#n] = (get##N() == (quint32) -1) ? -1.0 : ((double) get##N())
|
|
QByteArray EntityItemProperties::getStaticCertificateJSON() const {
|
|
// Produce a compact json of every non-default static certificate property, with the property names in alphabetical order.
|
|
// The static certificate properties include all an only those properties that cannot be changed without altering the identity
|
|
// of the entity as reviewed during the certification submission.
|
|
|
|
QJsonObject json;
|
|
|
|
quint32 staticCertificateVersion = getStaticCertificateVersion();
|
|
|
|
if (!getAnimation().getURL().isEmpty()) {
|
|
json["animationURL"] = getAnimation().getURL();
|
|
}
|
|
if (staticCertificateVersion >= 3) {
|
|
ADD_STRING_PROPERTY(certificateType, CertificateType);
|
|
}
|
|
ADD_STRING_PROPERTY(collisionSoundURL, CollisionSoundURL);
|
|
ADD_STRING_PROPERTY(compoundShapeURL, CompoundShapeURL);
|
|
ADD_INT_PROPERTY(editionNumber, EditionNumber);
|
|
ADD_INT_PROPERTY(entityInstanceNumber, EntityInstanceNumber);
|
|
ADD_STRING_PROPERTY(itemArtist, ItemArtist);
|
|
ADD_STRING_PROPERTY(itemCategories, ItemCategories);
|
|
ADD_STRING_PROPERTY(itemDescription, ItemDescription);
|
|
ADD_STRING_PROPERTY(itemLicenseUrl, ItemLicense);
|
|
ADD_STRING_PROPERTY(itemName, ItemName);
|
|
ADD_INT_PROPERTY(limitedRun, LimitedRun);
|
|
ADD_STRING_PROPERTY(marketplaceID, MarketplaceID);
|
|
ADD_STRING_PROPERTY(modelURL, ModelURL);
|
|
ADD_STRING_PROPERTY(script, Script);
|
|
if (staticCertificateVersion >= 1) {
|
|
ADD_STRING_PROPERTY(serverScripts, ServerScripts);
|
|
}
|
|
ADD_ENUM_PROPERTY(shapeType, ShapeType);
|
|
ADD_INT_PROPERTY(staticCertificateVersion, StaticCertificateVersion);
|
|
json["type"] = EntityTypes::getEntityTypeName(getType());
|
|
|
|
return QJsonDocument(json).toJson(QJsonDocument::Compact);
|
|
}
|
|
QByteArray EntityItemProperties::getStaticCertificateHash() const {
|
|
return QCryptographicHash::hash(getStaticCertificateJSON(), QCryptographicHash::Sha256);
|
|
}
|
|
|
|
// FIXME: This is largely copied from EntityItemProperties::verifyStaticCertificateProperties, which should be refactored to use this.
|
|
// I also don't like the nested-if style, but for this step I'm deliberately preserving the similarity.
|
|
bool EntityItemProperties::verifySignature(const QString& publicKey, const QByteArray& digestByteArray, const QByteArray& signatureByteArray) {
|
|
|
|
if (digestByteArray.isEmpty()) {
|
|
return false;
|
|
}
|
|
|
|
auto keyByteArray = publicKey.toUtf8();
|
|
auto key = keyByteArray.constData();
|
|
int keyLength = publicKey.length();
|
|
|
|
BIO *bio = BIO_new_mem_buf((void*)key, keyLength);
|
|
EVP_PKEY* evp_key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
|
|
if (evp_key) {
|
|
EC_KEY* ec = EVP_PKEY_get1_EC_KEY(evp_key);
|
|
if (ec) {
|
|
const unsigned char* digest = reinterpret_cast<const unsigned char*>(digestByteArray.constData());
|
|
int digestLength = digestByteArray.length();
|
|
|
|
const unsigned char* signature = reinterpret_cast<const unsigned char*>(signatureByteArray.constData());
|
|
int signatureLength = signatureByteArray.length();
|
|
|
|
ERR_clear_error();
|
|
// ECSDA verification prototype: note that type is currently ignored
|
|
// int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen,
|
|
// const unsigned char *sig, int siglen, EC_KEY *eckey);
|
|
int answer = ECDSA_verify(0,
|
|
digest,
|
|
digestLength,
|
|
signature,
|
|
signatureLength,
|
|
ec);
|
|
long error = ERR_get_error();
|
|
if (error != 0 || answer == -1) {
|
|
qCWarning(entities) << "ERROR while verifying signature!"
|
|
<< "\nKey:" << publicKey << "\nutf8 Key Length:" << keyLength
|
|
<< "\nDigest:" << digest << "\nDigest Length:" << digestLength
|
|
<< "\nSignature:" << signature << "\nSignature Length:" << signatureLength;
|
|
while (error != 0) {
|
|
const char* error_str = ERR_error_string(error, NULL);
|
|
qCWarning(entities) << "EC error:" << error_str;
|
|
error = ERR_get_error();
|
|
}
|
|
}
|
|
EC_KEY_free(ec);
|
|
if (bio) {
|
|
BIO_free(bio);
|
|
}
|
|
if (evp_key) {
|
|
EVP_PKEY_free(evp_key);
|
|
}
|
|
return (answer == 1);
|
|
} else {
|
|
if (bio) {
|
|
BIO_free(bio);
|
|
}
|
|
if (evp_key) {
|
|
EVP_PKEY_free(evp_key);
|
|
}
|
|
long error = ERR_get_error();
|
|
const char* error_str = ERR_error_string(error, NULL);
|
|
qCWarning(entities) << "Failed to verify signature! key" << publicKey << " EC key error:" << error_str;
|
|
return false;
|
|
}
|
|
} else {
|
|
if (bio) {
|
|
BIO_free(bio);
|
|
}
|
|
long error = ERR_get_error();
|
|
const char* error_str = ERR_error_string(error, NULL);
|
|
qCWarning(entities) << "Failed to verify signature! key" << publicKey << " EC PEM error:" << error_str;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool EntityItemProperties::verifyStaticCertificateProperties() {
|
|
// True IFF a non-empty certificateID matches the static certificate json.
|
|
// I.e., if we can verify that the certificateID was produced by Vircadia signing the static certificate hash.
|
|
return verifySignature(EntityItem::_marketplacePublicKey, getStaticCertificateHash(), QByteArray::fromBase64(getCertificateID().toUtf8()));
|
|
}
|
|
|
|
void EntityItemProperties::convertToCloneProperties(const EntityItemID& entityIDToClone) {
|
|
setName(getName() + "-clone-" + entityIDToClone.toString());
|
|
setLocked(false);
|
|
setParentID(QUuid());
|
|
setParentJointIndex(-1);
|
|
setLifetime(getCloneLifetime());
|
|
setDynamic(getCloneDynamic());
|
|
if (getEntityHostType() != entity::HostType::LOCAL) {
|
|
setEntityHostType(getCloneAvatarEntity() ? entity::HostType::AVATAR : entity::HostType::DOMAIN);
|
|
} else {
|
|
// Local Entities clone as local entities
|
|
setEntityHostType(entity::HostType::LOCAL);
|
|
setCollisionless(true);
|
|
}
|
|
uint64_t now = usecTimestampNow();
|
|
setCreated(now);
|
|
setLastEdited(now);
|
|
setCloneable(ENTITY_ITEM_DEFAULT_CLONEABLE);
|
|
setCloneLifetime(ENTITY_ITEM_DEFAULT_CLONE_LIFETIME);
|
|
setCloneLimit(ENTITY_ITEM_DEFAULT_CLONE_LIMIT);
|
|
setCloneDynamic(ENTITY_ITEM_DEFAULT_CLONE_DYNAMIC);
|
|
setCloneAvatarEntity(ENTITY_ITEM_DEFAULT_CLONE_AVATAR_ENTITY);
|
|
}
|
|
|
|
bool EntityItemProperties::blobToProperties(QScriptEngine& scriptEngine, const QByteArray& blob, EntityItemProperties& properties) {
|
|
// DANGER: this method is NOT efficient.
|
|
// begin recipe for converting unfortunately-formatted-binary-blob to EntityItemProperties
|
|
QJsonDocument jsonProperties = QJsonDocument::fromBinaryData(blob);
|
|
if (jsonProperties.isEmpty() || jsonProperties.isNull() || !jsonProperties.isObject() || jsonProperties.object().isEmpty()) {
|
|
qCDebug(entities) << "bad avatarEntityData json" << QString(blob.toHex());
|
|
return false;
|
|
}
|
|
QVariant variant = jsonProperties.toVariant();
|
|
QVariantMap variantMap = variant.toMap();
|
|
QScriptValue scriptValue = variantMapToScriptValue(variantMap, scriptEngine);
|
|
EntityItemPropertiesFromScriptValueIgnoreReadOnly(scriptValue, properties);
|
|
// end recipe
|
|
return true;
|
|
}
|
|
|
|
void EntityItemProperties::propertiesToBlob(QScriptEngine& scriptEngine, const QUuid& myAvatarID,
|
|
const EntityItemProperties& properties, QByteArray& blob, bool allProperties) {
|
|
// DANGER: this method is NOT efficient.
|
|
// begin recipe for extracting unfortunately-formatted-binary-blob from EntityItem
|
|
QScriptValue scriptValue = allProperties
|
|
? EntityItemPropertiesToScriptValue(&scriptEngine, properties)
|
|
: EntityItemNonDefaultPropertiesToScriptValue(&scriptEngine, properties);
|
|
QVariant variantProperties = scriptValue.toVariant();
|
|
QJsonDocument jsonProperties = QJsonDocument::fromVariant(variantProperties);
|
|
// the ID of the parent/avatar changes from session to session. use a special UUID to indicate the avatar
|
|
QJsonObject jsonObject = jsonProperties.object();
|
|
if (jsonObject.contains("parentID")) {
|
|
if (QUuid(jsonObject["parentID"].toString()) == myAvatarID) {
|
|
jsonObject["parentID"] = AVATAR_SELF_ID.toString();
|
|
}
|
|
}
|
|
jsonProperties = QJsonDocument(jsonObject);
|
|
blob = jsonProperties.toBinaryData();
|
|
// end recipe
|
|
}
|
|
|
|
QDebug& operator<<(QDebug& dbg, const EntityPropertyFlags& f) {
|
|
QString result = "[ ";
|
|
|
|
for (int i = 0; i < PROP_AFTER_LAST_ITEM; i++) {
|
|
auto prop = EntityPropertyList(i);
|
|
if (f.getHasProperty(prop)) {
|
|
result = result + _enumsToPropertyStrings[prop] + " ";
|
|
}
|
|
}
|
|
|
|
result += "]";
|
|
dbg.nospace() << result;
|
|
return dbg;
|
|
}
|