diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 94d0024fd5..cd0f550a05 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1693,7 +1693,8 @@ float EntityItem::getVolumeEstimate() const { void EntityItem::setRegistrationPoint(const glm::vec3& value) { if (value != _registrationPoint) { withWriteLock([&] { - _registrationPoint = glm::clamp(value, 0.0f, 1.0f); + _registrationPoint = glm::clamp(value, glm::vec3(ENTITY_ITEM_MIN_REGISTRATION_POINT), + glm::vec3(ENTITY_ITEM_MAX_REGISTRATION_POINT)); }); dimensionsChanged(); // Registration Point affects the bounding box markDirtyFlags(Simulation::DIRTY_SHAPE); @@ -1858,7 +1859,7 @@ void EntityItem::setVelocity(const glm::vec3& value) { } void EntityItem::setDamping(float value) { - auto clampedDamping = glm::clamp(value, 0.0f, 1.0f); + auto clampedDamping = glm::clamp(value, ENTITY_ITEM_MIN_DAMPING, ENTITY_ITEM_MAX_DAMPING); withWriteLock([&] { if (_damping != clampedDamping) { _damping = clampedDamping; @@ -1913,7 +1914,7 @@ void EntityItem::setAngularVelocity(const glm::vec3& value) { } void EntityItem::setAngularDamping(float value) { - auto clampedDamping = glm::clamp(value, 0.0f, 1.0f); + auto clampedDamping = glm::clamp(value, ENTITY_ITEM_MIN_DAMPING, ENTITY_ITEM_MAX_DAMPING); withWriteLock([&] { if (_angularDamping != clampedDamping) { _angularDamping = clampedDamping; diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 3eb193f1bd..5616d04ea4 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -2158,8 +2158,6 @@ void EntityItemPropertiesFromScriptValueHonorReadOnly(const QScriptValue &object QScriptValue EntityPropertyFlagsToScriptValue(QScriptEngine* engine, const EntityPropertyFlags& flags) { return EntityItemProperties::entityPropertyFlagsToScriptValue(engine, flags); - QScriptValue result = engine->newObject(); - return result; } void EntityPropertyFlagsFromScriptValue(const QScriptValue& object, EntityPropertyFlags& flags) { @@ -2172,25 +2170,48 @@ QScriptValue EntityItemProperties::entityPropertyFlagsToScriptValue(QScriptEngin return result; } -static QHash _propertyStringsToEnums; - 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 _propertyInfos; + +bool EntityItemProperties::getPropertyInfo(const QString& propertyName, EntityPropertyInfo& propertyInfo) { static std::once_flag initMap; - + std::call_once(initMap, []() { ADD_PROPERTY_TO_MAP(PROP_VISIBLE, Visible, visible, bool); ADD_PROPERTY_TO_MAP(PROP_CAN_CAST_SHADOW, CanCastShadow, canCastShadow, bool); ADD_PROPERTY_TO_MAP(PROP_POSITION, Position, position, vec3); - ADD_PROPERTY_TO_MAP(PROP_DIMENSIONS, Dimensions, dimensions, 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(PROP_DENSITY, Density, density, float); + 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_GRAVITY, Gravity, gravity, vec3); ADD_PROPERTY_TO_MAP(PROP_ACCELERATION, Acceleration, acceleration, vec3); - ADD_PROPERTY_TO_MAP(PROP_DAMPING, Damping, damping, float); - ADD_PROPERTY_TO_MAP(PROP_RESTITUTION, Restitution, restitution, float); - ADD_PROPERTY_TO_MAP(PROP_FRICTION, Friction, friction, float); + 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_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_SCRIPT, Script, script, QString); ADD_PROPERTY_TO_MAP(PROP_SCRIPT_TIMESTAMP, ScriptTimestamp, scriptTimestamp, quint64); @@ -2200,16 +2221,21 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue 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(PROP_ALPHA, Alpha, alpha, float); - ADD_PROPERTY_TO_MAP(PROP_ALPHA_SPREAD, AlphaSpread, alphaSpread, float); - ADD_PROPERTY_TO_MAP(PROP_ALPHA_START, AlphaStart, alphaStart, float); - ADD_PROPERTY_TO_MAP(PROP_ALPHA_FINISH, AlphaFinish, alphaFinish, float); + ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_ALPHA, Alpha, alpha, float, particle::MINIMUM_ALPHA, particle::MAXIMUM_ALPHA); + 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(PROP_MODEL_URL, ModelURL, modelURL, QString); ADD_PROPERTY_TO_MAP(PROP_COMPOUND_SHAPE_URL, CompoundShapeURL, compoundShapeURL, QString); - ADD_PROPERTY_TO_MAP(PROP_REGISTRATION_POINT, RegistrationPoint, registrationPoint, vec3); + 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_ANGULAR_VELOCITY, AngularVelocity, angularVelocity, vec3); - ADD_PROPERTY_TO_MAP(PROP_ANGULAR_DAMPING, AngularDamping, angularDamping, float); + ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_ANGULAR_DAMPING, AngularDamping, angularDamping, float, + ENTITY_ITEM_MIN_DAMPING, ENTITY_ITEM_MAX_DAMPING); ADD_PROPERTY_TO_MAP(PROP_COLLISIONLESS, Collisionless, collisionless, bool); ADD_PROPERTY_TO_MAP(PROP_COLLISIONLESS, unused, ignoreForCollisions, unused); // legacy support ADD_PROPERTY_TO_MAP(PROP_COLLISION_MASK, unused, collisionMask, unused); @@ -2220,7 +2246,8 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_PROPERTY_TO_MAP(PROP_INTENSITY, Intensity, intensity, float); ADD_PROPERTY_TO_MAP(PROP_FALLOFF_RADIUS, FalloffRadius, falloffRadius, float); ADD_PROPERTY_TO_MAP(PROP_EXPONENT, Exponent, exponent, float); - ADD_PROPERTY_TO_MAP(PROP_CUTOFF, Cutoff, cutoff, float); + ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_CUTOFF, Cutoff, cutoff, float, + LightEntityItem::MIN_CUTOFF, LightEntityItem::MAX_CUTOFF); ADD_PROPERTY_TO_MAP(PROP_LOCKED, Locked, locked, bool); ADD_PROPERTY_TO_MAP(PROP_TEXTURES, Textures, textures, QString); ADD_PROPERTY_TO_MAP(PROP_USER_DATA, UserData, userData, QString); @@ -2230,25 +2257,42 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_PROPERTY_TO_MAP(PROP_TEXT_COLOR, TextColor, textColor, u8vec3Color); ADD_PROPERTY_TO_MAP(PROP_BACKGROUND_COLOR, BackgroundColor, backgroundColor, u8vec3Color); ADD_PROPERTY_TO_MAP(PROP_SHAPE_TYPE, ShapeType, shapeType, ShapeType); - ADD_PROPERTY_TO_MAP(PROP_MAX_PARTICLES, MaxParticles, maxParticles, quint32); - ADD_PROPERTY_TO_MAP(PROP_LIFESPAN, Lifespan, lifespan, float); + 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(PROP_EMIT_RATE, EmitRate, emitRate, float); - ADD_PROPERTY_TO_MAP(PROP_EMIT_SPEED, EmitSpeed, emitSpeed, vec3); - ADD_PROPERTY_TO_MAP(PROP_SPEED_SPREAD, SpeedSpread, speedSpread, vec3); + 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(PROP_EMIT_DIMENSIONS, EmitDimensions, emitDimensions, vec3); - ADD_PROPERTY_TO_MAP(PROP_EMIT_RADIUS_START, EmitRadiusStart, emitRadiusStart, float); - ADD_PROPERTY_TO_MAP(PROP_POLAR_START, EmitPolarStart, polarStart, float); - ADD_PROPERTY_TO_MAP(PROP_POLAR_FINISH, EmitPolarFinish, polarFinish, float); - ADD_PROPERTY_TO_MAP(PROP_AZIMUTH_START, EmitAzimuthStart, azimuthStart, float); - ADD_PROPERTY_TO_MAP(PROP_AZIMUTH_FINISH, EmitAzimuthFinish, azimuthFinish, float); - ADD_PROPERTY_TO_MAP(PROP_EMIT_ACCELERATION, EmitAcceleration, emitAcceleration, vec3); - ADD_PROPERTY_TO_MAP(PROP_ACCELERATION_SPREAD, AccelerationSpread, accelerationSpread, vec3); - ADD_PROPERTY_TO_MAP(PROP_PARTICLE_RADIUS, ParticleRadius, particleRadius, float); - ADD_PROPERTY_TO_MAP(PROP_RADIUS_SPREAD, RadiusSpread, radiusSpread, float); - ADD_PROPERTY_TO_MAP(PROP_RADIUS_START, RadiusStart, radiusStart, float); - ADD_PROPERTY_TO_MAP(PROP_RADIUS_FINISH, RadiusFinish, radiusFinish, float); + 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_MATERIAL_URL, MaterialURL, materialURL, QString); ADD_PROPERTY_TO_MAP(PROP_MATERIAL_MAPPING_MODE, MaterialMappingMode, materialMappingMode, MaterialMappingMode); @@ -2262,10 +2306,14 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_PROPERTY_TO_MAP(PROP_VISIBLE_IN_SECONDARY_CAMERA, IsVisibleInSecondaryCamera, isVisibleInSecondaryCamera, bool); - ADD_PROPERTY_TO_MAP(PROP_PARTICLE_SPIN, ParticleSpin, particleSpin, float); - ADD_PROPERTY_TO_MAP(PROP_SPIN_SPREAD, SpinSpread, spinSpread, float); - ADD_PROPERTY_TO_MAP(PROP_SPIN_START, SpinStart, spinStart, float); - ADD_PROPERTY_TO_MAP(PROP_SPIN_FINISH, SpinFinish, spinFinish, float); + 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, -120.2365895, 1563.2556); + //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); // Certifiable Properties @@ -2318,7 +2366,8 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue 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(PROP_LOCAL_DIMENSIONS, LocalDimensions, localDimensions, vec3); + ADD_PROPERTY_TO_MAP_WITH_RANGE(PROP_LOCAL_DIMENSIONS, LocalDimensions, localDimensions, vec3, + ENTITY_ITEM_MIN_DIMENSION, FLT_MAX); ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS_SET, JointRotationsSet, jointRotationsSet, QVector); ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector); @@ -2387,19 +2436,19 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue 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_LEFT_EQUIPPABLE_POSITION_OFFSET, Grab, grab, - EquippableLeftPosition, equippableLeftPosition); + EquippableLeftPosition, equippableLeftPosition); ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET, Grab, grab, - EquippableLeftRotation, equippableLeftRotation); + EquippableLeftRotation, equippableLeftRotation); ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET, Grab, grab, - EquippableRightPosition, equippableRightPosition); + EquippableRightPosition, equippableRightPosition); ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET, Grab, grab, - EquippableRightRotation, equippableRightRotation); + EquippableRightRotation, equippableRightRotation); ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_EQUIPPABLE_INDICATOR_URL, Grab, grab, - EquippableIndicatorURL, equippableIndicatorURL); + EquippableIndicatorURL, equippableIndicatorURL); ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, Grab, grab, - EquippableIndicatorScale, equippableIndicatorScale); + EquippableIndicatorScale, equippableIndicatorScale); ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET, Grab, grab, - EquippableIndicatorOffset, equippableIndicatorOffset); + EquippableIndicatorOffset, equippableIndicatorOffset); ADD_PROPERTY_TO_MAP(PROP_IMAGE_URL, ImageURL, imageURL, QString); ADD_PROPERTY_TO_MAP(PROP_EMISSIVE, Emissive, emissive, bool); @@ -2415,21 +2464,27 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue }); - if (object.isString()) { - // TODO: figure out how to do this without a double lookup in the map - if (_propertyStringsToEnums.contains(object.toString())) { - flags << _propertyStringsToEnums[object.toString()]; - } - } else if (object.isArray()) { - quint32 length = object.property("length").toInt32(); - for (quint32 i = 0; i < length; i++) { - QString propertyName = object.property(i).toString(); - // TODO: figure out how to do this without a double lookup in the map - if (_propertyStringsToEnums.contains(propertyName)) { - flags << _propertyStringsToEnums[propertyName]; - } - } + auto iter = _propertyInfos.find(propertyName); + if (iter != _propertyInfos.end()) { + propertyInfo = *iter; + return true; } + + return false; +} + +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 diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 6fe7907777..33858c6a7f 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -63,6 +63,17 @@ const std::array COMPONENT_MODES = { { using vec3Color = glm::vec3; using u8vec3Color = glm::u8vec3; +struct EntityPropertyInfo { + EntityPropertyInfo(EntityPropertyList propEnum) : + propertyEnum(propEnum) {} + EntityPropertyInfo(EntityPropertyList propEnum, QVariant min, QVariant max) : + propertyEnum(propEnum), minimum(min), maximum(max) {} + EntityPropertyInfo() = default; + EntityPropertyList propertyEnum; + QVariant minimum; + QVariant maximum; +}; + /// A collection of properties of an entity item used in the scripting API. Translates between the actual properties of an /// entity and a JavaScript style hash/QScriptValue storing a set of properties. Used in scripting to set/get the complete /// set of entity item properties via JavaScript hashes/QScriptValues @@ -101,6 +112,8 @@ public: static QScriptValue entityPropertyFlagsToScriptValue(QScriptEngine* engine, const EntityPropertyFlags& flags); static void entityPropertyFlagsFromScriptValue(const QScriptValue& object, EntityPropertyFlags& flags); + static bool getPropertyInfo(const QString& propertyName, EntityPropertyInfo& propertyInfo); + // editing related features supported by all entities quint64 getLastEdited() const { return _lastEdited; } float getEditedAgo() const /// Elapsed seconds since this entity was last edited @@ -458,6 +471,9 @@ Q_DECLARE_METATYPE(EntityPropertyFlags); QScriptValue EntityPropertyFlagsToScriptValue(QScriptEngine* engine, const EntityPropertyFlags& flags); void EntityPropertyFlagsFromScriptValue(const QScriptValue& object, EntityPropertyFlags& flags); +Q_DECLARE_METATYPE(EntityPropertyInfo); +QScriptValue EntityPropertyInfoToScriptValue(QScriptEngine* engine, const EntityPropertyInfo& propertyInfo); +void EntityPropertyInfoFromScriptValue(const QScriptValue& object, EntityPropertyInfo& propertyInfo); // define these inline here so the macros work inline void EntityItemProperties::setPosition(const glm::vec3& value) diff --git a/libraries/entities/src/EntityItemPropertiesDefaults.h b/libraries/entities/src/EntityItemPropertiesDefaults.h index 6c39e90c91..85f04b9a6b 100644 --- a/libraries/entities/src/EntityItemPropertiesDefaults.h +++ b/libraries/entities/src/EntityItemPropertiesDefaults.h @@ -53,6 +53,9 @@ const QString ENTITY_ITEM_DEFAULT_SCRIPT = QString(""); const quint64 ENTITY_ITEM_DEFAULT_SCRIPT_TIMESTAMP = 0; const QString ENTITY_ITEM_DEFAULT_SERVER_SCRIPTS = QString(""); const QString ENTITY_ITEM_DEFAULT_COLLISION_SOUND_URL = QString(""); + +const float ENTITY_ITEM_MIN_REGISTRATION_POINT = 0.0f; +const float ENTITY_ITEM_MAX_REGISTRATION_POINT = 1.0f; const glm::vec3 ENTITY_ITEM_DEFAULT_REGISTRATION_POINT = ENTITY_ITEM_HALF_VEC3; // center const float ENTITY_ITEM_IMMORTAL_LIFETIME = -1.0f; /// special lifetime which means the entity lives for ever @@ -75,6 +78,8 @@ const glm::vec3 ENTITY_ITEM_DEFAULT_VELOCITY = ENTITY_ITEM_ZERO_VEC3; const glm::vec3 ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY = ENTITY_ITEM_ZERO_VEC3; const glm::vec3 ENTITY_ITEM_DEFAULT_GRAVITY = ENTITY_ITEM_ZERO_VEC3; const glm::vec3 ENTITY_ITEM_DEFAULT_ACCELERATION = ENTITY_ITEM_ZERO_VEC3; +const float ENTITY_ITEM_MIN_DAMPING = 0.0f; +const float ENTITY_ITEM_MAX_DAMPING = 1.0f; const float ENTITY_ITEM_DEFAULT_DAMPING = 0.39347f; // approx timescale = 2.0 sec (see damping timescale formula in header) const float ENTITY_ITEM_DEFAULT_ANGULAR_DAMPING = 0.39347f; // approx timescale = 2.0 sec (see damping timescale formula in header) diff --git a/libraries/entities/src/EntityItemPropertiesMacros.h b/libraries/entities/src/EntityItemPropertiesMacros.h index c963c66187..b8c15823f9 100644 --- a/libraries/entities/src/EntityItemPropertiesMacros.h +++ b/libraries/entities/src/EntityItemPropertiesMacros.h @@ -411,10 +411,28 @@ inline QRect QRect_convertFromScriptValue(const QScriptValue& v, bool& isValid) static T _static##N; #define ADD_PROPERTY_TO_MAP(P, N, n, T) \ - _propertyStringsToEnums[#n] = P; + { \ + EntityPropertyInfo propertyInfo = EntityPropertyInfo(P); \ + _propertyInfos[#n] = propertyInfo; \ + } + +#define ADD_PROPERTY_TO_MAP_WITH_RANGE(P, N, n, T, M, X) \ + { \ + EntityPropertyInfo propertyInfo = EntityPropertyInfo(P, M, X); \ + _propertyInfos[#n] = propertyInfo; \ + } #define ADD_GROUP_PROPERTY_TO_MAP(P, G, g, N, n) \ - _propertyStringsToEnums[#g "." #n] = P; + { \ + EntityPropertyInfo propertyInfo = EntityPropertyInfo(P); \ + _propertyInfos[#g "." #n] = propertyInfo; \ + } + +#define ADD_GROUP_PROPERTY_TO_MAP_WITH_RANGE(P, G, g, N, n, M, X) \ + { \ + EntityPropertyInfo propertyInfo = EntityPropertyInfo(P, M, X); \ + _propertyInfos[#g "." #n] = propertyInfo; \ + } #define DEFINE_CORE(N, n, T, V) \ public: \ diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 303e6d54c4..f9f1cb0a06 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -1089,6 +1089,9 @@ QUuid EntityScriptingInterface::findClosestEntity(const glm::vec3& center, float _entityTree->withReadLock([&] { result = _entityTree->evalClosestEntity(center, radius, PickFilter(searchFilter)); }); + if (closestEntity) { + result = closestEntity->getEntityItemID(); + } } return result; } @@ -1111,6 +1114,10 @@ QVector EntityScriptingInterface::findEntities(const glm::vec3& center, f _entityTree->withReadLock([&] { _entityTree->evalEntitiesInSphere(center, radius, PickFilter(searchFilter), result); }); + + foreach (EntityItemPointer entity, entities) { + result << entity->getEntityItemID(); + } } return result; } @@ -1125,6 +1132,10 @@ QVector EntityScriptingInterface::findEntitiesInBox(const glm::vec3& corn AABox box(corner, dimensions); _entityTree->evalEntitiesInBox(box, PickFilter(searchFilter), result); }); + + foreach (EntityItemPointer entity, entities) { + result << entity->getEntityItemID(); + } } return result; } @@ -1163,6 +1174,10 @@ QVector EntityScriptingInterface::findEntitiesInFrustum(QVariantMap frust _entityTree->withReadLock([&] { _entityTree->evalEntitiesInFrustum(viewFrustum, PickFilter(searchFilter), result); }); + + foreach(EntityItemPointer entity, entities) { + result << entity->getEntityItemID(); + } } } @@ -1178,6 +1193,12 @@ QVector EntityScriptingInterface::findEntitiesByType(const QString entity _entityTree->withReadLock([&] { _entityTree->evalEntitiesInSphereWithType(center, radius, type, PickFilter(searchFilter), result); }); + + foreach(EntityItemPointer entity, entities) { + if (entity->getType() == type) { + result << entity->getEntityItemID().toString(); + } + } } return result; } @@ -1189,6 +1210,24 @@ QVector EntityScriptingInterface::findEntitiesByName(const QString entity unsigned int searchFilter = PickFilter::getBitMask(PickFilter::FlagBit::DOMAIN_ENTITIES) | PickFilter::getBitMask(PickFilter::FlagBit::AVATAR_ENTITIES); _entityTree->evalEntitiesInSphereWithName(center, radius, entityName, caseSensitiveSearch, PickFilter(searchFilter), result); }); + + if (caseSensitiveSearch) { + foreach(EntityItemPointer entity, entities) { + if (entity->getName() == entityName) { + result << entity->getEntityItemID(); + } + } + + } else { + QString entityNameLowerCase = entityName.toLower(); + + foreach(EntityItemPointer entity, entities) { + QString entityItemLowerCase = entity->getName().toLower(); + if (entityItemLowerCase == entityNameLowerCase) { + result << entity->getEntityItemID(); + } + } + } } return result; } @@ -1223,6 +1262,13 @@ RayToEntityIntersectionResult EntityScriptingInterface::evalRayIntersectionVecto return evalRayIntersectionWorker(ray, Octree::Lock, searchFilter, entityIdsToInclude, entityIdsToDiscard); } +RayToEntityIntersectionResult EntityScriptingInterface::evalRayIntersectionVector(const PickRay& ray, PickFilter searchFilter, + const QVector& entityIdsToInclude, const QVector& entityIdsToDiscard) { + PROFILE_RANGE(script_entities, __FUNCTION__); + + return evalRayIntersectionWorker(ray, Octree::Lock, searchFilter, entityIdsToInclude, entityIdsToDiscard); +} + RayToEntityIntersectionResult EntityScriptingInterface::evalRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType, PickFilter searchFilter, const QVector& entityIdsToInclude, const QVector& entityIdsToDiscard) const { @@ -2268,3 +2314,10 @@ bool EntityScriptingInterface::verifyStaticCertificateProperties(const QUuid& en } return result; } + +const EntityPropertyInfo EntityScriptingInterface::getPropertyInfo(const QScriptValue& property) const { + const QString name = property.toString(); + EntityPropertyInfo propertyInfo; + EntityItemProperties::getPropertyInfo(name, propertyInfo); + return propertyInfo; +} diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 1398c2ad1c..389b5e629b 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -513,6 +513,32 @@ public slots: const QScriptValue& entityIdsToInclude = QScriptValue(), const QScriptValue& entityIdsToDiscard = QScriptValue(), bool visibleOnly = false, bool collidableOnly = false) const; + /// Same as above but with QVectors + RayToEntityIntersectionResult findRayIntersectionVector(const PickRay& ray, bool precisionPicking, + const QVector& entityIdsToInclude, const QVector& entityIdsToDiscard, + bool visibleOnly, bool collidableOnly); + + /**jsdoc + * Find the first entity intersected by a {@link PickRay}. Light and Zone entities are not + * intersected unless they've been configured as pickable using {@link Entities.setLightsArePickable|setLightsArePickable} + * and {@link Entities.setZonesArePickable|setZonesArePickable}, respectively.
+ * This is a synonym for {@link Entities.findRayIntersection|findRayIntersection}. + * @function Entities.findRayIntersectionBlocking + * @param {PickRay} pickRay - The PickRay to use for finding entities. + * @param {boolean} [precisionPicking=false] - If true and the intersected entity is a Model + * entity, the result's extraInfo property includes more information than it otherwise would. + * @param {Uuid[]} [entitiesToInclude=[]] - If not empty then the search is restricted to these entities. + * @param {Uuid[]} [entitiesToDiscard=[]] - Entities to ignore during the search. + * @deprecated This function is deprecated and will soon be removed. Use + * {@link Entities.findRayIntersection|findRayIntersection} instead; it blocks and performs the same function. + */ + /// If the scripting context has visible entities, this will determine a ray intersection, and will block in + /// order to return an accurate result + Q_INVOKABLE RayToEntityIntersectionResult findRayIntersectionBlocking(const PickRay& ray, bool precisionPicking = false, + const QScriptValue& entityIdsToInclude = QScriptValue(), const QScriptValue& entityIdsToDiscard = QScriptValue()); + +>>>>>>> property range audit - add range info via macros accessible via API, tweak min/max/steps in entityProperties + /**jsdoc * Reloads an entity's server entity script such that the latest version re-downloaded. * @function Entities.reloadServerScripts @@ -1592,6 +1618,16 @@ public slots: */ Q_INVOKABLE bool verifyStaticCertificateProperties(const QUuid& entityID); + /**jsdoc + * Get information about entity properties including a minimum to maximum range for numerical properties + * as well as property enum value. + * @function Entities.getPropertyInfo + * @param {string} property - The property name to get the information for. + * @returns {Entities.EntityPropertyInfo} The information data including propertyEnum, minimum, and maximum + * if the property can be found, otherwise an empty object. + */ + Q_INVOKABLE const EntityPropertyInfo getPropertyInfo(const QScriptValue& property) const; + signals: /**jsdoc * Triggered on the client that is the physics simulation owner during the collision of two entities. Note: Isn't triggered diff --git a/libraries/entities/src/LightEntityItem.cpp b/libraries/entities/src/LightEntityItem.cpp index e3de5f66f8..dbb55c7329 100644 --- a/libraries/entities/src/LightEntityItem.cpp +++ b/libraries/entities/src/LightEntityItem.cpp @@ -25,6 +25,8 @@ const bool LightEntityItem::DEFAULT_IS_SPOTLIGHT = false; const float LightEntityItem::DEFAULT_INTENSITY = 1.0f; const float LightEntityItem::DEFAULT_FALLOFF_RADIUS = 0.1f; const float LightEntityItem::DEFAULT_EXPONENT = 0.0f; +const float LightEntityItem::MIN_CUTOFF = 0.0f; +const float LightEntityItem::MAX_CUTOFF = 90.0f; const float LightEntityItem::DEFAULT_CUTOFF = PI / 2.0f; bool LightEntityItem::_lightsArePickable = false; @@ -115,7 +117,7 @@ void LightEntityItem::setIsSpotlight(bool value) { } void LightEntityItem::setCutoff(float value) { - value = glm::clamp(value, 0.0f, 90.0f); + value = glm::clamp(value, MIN_CUTOFF, MAX_CUTOFF); if (value == getCutoff()) { return; } diff --git a/libraries/entities/src/LightEntityItem.h b/libraries/entities/src/LightEntityItem.h index 813333d534..26b74f02cd 100644 --- a/libraries/entities/src/LightEntityItem.h +++ b/libraries/entities/src/LightEntityItem.h @@ -20,6 +20,8 @@ public: static const float DEFAULT_INTENSITY; static const float DEFAULT_FALLOFF_RADIUS; static const float DEFAULT_EXPONENT; + static const float MIN_CUTOFF; + static const float MAX_CUTOFF; static const float DEFAULT_CUTOFF; static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 6f98dd2864..8dad5932be 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -670,6 +670,7 @@ void ScriptEngine::init() { qScriptRegisterMetaType(this, EntityPropertyFlagsToScriptValue, EntityPropertyFlagsFromScriptValue); qScriptRegisterMetaType(this, EntityItemPropertiesToScriptValue, EntityItemPropertiesFromScriptValueHonorReadOnly); + qScriptRegisterMetaType(this, EntityPropertyInfoToScriptValue, EntityPropertyInfoFromScriptValue); qScriptRegisterMetaType(this, EntityItemIDtoScriptValue, EntityItemIDfromScriptValue); qScriptRegisterMetaType(this, RayToEntityIntersectionResultToScriptValue, RayToEntityIntersectionResultFromScriptValue); qScriptRegisterMetaType(this, RayToAvatarIntersectionResultToScriptValue, RayToAvatarIntersectionResultFromScriptValue); diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 36f9af0ea7..3ff91dbda3 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -453,7 +453,7 @@ const DEFAULT_ENTITY_PROPERTIES = { spinSpread: 0, rotateWithEntity: false, polarStart: 0, - polarFinish: 0, + polarFinish: Math.PI, azimuthStart: -Math.PI, azimuthFinish: Math.PI }, @@ -2479,6 +2479,15 @@ var PropertiesTool = function (opts) { tooltips: Script.require('./assets/data/createAppTooltips.json'), hmdActive: HMD.active, }); + } else if (data.type === "propertyRangeRequest") { + var propertyRanges = {}; + data.properties.forEach(function (property) { + propertyRanges[property] = Entities.getPropertyInfo(property); + }); + emitScriptEvent({ + type: 'propertyRangeReply', + propertyRanges: propertyRanges, + }); } }; diff --git a/scripts/system/html/js/draggableNumber.js b/scripts/system/html/js/draggableNumber.js index 4e3a32b0f2..b1039ed37b 100644 --- a/scripts/system/html/js/draggableNumber.js +++ b/scripts/system/html/js/draggableNumber.js @@ -139,7 +139,14 @@ DraggableNumber.prototype = { }, inputChange: function() { - this.setValue(this.elInput.value); + let value = this.elInput.value; + if (this.max !== undefined) { + value = Math.min(this.max, value); + } + if (this.min !== undefined) { + value = Math.max(this.min, value); + } + this.setValue(value); }, inputBlur: function(ev) { @@ -156,6 +163,17 @@ DraggableNumber.prototype = { return this.elText.getAttribute("disabled") === "disabled"; }, + updateMinMax: function(min, max) { + this.min = min; + this.max = max; + if (this.min !== undefined) { + this.elInput.setAttribute("min", this.min); + } + if (this.max !== undefined) { + this.elInput.setAttribute("max", this.max); + } + }, + initialize: function() { this.onMouseDown = this.mouseDown.bind(this); this.onMouseUp = this.mouseUp.bind(this); @@ -189,12 +207,7 @@ DraggableNumber.prototype = { this.elInput = document.createElement('input'); this.elInput.className = "input"; this.elInput.setAttribute("type", "number"); - if (this.min !== undefined) { - this.elInput.setAttribute("min", this.min); - } - if (this.max !== undefined) { - this.elInput.setAttribute("max", this.max); - } + this.updateMinMax(this.min, this.max); if (this.step !== undefined) { this.elInput.setAttribute("step", this.step); } diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index 78ef8ac313..16b83285b9 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -75,7 +75,7 @@ const GROUPS = [ }, { label: "Parent Joint Index", - type: "number-draggable", + type: "number", propertyID: "parentJointIndex", }, { @@ -137,7 +137,7 @@ const GROUPS = [ label: "Line Height", type: "number-draggable", min: 0, - step: 0.005, + step: 0.001, decimals: 4, unit: "m", propertyID: "lineHeight" @@ -185,8 +185,8 @@ const GROUPS = [ label: "Light Intensity", type: "number-draggable", min: 0, - max: 10, - step: 0.1, + max: 40, + step: 0.01, decimals: 2, propertyID: "keyLight.intensity", showPropertyRule: { "keyLightMode": "enabled" }, @@ -194,6 +194,7 @@ const GROUPS = [ { label: "Light Horizontal Angle", type: "number-draggable", + step: 0.1, multiplier: DEGREES_TO_RADIANS, decimals: 2, unit: "deg", @@ -203,6 +204,7 @@ const GROUPS = [ { label: "Light Vertical Angle", type: "number-draggable", + step: 0.1, multiplier: DEGREES_TO_RADIANS, decimals: 2, unit: "deg", @@ -243,7 +245,7 @@ const GROUPS = [ label: "Ambient Intensity", type: "number-draggable", min: 0, - max: 10, + max: 200, step: 0.1, decimals: 2, propertyID: "ambientLight.ambientIntensity", @@ -271,9 +273,9 @@ const GROUPS = [ { label: "Range", type: "number-draggable", - min: 5, + min: 1, max: 10000, - step: 5, + step: 1, decimals: 0, unit: "m", propertyID: "haze.hazeRange", @@ -290,7 +292,7 @@ const GROUPS = [ type: "number-draggable", min: -1000, max: 1000, - step: 10, + step: 1, decimals: 0, unit: "m", propertyID: "haze.hazeBaseRef", @@ -301,7 +303,7 @@ const GROUPS = [ type: "number-draggable", min: -1000, max: 5000, - step: 10, + step: 1, decimals: 0, unit: "m", propertyID: "haze.hazeCeiling", @@ -318,8 +320,8 @@ const GROUPS = [ type: "number-draggable", min: 0, max: 1, - step: 0.01, - decimals: 2, + step: 0.001, + decimals: 3, propertyID: "haze.hazeBackgroundBlend", showPropertyRule: { "hazeMode": "enabled" }, }, @@ -356,8 +358,8 @@ const GROUPS = [ type: "number-draggable", min: 0, max: 1, - step: 0.01, - decimals: 2, + step: 0.001, + decimals: 3, propertyID: "bloom.bloomIntensity", showPropertyRule: { "bloomMode": "enabled" }, }, @@ -366,8 +368,8 @@ const GROUPS = [ type: "number-draggable", min: 0, max: 1, - step: 0.01, - decimals: 2, + step: 0.001, + decimals: 3, propertyID: "bloom.bloomThreshold", showPropertyRule: { "bloomMode": "enabled" }, }, @@ -376,8 +378,8 @@ const GROUPS = [ type: "number-draggable", min: 0, max: 2, - step: 0.01, - decimals: 2, + step: 0.001, + decimals: 3, propertyID: "bloom.bloomSize", showPropertyRule: { "bloomMode": "enabled" }, }, @@ -510,16 +512,18 @@ const GROUPS = [ label: "Intensity", type: "number-draggable", min: 0, + max: 10000, step: 0.1, - decimals: 1, + decimals: 2, propertyID: "intensity", }, { label: "Fall-Off Radius", type: "number-draggable", min: 0, + max: 10000, step: 0.1, - decimals: 1, + decimals: 2, unit: "m", propertyID: "falloffRadius", }, @@ -531,6 +535,7 @@ const GROUPS = [ { label: "Spotlight Exponent", type: "number-draggable", + min: 0, step: 0.01, decimals: 2, propertyID: "exponent", @@ -643,8 +648,6 @@ const GROUPS = [ label: "Lifespan", type: "number-draggable", unit: "s", - min: 0.01, - max: 10, step: 0.01, decimals: 2, propertyID: "lifespan", @@ -652,8 +655,6 @@ const GROUPS = [ { label: "Max Particles", type: "number-draggable", - min: 1, - max: 10000, step: 1, propertyID: "maxParticles", }, @@ -673,26 +674,20 @@ const GROUPS = [ { label: "Emit Rate", type: "number-draggable", - min: 1, - max: 1000, step: 1, propertyID: "emitRate", }, { label: "Emit Speed", type: "number-draggable", - min: 0, - max: 5, - step: 0.01, + step: 0.1, decimals: 2, propertyID: "emitSpeed", }, { label: "Speed Spread", type: "number-draggable", - min: 0, - max: 5, - step: 0.01, + step: 0.1, decimals: 2, propertyID: "speedSpread", }, @@ -700,7 +695,6 @@ const GROUPS = [ label: "Emit Dimensions", type: "vec3", vec3Type: "xyz", - min: 0, step: 0.01, round: 100, subLabels: [ "x", "y", "z" ], @@ -709,10 +703,8 @@ const GROUPS = [ { label: "Emit Radius Start", type: "number-draggable", - min: 0, - max: 1, - step: 0.01, - decimals: 2, + step: 0.001, + decimals: 3, propertyID: "emitRadiusStart" }, { @@ -745,8 +737,6 @@ const GROUPS = [ { label: "Start", type: "number-draggable", - min: 0, - max: 4, step: 0.01, decimals: 2, propertyID: "radiusStart", @@ -755,8 +745,6 @@ const GROUPS = [ { label: "Middle", type: "number-draggable", - min: 0, - max: 4, step: 0.01, decimals: 2, propertyID: "particleRadius", @@ -764,8 +752,6 @@ const GROUPS = [ { label: "Finish", type: "number-draggable", - min: 0, - max: 4, step: 0.01, decimals: 2, propertyID: "radiusFinish", @@ -776,8 +762,6 @@ const GROUPS = [ { label: "Size Spread", type: "number-draggable", - min: 0, - max: 4, step: 0.01, decimals: 2, propertyID: "radiusSpread", @@ -834,29 +818,23 @@ const GROUPS = [ { label: "Start", type: "number-draggable", - min: 0, - max: 1, - step: 0.01, - decimals: 2, + step: 0.001, + decimals: 3, propertyID: "alphaStart", fallbackProperty: "alpha", }, { label: "Middle", type: "number-draggable", - min: 0, - max: 1, - step: 0.01, - decimals: 2, + step: 0.001, + decimals: 3, propertyID: "alpha", }, { label: "Finish", type: "number-draggable", - min: 0, - max: 1, - step: 0.01, - decimals: 2, + step: 0.001, + decimals: 3, propertyID: "alphaFinish", fallbackProperty: "alpha", }, @@ -865,10 +843,8 @@ const GROUPS = [ { label: "Alpha Spread", type: "number-draggable", - min: 0, - max: 1, - step: 0.01, - decimals: 2, + step: 0.001, + decimals: 3, propertyID: "alphaSpread", }, ] @@ -911,10 +887,8 @@ const GROUPS = [ { label: "Start", type: "number-draggable", - min: -360, - max: 360, - step: 1, - decimals: 0, + step: 0.1, + decimals: 2, multiplier: DEGREES_TO_RADIANS, unit: "deg", propertyID: "spinStart", @@ -923,10 +897,8 @@ const GROUPS = [ { label: "Middle", type: "number-draggable", - min: -360, - max: 360, - step: 1, - decimals: 0, + step: 0.1, + decimals: 2, multiplier: DEGREES_TO_RADIANS, unit: "deg", propertyID: "particleSpin", @@ -934,10 +906,8 @@ const GROUPS = [ { label: "Finish", type: "number-draggable", - min: -360, - max: 360, - step: 1, - decimals: 0, + step: 0.1, + decimals: 2, multiplier: DEGREES_TO_RADIANS, unit: "deg", propertyID: "spinFinish", @@ -948,10 +918,8 @@ const GROUPS = [ { label: "Spin Spread", type: "number-draggable", - min: 0, - max: 360, - step: 1, - decimals: 0, + step: 0.1, + decimals: 2, multiplier: DEGREES_TO_RADIANS, unit: "deg", propertyID: "spinSpread", @@ -976,10 +944,8 @@ const GROUPS = [ { label: "Start", type: "number-draggable", - min: 0, - max: 180, - step: 1, - decimals: 0, + step: 0.1, + decimals: 2, multiplier: DEGREES_TO_RADIANS, unit: "deg", propertyID: "polarStart", @@ -987,10 +953,8 @@ const GROUPS = [ { label: "Finish", type: "number-draggable", - min: 0, - max: 180, - step: 1, - decimals: 0, + step: 0.1, + decimals: 2, multiplier: DEGREES_TO_RADIANS, unit: "deg", propertyID: "polarFinish", @@ -1005,10 +969,8 @@ const GROUPS = [ { label: "Start", type: "number-draggable", - min: -180, - max: 180, - step: 1, - decimals: 0, + step: 0.1, + decimals: 2, multiplier: DEGREES_TO_RADIANS, unit: "deg", propertyID: "azimuthStart", @@ -1016,10 +978,8 @@ const GROUPS = [ { label: "Finish", type: "number-draggable", - min: -180, - max: 180, - step: 1, - decimals: 0, + step: 0.1, + decimals: 2, multiplier: DEGREES_TO_RADIANS, unit: "deg", propertyID: "azimuthFinish", @@ -1036,6 +996,7 @@ const GROUPS = [ label: "Position", type: "vec3", vec3Type: "xyz", + step: 0.1, decimals: 4, subLabels: [ "x", "y", "z" ], unit: "m", @@ -1046,6 +1007,7 @@ const GROUPS = [ label: "Local Position", type: "vec3", vec3Type: "xyz", + step: 0.1, decimals: 4, subLabels: [ "x", "y", "z" ], unit: "m", @@ -1078,8 +1040,7 @@ const GROUPS = [ label: "Dimensions", type: "vec3", vec3Type: "xyz", - min: 0, - step: 0.1, + step: 0.01, decimals: 4, subLabels: [ "x", "y", "z" ], unit: "m", @@ -1090,8 +1051,7 @@ const GROUPS = [ label: "Local Dimensions", type: "vec3", vec3Type: "xyz", - min: 0, - step: 0.1, + step: 0.01, decimals: 4, subLabels: [ "x", "y", "z" ], unit: "m", @@ -1111,7 +1071,7 @@ const GROUPS = [ label: "Pivot", type: "vec3", vec3Type: "xyz", - step: 0.1, + step: 0.001, decimals: 4, subLabels: [ "x", "y", "z" ], unit: "(ratio of dimension)", @@ -1143,6 +1103,7 @@ const GROUPS = [ { label: "Clone Lifetime", type: "number-draggable", + min: -1, unit: "s", propertyID: "cloneLifetime", showPropertyRule: { "cloneable": "true" }, @@ -1150,6 +1111,7 @@ const GROUPS = [ { label: "Clone Limit", type: "number-draggable", + min: 0, propertyID: "cloneLimit", showPropertyRule: { "cloneable": "true" }, }, @@ -1296,7 +1258,7 @@ const GROUPS = [ label: "Linear Velocity", type: "vec3", vec3Type: "xyz", - step: 0.1, + step: 0.01, decimals: 4, subLabels: [ "x", "y", "z" ], unit: "m/s", @@ -1307,8 +1269,8 @@ const GROUPS = [ type: "number-draggable", min: 0, max: 1, - step: 0.01, - decimals: 2, + step: 0.001, + decimals: 4, propertyID: "damping", }, { @@ -1326,33 +1288,27 @@ const GROUPS = [ type: "number-draggable", min: 0, max: 1, - step: 0.01, + step: 0.001, decimals: 4, propertyID: "angularDamping", }, { label: "Bounciness", type: "number-draggable", - min: 0, - max: 1, - step: 0.01, + step: 0.001, decimals: 4, propertyID: "restitution", }, { label: "Friction", type: "number-draggable", - min: 0, - max: 10, - step: 0.1, + step: 0.01, decimals: 4, propertyID: "friction", }, { label: "Density", type: "number-draggable", - min: 100, - max: 10000, step: 1, decimals: 4, propertyID: "density", @@ -1372,6 +1328,7 @@ const GROUPS = [ type: "vec3", vec3Type: "xyz", subLabels: [ "x", "y", "z" ], + step: 0.1, decimals: 4, unit: "m/s2", propertyID: "acceleration", @@ -1446,6 +1403,7 @@ const JSON_EDITOR_ROW_DIV_INDEX = 2; let elGroups = {}; let properties = {}; +let propertyRangeRequests = []; let colorPickers = {}; let particlePropertyUpdates = {}; let selectedEntityProperties; @@ -1922,6 +1880,17 @@ function createNumberProperty(property, elProperty) { return elInput; } +function updateNumberMinMax(property) { + let propertyData = property.data; + let elInput = property.elInput; + if (propertyData.min !== undefined) { + elInput.setAttribute("min", propertyData.min); + } + if (propertyData.max !== undefined) { + elInput.setAttribute("max", propertyData.max); + } +} + function createNumberDraggableProperty(property, elProperty) { let elementID = property.elementID; let propertyData = property.data; @@ -1951,6 +1920,11 @@ function createNumberDraggableProperty(property, elProperty) { return elDraggableNumber; } +function updateNumberDraggableMinMax(property) { + let propertyData = property.data; + property.elNumber.updateMinMax(propertyData.min, propertyData.max); +} + function createVec3Property(property, elProperty) { let propertyData = property.data; @@ -2000,6 +1974,15 @@ function createVec2Property(property, elProperty) { return elResult; } +function updateVectorMinMax(property) { + let propertyData = property.data; + property.elNumberX.updateMinMax(propertyData.min, propertyData.max); + property.elNumberY.updateMinMax(propertyData.min, propertyData.max); + if (property.elNumberZ) { + property.elNumberZ.updateMinMax(propertyData.min, propertyData.max); + } +} + function createColorProperty(property, elProperty) { let propertyName = property.name; let elementID = property.elementID; @@ -2046,7 +2029,6 @@ function createColorProperty(property, elProperty) { color: '000000', submit: false, // We don't want to have a submission button onShow: function(colpick) { - console.log("Showing"); $(colorPickerID).attr('active', 'true'); // The original color preview within the picker needs to be updated on show because // prior to the picker being shown we don't have access to the selections' starting color. @@ -2986,6 +2968,9 @@ function loaded() { if (property.type !== 'placeholder') { properties[propertyID] = property; } + if (innerPropertyData.type === 'number' || innerPropertyData.type === 'number-draggable') { + propertyRangeRequests.push(propertyID); + } } } else { let property = createProperty(propertyData, propertyElementID, propertyName, propertyID, elProperty); @@ -2995,6 +2980,10 @@ function loaded() { if (property.type !== 'placeholder') { properties[propertyID] = property; + } + if (propertyData.type === 'number' || propertyData.type === 'number-draggable' || + propertyData.type === 'vec2' || propertyData.type === 'vec3') { + propertyRangeRequests.push(propertyID); } let showPropertyRule = propertyData.showPropertyRule; @@ -3346,11 +3335,40 @@ function loaded() { } else if (data.type === 'setSpaceMode') { currentSpaceMode = data.spaceMode === "local" ? PROPERTY_SPACE_MODE.LOCAL : PROPERTY_SPACE_MODE.WORLD; updateVisibleSpaceModeProperties(); + } else if (data.type === 'propertyRangeReply') { + let propertyRanges = data.propertyRanges; + for (let property in propertyRanges) { + let propertyRange = propertyRanges[property]; + if (propertyRange !== undefined) { + let propertyData = properties[property].data; + let multiplier = propertyData.multiplier; + if (propertyData.min === undefined && propertyRange.minimum != "") { + propertyData.min = propertyRange.minimum; + if (multiplier !== undefined) { + propertyData.min /= multiplier; + } + } + if (propertyData.max === undefined && propertyRange.maximum != "") { + propertyData.max = propertyRange.maximum; + if (multiplier !== undefined) { + propertyData.max /= multiplier; + } + } + if (propertyData.type === 'number') { + updateNumberMinMax(properties[property]); + } else if (propertyData.type === 'number-draggable') { + updateNumberDraggableMinMax(properties[property]); + } else if (propertyData.type === 'vec2' || propertyData.type === 'vec3') { + updateVectorMinMax(properties[property]); + } + } + } } }); - // Request tooltips as soon as we can process a reply: + // Request tooltips and property ranges as soon as we can process a reply: EventBridge.emitWebEvent(JSON.stringify({ type: 'tooltipsRequest' })); + EventBridge.emitWebEvent(JSON.stringify({ type: 'propertyRangeRequest', properties: propertyRangeRequests })); } // Server Script Status diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 164899ef86..83cd010337 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -599,12 +599,10 @@ SelectionDisplay = (function() { const STRETCH_CUBE_OFFSET = 0.06; const STRETCH_CUBE_CAMERA_DISTANCE_MULTIPLE = 0.02; - const STRETCH_MINIMUM_DIMENSION = 0.001; const STRETCH_PANEL_WIDTH = 0.01; const SCALE_OVERLAY_CAMERA_DISTANCE_MULTIPLE = 0.02; const SCALE_DIMENSIONS_CAMERA_DISTANCE_MULTIPLE = 0.5; - const SCALE_MINIMUM_DIMENSION = 0.01; const BOUNDING_EDGE_OFFSET = 0.5; @@ -1543,7 +1541,7 @@ SelectionDisplay = (function() { print(" SpaceMode: " + spaceMode); print(" DisplayMode: " + getMode()); } - + if (SelectionManager.selections.length === 0) { that.setOverlaysVisible(false); that.clearDebugPickPlane(); @@ -1574,7 +1572,7 @@ SelectionDisplay = (function() { dimensions: dimensions }; var isCameraInsideBox = isPointInsideBox(Camera.position, selectionBoxGeometry); - + // in HMD if outside the bounding box clamp the overlays to the bounding box for now so lasers can hit them var maxHandleDimension = 0; if (HMD.active && !isCameraInsideBox) { @@ -2515,7 +2513,7 @@ SelectionDisplay = (function() { var newDimensions = Vec3.sum(initialDimensions, changeInDimensions); - var minimumDimension = STRETCH_MINIMUM_DIMENSION; + var minimumDimension = Entities.getPropertyInfo("dimensions").minimum; if (newDimensions.x < minimumDimension) { newDimensions.x = minimumDimension; changeInDimensions.x = minimumDimension - initialDimensions.x; @@ -2634,7 +2632,7 @@ SelectionDisplay = (function() { newDimensions.y = Math.abs(newDimensions.y); newDimensions.z = Math.abs(newDimensions.z); - var minimumDimension = SCALE_MINIMUM_DIMENSION; + var minimumDimension = Entities.getPropertyInfo("dimensions").minimum; if (newDimensions.x < minimumDimension) { newDimensions.x = minimumDimension; changeInDimensions.x = minimumDimension - initialDimensions.x;