diff --git a/interface/src/avatar/AvatarActionFarGrab.h b/interface/src/avatar/AvatarActionFarGrab.h index bcaf7f2f3c..97d4a6bb03 100644 --- a/interface/src/avatar/AvatarActionFarGrab.h +++ b/interface/src/avatar/AvatarActionFarGrab.h @@ -15,6 +15,24 @@ #include #include +/**jsdoc + * The "far-grab" {@link Entities.ActionType|ActionType} moves and rotates an entity to a target position and + * orientation, optionally relative to another entity. Collisions between the entity and the user's avatar are disabled during + * the far-grab. + * It has arguments in addition to the common {@link Entities.ActionArguments|ActionArguments}. + * + * @typedef {object} Entities.ActionArguments-FarGrab + * @property {Vec3} targetPosition=0,0,0 - The target position. + * @property {Quat} targetRotation=0,0,0,1 - The target rotation. + * @property {Uuid} otherID=null - If an entity ID, the targetPosition and targetRotation are + * relative to this entity's position and rotation. + * @property {number} linearTimeScale=3.4e+38 - Controls how long it takes for the entity's position to catch up with the + * target position. The value is the time for the action to catch up to 1/e = 0.368 of the target value, where the action + * is applied using an exponential decay. + * @property {number} angularTimeScale=3.4e+38 - Controls how long it takes for the entity's orientation to catch up with the + * target orientation. The value is the time for the action to catch up to 1/e = 0.368 of the target value, where the + * action is applied using an exponential decay. + */ class AvatarActionFarGrab : public ObjectActionTractor { public: AvatarActionFarGrab(const QUuid& id, EntityItemPointer ownerEntity); diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index d4fe8574ca..9d568e6d73 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -416,6 +416,26 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { return true; } +/**jsdoc + * The "hold" {@link Entities.ActionType|ActionType} positions and rotates an entity relative to an avatar's hand. + * Collisions between the entity and the user's avatar are disabled during the hold. + * It has arguments in addition to the common {@link Entities.ActionArguments|ActionArguments}. + * + * @typedef {object} Entities.ActionArguments-Hold + * @property {Uuid} holderID=MyAvatar.sessionUUID - The ID of the avatar holding the entity. + * @property {Vec3} relativePosition=0,0,0 - The target position relative to the avatar's hand. + * @property {Vec3} relativeRotation=0,0,0,1 - The target rotation relative to the avatar's hand. + * @property {number} timeScale=3.4e+38 - Controls how long it takes for the entity's position and rotation to catch up with + * the target. The value is the time for the action to catch up to 1/e = 0.368 of the target value, where the action is + * applied using an exponential decay. + * @property {string} hand=right - The hand holding the entity: "left" or "right". + * @property {boolean} kinematic=false - If true, the entity is made kinematic during the action; the entity won't + * lag behind the hand but constraint actions such as "hinge" won't act properly. + * @property {boolean} kinematicSetVelocity=false - If true and kinematic is true, the + * entity's velocity property will be set during the action, e.g., so that other scripts may use the value. + * @property {boolean} ignoreIK=false - If true, the entity follows the HMD controller rather than the avatar's + * hand. + */ QVariantMap AvatarActionHold::getArguments() { QVariantMap arguments = ObjectDynamic::getArguments(); withReadLock([&]{ diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 3efe94c206..c3d87642f1 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -44,6 +44,8 @@ void OverlayPropertyResultFromScriptValue(const QScriptValue& object, OverlayPro const OverlayID UNKNOWN_OVERLAY_ID = OverlayID(); /**jsdoc + * The result of a {@link PickRay} search using {@link Overlays.findRayIntersection|findRayIntersection} or + * {@link Overlays.findRayIntersectionVector|findRayIntersectionVector}. * @typedef {object} Overlays.RayToOverlayIntersectionResult * @property {boolean} intersects - true if the {@link PickRay} intersected with a 3D overlay, otherwise * false. @@ -75,7 +77,8 @@ void RayToOverlayIntersectionResultFromScriptValue(const QScriptValue& object, R * yourself and that aren't persisted to the domain. They are used for UI. * @namespace Overlays * @property {Uuid} keyboardFocusOverlay - Get or set the {@link Overlays.OverlayType|web3d} overlay that has keyboard focus. - * If no overlay is set, get returns null; set to null to clear keyboard focus. + * If no overlay has keyboard focus, get returns null; set to null or {@link Uuid|Uuid.NULL} to + * clear keyboard focus. */ class Overlays : public QObject { @@ -116,7 +119,7 @@ public slots: * @function Overlays.addOverlay * @param {Overlays.OverlayType} type - The type of the overlay to add. * @param {Overlays.OverlayProperties} properties - The properties of the overlay to add. - * @returns {Uuid} The ID of the newly created overlay. + * @returns {Uuid} The ID of the newly created overlay if successful, otherwise {@link Uuid|Uuid.NULL}. * @example Add a cube overlay in front of your avatar. * var overlay = Overlays.addOverlay("cube", { * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -3 })), @@ -131,7 +134,7 @@ public slots: * Create a clone of an existing overlay. * @function Overlays.cloneOverlay * @param {Uuid} overlayID - The ID of the overlay to clone. - * @returns {Uuid} The ID of the new overlay. + * @returns {Uuid} The ID of the new overlay if successful, otherwise {@link Uuid|Uuid.NULL}. * @example Add an overlay in front of your avatar, clone it, and move the clone to be above the * original. * var position = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -3 })); @@ -322,10 +325,8 @@ public slots: * @function Overlays.findRayIntersection * @param {PickRay} pickRay - The PickRay to use for finding overlays. * @param {boolean} [precisionPicking=false] - Unused; exists to match Entity API. - * @param {Array.} [overlayIDsToInclude=[]] - Whitelist for intersection test. If empty then the result isn't limited - * to overlays in the list. - * @param {Array.} [overlayIDsToExclude=[]] - Blacklist for intersection test. If empty then the result doesn't - * exclude overlays in the list. + * @param {Array.} [overlayIDsToInclude=[]] - If not empty then the search is restricted to these overlays. + * @param {Array.} [overlayIDsToExclude=[]] - Overlays to ignore during the search. * @param {boolean} [visibleOnly=false] - Unused; exists to match Entity API. * @param {boolean} [collidableOnly=false] - Unused; exists to match Entity API. * @returns {Overlays.RayToOverlayIntersectionResult} The closest 3D overlay intersected by pickRay, taking @@ -531,7 +532,7 @@ public slots: * Set the Web3D overlay that has keyboard focus. * @function Overlays.setKeyboardFocusOverlay * @param {Uuid} overlayID - The ID of the {@link Overlays.OverlayType|web3d} overlay to set keyboard focus to. Use - * {@link Uuid|Uuid.NULL} or null to unset keyboard focus from an overlay. + * null or {@link Uuid|Uuid.NULL} to unset keyboard focus from an overlay. */ void setKeyboardFocusOverlay(const OverlayID& id); diff --git a/interface/src/ui/overlays/Shape3DOverlay.cpp b/interface/src/ui/overlays/Shape3DOverlay.cpp index e9ec0d6cf4..c27faf6f0f 100644 --- a/interface/src/ui/overlays/Shape3DOverlay.cpp +++ b/interface/src/ui/overlays/Shape3DOverlay.cpp @@ -67,6 +67,32 @@ Shape3DOverlay* Shape3DOverlay::createClone() const { } +/**jsdoc + *

A shape {@link Overlays.OverlayType|OverlayType} may display as one of the following geometrical shapes:

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
ValueDimensionsDescription
"Circle"2DA circle oriented in 3D.
"Cone"3D
"Cube"3D
"Cylinder"3D
"Dodecahedron"3D
"Hexagon"3DA hexagonal prism.
"Icosahedron"3D
"Line"1DA line oriented in 3D.
"Octagon"3DAn octagonal prism.
"Octahedron"3D
"Quad"2DA square oriented in 3D.
"Sphere"3D
"Tetrahedron"3D
"Torus"3DNot implemented.
"Triangle"3DA triangular prism.
+ * @typedef {string} Overlays.Shape + */ static const std::array shapeStrings { { "Line", "Triangle", @@ -80,7 +106,7 @@ static const std::array shapeStrings "Octahedron", "Dodecahedron", "Icosahedron", - "Torus", + "Torus", // Not implemented yet. "Cone", "Cylinder" } }; @@ -145,7 +171,7 @@ void Shape3DOverlay::setProperties(const QVariantMap& properties) { * * @property {Vec3} dimensions - The dimensions of the overlay. Synonyms: scale, size. * - * @property {Shape} shape=Hexagon - The geometrical shape of the overlay. + * @property {Overlays.Shape} shape=Hexagon - The geometrical shape of the overlay. */ QVariant Shape3DOverlay::getProperty(const QString& property) { if (property == "shape") { diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 322c91e3d3..5a3caa55fe 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -433,7 +433,7 @@ void ZoneEntityRenderer::setAmbientURL(const QString& ambientUrl) { _ambientTexture = textureCache->getTexture(_ambientTextureURL, image::TextureUsage::CUBE_TEXTURE); // keep whatever is assigned on the ambient map/sphere until texture is loaded -} + } } void ZoneEntityRenderer::updateAmbientMap() { diff --git a/libraries/entities/src/AmbientLightPropertyGroup.h b/libraries/entities/src/AmbientLightPropertyGroup.h index fbbc7c9900..591ea6a6fa 100644 --- a/libraries/entities/src/AmbientLightPropertyGroup.h +++ b/libraries/entities/src/AmbientLightPropertyGroup.h @@ -27,6 +27,14 @@ class OctreePacketData; class EntityTreeElementExtraEncodeData; class ReadBitstreamToTreeParams; +/**jsdoc + * Ambient light is defined by the following properties. + * @typedef {object} Entities.AmbientLight + * @property {number} ambientIntensity=0.5 - The intensity of the light. + * @property {string} ambientURL="" - A cube map image that defines the color of the light coming from each direction. If + * "" then the entity's {@link Entities.Skybox|Skybox} url property value is used, unless that also is "" in which + * case the entity's ambientLightMode property is set to "inherit". + */ class AmbientLightPropertyGroup : public PropertyGroup { public: // EntityItemProperty related helpers diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index 2af56fb6b2..82af60ed1a 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -44,6 +44,19 @@ bool operator!=(const AnimationPropertyGroup& a, const AnimationPropertyGroup& b } +/**jsdoc + * The AnimationProperties are used to configure an animation. + * @typedef Entities.AnimationProperties + * @property {string} url="" - The URL of the FBX file that has the animation. + * @property {number} fps=30 - The speed in frames/s that the animation is played at. + * @property {number} firstFrame=0 - The first frame to play in the animation. + * @property {number} lastFrame=100000 - The last frame to play in the animation. + * @property {number} currentFrame=0 - The current frame being played in the animation. + * @property {boolean} running=false - If true then the animation should play. + * @property {boolean} loop=true - If true then the animation should be continuously repeated in a loop. + * @property {boolean} hold=false - If true then the rotations and translations of the last frame played should be + * maintained when the animation stops playing. + */ void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const { COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_URL, Animation, animation, URL, url); COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_ALLOW_TRANSLATION, Animation, animation, AllowTranslation, allowTranslation); diff --git a/libraries/entities/src/EntityDynamicInterface.cpp b/libraries/entities/src/EntityDynamicInterface.cpp index f424c02e6e..d43bdd7b51 100644 --- a/libraries/entities/src/EntityDynamicInterface.cpp +++ b/libraries/entities/src/EntityDynamicInterface.cpp @@ -94,6 +94,49 @@ variables. These argument variables are used by the code which is run when bull #include "EntityDynamicInterface.h" +/**jsdoc +*

An entity action may be one of the following types:

+* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +* +*
ValueTypeDescriptionArguments
"far-grab"Avatar actionMoves and rotates an entity to a target position and orientation, optionally relative to another entity. Collisions +* between the entity and the user's avatar are disabled during the far-grab.{@link Entities.ActionArguments-FarGrab}
"hold"Avatar actionPositions and rotates an entity relative to an avatar's hand. Collisions between the entity and the user's avatar +* are disabled during the hold.{@link Entities.ActionArguments-Hold}
"offset"Object actionMoves an entity so that it is a set distance away from a target point.{@link Entities.ActionArguments-Offset}
"tractor"Object actionMoves and rotates an entity to a target position and orientation, optionally relative to another entity.{@link Entities.ActionArguments-Tractor}
"travel-oriented"Object actionOrients an entity to align with its direction of travel.{@link Entities.ActionArguments-TravelOriented}
"hinge"Object constraintLets an entity pivot about an axis or connects two entities with a hinge joint.{@link Entities.ActionArguments-Hinge}
"slider"Object constraintLets an entity slide and rotate along an axis, or connects two entities that slide and rotate along a shared +* axis.{@link Entities.ActionArguments-Slider|ActionArguments-Slider}
"cone-twist"Object constraintConnects two entities with a joint that can move through a cone and can twist.{@link Entities.ActionArguments-ConeTwist}
"ball-socket"Object constraintConnects two entities with a ball and socket joint.{@link Entities.ActionArguments-BallSocket}
"spring"Synonym for "tractor". Legacy value.
+* @typedef {string} Entities.ActionType +*/ +// Note: The "none" action type is not listed because it's an internal "uninitialized" value and not useful for scripts. EntityDynamicType EntityDynamicInterface::dynamicTypeFromString(QString dynamicTypeString) { QString normalizedDynamicTypeString = dynamicTypeString.toLower().remove('-').remove('_'); if (normalizedDynamicTypeString == "none") { diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 2eca612fc2..d348101b66 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -440,6 +440,707 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { return changedProperties; } +/**jsdoc + * Different entity types have different properties: some common to all entities (listed below) and some specific to each + * {@link Entities.EntityType|EntityType} (linked to below). The properties are accessed as an object of property names and + * values. + * + * @typedef {object} Entities.EntityProperties + * @property {Uuid} id - The ID of the entity. Read-only. + * @property {string} name="" - A name for the entity. Need not be unique. + * @property {Entities.EntityType} type - The entity type. You cannot change the type of an entity after it's created. (Though + * its value may switch among "Box", "Shape", and "Sphere" depending on changes to + * the shape property set for entities of these types.) Read-only. + * @property {boolean} clientOnly=false - If true then the entity is an avatar entity, otherwise it is a server + * entity. Read-only. + * @property {Uuid} owningAvatarID=Uuid.NULL - The session ID of the owning avatar if clientOnly is + * true, otherwise {@link Uuid|Uuid.NULL}. Read-only. + * + * @property {string} created - The UTC date and time that the entity was created, in ISO 8601 format as + * yyyy-MM-ddTHH:mm:ssZ. Read-only. + * @property {number} age - The age of the entity in seconds since it was created. Read-only. + * @property {string} ageAsText - The age of the entity since it was created, formatted as h hours m minutes s + * seconds. + * @property {number} lifetime=-1 - How long an entity lives for, in seconds, before being automatically deleted. A value of + * -1 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. Read-only. + * @property {Uuid} lastEditedBy - The session ID of the avatar or agent that most recently created or edited the entity. + * Read-only. + * + * @property {boolean} locked=false - Whether or not the entity can be edited or deleted. If true then the + * entity's properties other than locked cannot be changed, and the entity cannot be deleted. + * @property {boolean} visible=true - Whether or not the entity is rendered. If true then the entity is rendered. + * @property {boolean} canCastShadows=true - Whether or not the entity casts shadows. Currently applicable only to + * {@link Entities.EntityType|Model} and {@link Entities.EntityType|Shape} entities. Shadows are cast if inside a + * {@link Entities.EntityType|Zone} entity with castShadows enabled in its {@link Entities.EntityProperties-Zone|keyLight} property. + * + * @property {Vec3} position=0,0,0 - The position of the entity. + * @property {Quat} rotation=0,0,0,1 - The orientation of the entity with respect to 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, {@link Vec3|Vec3.ZERO} – {@link Vec3|Vec3.ONE}. A value of {@link Vec3|Vec3.ZERO} is the entity's + * minimum x, y, z corner; a value of {@link Vec3|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|Vec3.ZERO}. Read-only. + * @property {Vec3} naturalDimensions - The dimensions of the entity's unscaled mesh model if it has one, otherwise + * {@link Vec3|Vec3.ONE}. Read-only. + * + * @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 to slow down the linear velocity of an entity over time, 0.0 + * – 1.0. 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 1/e = 0.368 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 to slow down the angular velocity of an entity over time, + * 0.01.0. 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 1/e = 0.368 + * of its initial value. + * + * @property {Vec3} gravity=0,0,0 - The acceleration due to gravity in m/s2 that the entity should move with, in + * world coordinates. Set to { x: 0, y: -9.8, z: 0 } to simulate Earth's gravity. Gravity is applied to an + * entity's motion only if its dynamic property is true. If changing an entity's + * gravity from {@link Vec3|Vec3.ZERO}, you need to give it a small velocity in order to kick off + * physics simulation. + * The gravity value is applied in addition to the acceleration value. + * @property {Vec3} acceleration=0,0,0 - A general acceleration in m/s2 that the entity should move with, in world + * coordinates. The acceleration is applied to an entity's motion only if its dynamic property is + * true. If changing an entity's acceleration from {@link Vec3|Vec3.ZERO}, you need to give it a + * small velocity in order to kick off physics simulation. + * The acceleration value is applied in addition to the gravity value. + * @property {number} restitution=0.5 - The "bounciness" of an entity when it collides, 0.0 – + * 0.99. The higher the value, the more bouncy. + * @property {number} friction=0.5 - How much to slow down an entity when it's moving against another, 0.0 – + * 10.0. The higher the value, the more quickly it slows down. Examples: 0.1 for ice, + * 0.9 for sandpaper. + * @property {number} density=1000 - The density of the entity in kg/m3, 100 for balsa wood – + * 10000 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 - Whether or not the entity should collide with items per its + * collisionMask property. If true then the entity does not collide. + * @property {boolean} ignoreForCollisions=false - Synonym for collisionless. + * @property {Entities.CollisionMask} collisionMask=31 - What types of items the entity should collide with. + * @property {string} collidesWith="static,dynamic,kinematic,myAvatar,otherAvatar," - Synonym for collisionMask, + * in text format. + * @property {string} collisionSoundURL="" - The sound to play when the entity experiences a collision. Valid file formats are + * as per the {@link SoundCache} object. + * @property {boolean} dynamic=false - Whether or not the entity should be affected by collisions. If true then + * the entity's movement is affected by collisions. + * @property {boolean} collisionsWillMove=false - Synonym for dynamic. + * + * @property {string} href="" - A "hifi://" metaverse address that a user is taken to when they click on the entity. + * @property {string} description="" - A description of the href property value. + * + * @property {string} userData="" - Used to store extra data about the entity in JSON format. WARNING: Other apps such as the + * Create app can 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 JSON.parse() to parse the string into a JavaScript object + * which you can manipulate the properties of, and use JSON.stringify() to convert the object into a string to + * put in the property. + * + * @property {string} script="" - The URL of the client entity script, if any, that is attached to the entity. + * @property {number} scriptTimestamp=0 - Intended to be 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 Date.now(). + * If you update the property's value, the script 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 this entity is parented to. {@link Uuid|Uuid.NULL} + * if the entity is not parented. + * @property {number} parentJointIndex=65535 - The joint of the entity or avatar that this entity is parented to. Use + * 65535 or -1 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 position. If the entity is parented to an avatar and is clientOnly + * 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 rotation. + * @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 velocity. + * @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 position. + * @property {Vec3} localDimensions - The dimensions of the entity. If the entity is parented to an avatar and is + * clientOnly 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. + * Read-only. + * @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. + * The size of this property increases with the number of actions. Because this property value has to fit within a High + * Fidelity datagram packet there is a limit to the number of actions that an entity can have, and edits which would result + * in overflow are rejected. + * Read-only. + * @property {Entities.RenderInfo} renderInfo - Information on the cost of rendering the entity. Currently information is only + * provided for Model entities. Read-only. + * + * @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 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 certificateID. + * + * @see The different entity types have additional properties as follows: + * @see {@link Entities.EntityProperties-Box|EntityProperties-Box} + * @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 "Box" {@link Entities.EntityType|EntityType} is the same as the "Shape" + * {@link Entities.EntityType|EntityType} except that its shape value is always set to "Cube" + * when the entity is created. If its shape property value is subsequently changed then the entity's + * type will be reported as "Sphere" if the shape is set to "Sphere", + * otherwise it will be reported as "Shape". + * @typedef {object} Entities.EntityProperties-Box + */ + +/**jsdoc + * The "Light" {@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. Entity surface 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 - If true then the light is directional, emitting along the entity's + * local negative z-axis; otherwise 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 Create a spotlight pointing at the ground. + * 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 "Line" {@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}. + * @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 + * linePoints. + * @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 linePoints + * lie within the entity's dimensions. + * @property {number} lineWidth=2 - Currently not used. + * @property {Color} color=255,255,255 - The color of the line. + * @example Draw lines in a "V". + * 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 "Material" {@link Entities.EntityType|EntityType} modifies the existing materials on + * {@link Entities.EntityType|Model} entities, {@link Entities.EntityType|Shape} entities (albedo only), + * {@link Overlays.OverlayType|model overlays}, and avatars. + * It has properties in addition to the common {@link Entities.EntityProperties|EntityProperties}.
+ * To apply a material to an entity or overlay, set the material entity's parentID property to the entity or + * overlay's ID. + * To apply a material to an avatar, set the material entity's parentID 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 clientOnly parameter in {@link Entities.addEntity} to true. + * Material entities render as non-scalable spheres if they don't have their parent set. + * @typedef {object} Entities.EntityProperties-Material + * @property {string} materialURL="" - URL to a {@link MaterialResource}. If you append ?name to the URL, the + * material with that name in the {@link MaterialResource} will be applied to the entity.
+ * Alternatively, set the property value to "userData" to use the {@link Entities.EntityProperties|userData} + * entity property to live edit the material resource values. + * @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 + * 0. + * @property {string|number} parentMaterialName="0" - Selects the submesh or submeshes within the parent to apply the material + * to. If in the format "mat::string", all submeshes with material name "string" are replaced. + * Otherwise the property value is parsed as an unsigned integer, specifying the mesh index to modify. Invalid values are + * parsed to 0. + * @property {string} materialMappingMode="uv" - How the material is mapped to the entity. Either "uv" or + * "projected". Currently, only "uv" is supported. + * @property {Vec2} materialMappingPos=0,0 - Offset position in UV-space of the top left of the material, range + * { x: 0, y: 0 }{ x: 1, y: 1 }. + * @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. + * @example Color a sphere using a Material entity. + * 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: "userData", + * priority: 1, + * userData: JSON.stringify({ + * materials: { + * // Can only set albedo on a Shape entity. + * // Value overrides entity's "color" property. + * albedo: [1.0, 0, 0] + * } + * }), + * }); + */ + +/**jsdoc + * The "Model" {@link Entities.EntityType|EntityType} displays an FBX or OBJ model. + * 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 dimensions + * value is specified then the model is automatically sized to its + * {@link Entities.EntityProperties|naturalDimensions}. + * @property {Color} color=255,255,255 - Currently not used. + * @property {string} modelURL="" - The URL of the FBX of OBJ model. Baked FBX models' URLs end in ".baked.fbx".
+ * Note: If the name ends with "default-image-model.fbx" then the entity is considered to be an "Image" + * entity, in which case the textures property should be set per the example. + * @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 originalTextures 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 JSON.stringify() 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 JSON.parse() to + * parse the JSON string into a JavaScript object of name, URL pairs. Read-only. + * + * @property {ShapeType} shapeType="none" - The shape of the collision hull used if collisions are enabled. + * @property {string} compoundShapeURL="" - The OBJ file to use for the compound shape if shapeType is + * "compound". + * + * @property {Entities.AnimationProperties} animation - An animation to play on the model. + * + * @property {Quat[]} jointRotations=[]] - Joint rotations applied to the model; [] 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.
+ * 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 jointRotationsSet value to true. + * @property {boolean[]} jointRotationsSet=[]] - true values for joints that have had rotations applied, + * false otherwise; [] 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; [] 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.
+ * 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 jointTranslationsSet value to true. + * @property {boolean[]} jointTranslationsSet=[]] - true values for joints that have had translations applied, + * false otherwise; [] if none are applied or the model hasn't loaded. The array indexes are per + * {@link Entities.getJointIndex|getJointIndex}. + * @property {boolean} relayParentJoints=false - If true and the entity is parented to an avatar, then the + * avatar's joint rotations are applied to the entity's joints. + * + * @example Rez a Vive tracker puck. + * 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: "http://content.highfidelity.com/seefo/production/puck-attach/vive_tracker_puck.obj", + * dimensions: { x: 0.0945, y: 0.0921, z: 0.0423 }, + * lifetime: 300 // Delete after 5 minutes. + * }); + * @example Create an "Image" entity like you can in the Create app. + * var IMAGE_MODEL = "https://hifi-content.s3.amazonaws.com/DomainContent/production/default-image-model.fbx"; + * var DEFAULT_IMAGE = "https://hifi-content.s3.amazonaws.com/DomainContent/production/no-image.jpg"; + * var entity = Entities.addEntity({ + * type: "Model", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0.5, z: -3 })), + * rotation: MyAvatar.orientation, + * dimensions: { + * x: 0.5385, + * y: 0.2819, + * z: 0.0092 + * }, + * shapeType: "box", + * collisionless: true, + * modelURL: IMAGE_MODEL, + * textures: JSON.stringify({ "tex.picture": DEFAULT_IMAGE }), + * lifetime: 300 // Delete after 5 minutes + * }); + */ + +/**jsdoc + * The "ParticleEffect" {@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 - If true then particles are emitted. + * @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. If emitSpeed == 5 + * and speedSpread == 1, particles will be emitted with speeds in the range 4m/s – 6m/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. If + * emitAccelerations == {x: 0, y: -9.8, z: 0} and accelerationSpread == + * {x: 0, y: 1, z: 0}, each particle will have an acceleration in the range, {x: 0, y: -10.8, z: 0} + * – {x: 0, y: -8.8, z: 0}. + * @property {Vec3} dimensions - The dimensions of the particle effect, i.e., a bounding box containing all the particles + * during their lifetimes, assuming that emitterShouldTrail is false. Read-only. + * @property {boolean} emitterShouldTrail=false - If true then particles are "left behind" as the emitter moves, + * otherwise they stay with 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 azimuthStart and azimuthFinish + * 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 {vec3} emitDimensions=0,0,0 - The dimensions of the ellipsoid from which particles are emitted. + * @property {number} emitRadiusStart=1 - The starting radius within the ellipsoid at which particles start being emitted; + * range 0.01.0 for the ellipsoid center to the ellipsoid surface, respectively. + * Particles are emitted from the portion of the ellipsoid that lies between emitRadiusStart and the + * ellipsoid'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 ellipsoid; range 0Math.PI. Particles are emitted from the portion of the + * ellipsoid that lies between polarStart and polarFinish. + * @property {number} polarFinish=0 - The angle in radians from the entity's local z-axis at which particles stop being emitted + * within the ellipsoid; range 0Math.PI. Particles are emitted from the portion of the + * ellipsoid that lies between polarStart and polarFinish. + * @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 -Math.PIMath.PI. Particles are + * emitted from the portion of the ellipsoid that lies between azimuthStart and azimuthFinish. + * @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 -Math.PIMath.PI. Particles are + * emitted from the portion of the ellipsoid that lies between azimuthStart and azimuthFinish. + * + * @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=0.025 - The radius of each particle at the start of its life. If not explicitly set, the + * particleRadius value is used. + * @property {number} radiusFinish=0.025 - The radius of each particle at the end of its life. If not explicitly set, the + * particleRadius value is used. + * @property {number} radiusSpread=0 - Currently not used. + * @property {Color} color=255,255,255 - The color of each particle at the middle of its life. + * @property {Color} colorStart=255,255,255 - The color of each particle at the start of its life. If not explicitly set, the + * color value is used. + * @property {Color} colorFinish=255,255,255 - The color of each particle at the end of its life. If not explicitly set, the + * color value is used. + * @property {Color} colorSpread=0,0,0 - Currently not used. + * @property {number} alpha=1 - The alpha of each particle at the middle of its life. + * @property {number} alphaStart=1 - The alpha of each particle at the start of its life. If not explicitly set, the + * alpha value is used. + * @property {number} alphaFinish=1 - The alpha of each particle at the end of its life. If not explicitly set, the + * alpha value is used. + * @property {number} alphaSpread=0 - Currently not used. + * + * @property {ShapeType} shapeType="none" - Currently not used. Read-only. + * + * @example Create a ball of green smoke. + * 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 "PolyLine" {@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=1,1,1 - The dimensions of the entity, i.e., the size of the bounding box that contains the + * lines drawn. + * @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. Must be specified in order for the entity to render. + * @property {Vec3[]} normals=[]] - The normal vectors for the line's surface at the linePoints. 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 linePoints. Must be specified in + * order for the entity to render. + * @property {number} lineWidth=2 - Currently not used. + * @property {Vec3[]} strokeColors=[]] - Currently not used. + * @property {Color} color=255,255,255 - The base color of the line, which is multiplied with the color of the texture for + * rendering. + * @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 - If true, the texture is stretched to fill the whole line, otherwise + * the texture repeats along the line. + * @example Draw a textured "V". + * 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 "PolyVox" {@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 voxelSurfaceStyle and neighbor ID properties.
+ * PolyVox entities uses a library from Volumes of Fun. Their + * library documentation may be useful to read. + * @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 + * 1,1,1 to 128,128,128. The dimensions of each voxel is + * dimensions / voxelVolumesize. + * @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.
+ * 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 High Fidelity datagram packet + * there is a limit to the size and complexity of a PolyVox entity, and edits which would result in an overflow are + * rejected. + * @property {Entities.PolyVoxSurfaceStyle} voxelSurfaceStyle=2 - The style of rendering the voxels' surface and how + * neighboring PolyVox entities are joined. + * @property {string} xTextureURL="" - 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="" - 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="" - 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 - ID of the neighboring PolyVox entity in the entity's -ve local x-axis direction, + * if you want them joined. Set to {@link Uuid|Uuid.NULL} if there is none or you don't want to join them. + * @property {Uuid} yNNeighborID=Uuid.NULL - ID of the neighboring PolyVox entity in the entity's -ve local y-axis direction, + * if you want them joined. Set to {@link Uuid|Uuid.NULL} if there is none or you don't want to join them. + * @property {Uuid} zNNeighborID=Uuid.NULL - ID of the neighboring PolyVox entity in the entity's -ve local z-axis direction, + * if you want them joined. Set to {@link Uuid|Uuid.NULL} if there is none or you don't want to join them. + * @property {Uuid} xPNeighborID=Uuid.NULL - ID of the neighboring PolyVox entity in the entity's +ve local x-axis direction, + * if you want them joined. Set to {@link Uuid|Uuid.NULL} if there is none or you don't want to join them. + * @property {Uuid} yPNeighborID=Uuid.NULL - ID of the neighboring PolyVox entity in the entity's +ve local y-axis direction, + * if you want them joined. Set to {@link Uuid|Uuid.NULL} if there is none or you don't want to join them. + * @property {Uuid} zPNeighborID=Uuid.NULL - ID of the neighboring PolyVox entity in the entity's +ve local z-axis direction, + * if you want them joined. Set to {@link Uuid|Uuid.NULL} if there is none or you don't want to join them. + * @example Create a textured PolyVox sphere. + * 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 "Shape" {@link Entities.EntityType|EntityType} displays an entity of a specified shape. + * 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. + * @example Create a cylinder. + * 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 "Sphere" {@link Entities.EntityType|EntityType} is the same as the "Shape" + * {@link Entities.EntityType|EntityType} except that its shape value is always set to "Sphere" + * when the entity is created. If its shape property value is subsequently changed then the entity's + * type will be reported as "Box" if the shape is set to "Cube", + * otherwise it will be reported as "Shape". + * @typedef {object} Entities.EntityProperties-Sphere + */ + +/**jsdoc + * The "Text" {@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 \n. 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 {Color} backgroundColor=0,0,0 - The color of the background rectangle. + * @property {boolean} faceCamera=false - If true, the entity is oriented to face each user's camera (i.e., it + * differs for each user present). + * @example Create a text entity. + * 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!", + * faceCamera: true, + * lifetime: 300 // Delete after 5 minutes. + * }); + */ + +/**jsdoc + * The "Web" {@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. + * The entity 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 {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 dimensions.x and dimensions.y by that value + * you get the resolution in pixels. + * @example Create a Web entity displaying at 1920 x 1080 resolution. + * var METERS_TO_INCHES = 39.3701; + * var entity = Entities.addEntity({ + * type: "Web", + * sourceUrl: "https://highfidelity.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 "Zone" {@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 size 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 "none", or set to "compound" + * and compoundShapeURL is "". + * @property {string} compoundShapeURL="" - The OBJ file to use for the compound shape if shapeType is + * "compound". + * + * @property {string} keyLightMode="inherit" - Configures the key light in the zone. Possible values:
+ * "inherit": The key light from any enclosing zone continues into this zone.
+ * "disabled": The key light from any enclosing zone and the key light of this zone are disabled in this + * zone.
+ * "enabled": The key light properties of this zone are enabled, overriding the key light of from any + * enclosing zone. + * @property {Entities.KeyLight} keyLight - The key light properties of the zone. + * + * @property {string} ambientLightMode="inherit" - Configures the ambient light in the zone. Possible values:
+ * "inherit": The ambient light from any enclosing zone continues into this zone.
+ * "disabled": The ambient light from any enclosing zone and the ambient light of this zone are disabled in + * this zone.
+ * "enabled": The ambient light properties of this zone are enabled, overriding the ambient light from any + * enclosing zone. + * @property {Entities.AmbientLight} ambientLight - The ambient light properties of the zone. + * + * @property {string} skyboxMode="inherit" - Configures the skybox displayed in the zone. Possible values:
+ * "inherit": The skybox from any enclosing zone is dislayed in this zone.
+ * "disabled": The skybox from any enclosing zone and the skybox of this zone are disabled in this zone.
+ * "enabled": The skybox properties of this zone are enabled, overriding the skybox from any enclosing zone. + * @property {Entities.Skybox} skybox - The skybox properties of the zone. + * + * @property {string} hazeMode="inherit" - Configures the haze in the zone. Possible values:
+ * "inherit": The haze from any enclosing zone continues into this zone.
+ * "disabled": The haze from any enclosing zone and the haze of this zone are disabled in this zone.
+ * "enabled": The haze properties of this zone are enabled, overriding the haze from any enclosing zone. + * @property {Entities.Haze} haze - The haze properties of the zone. + * + * @property {boolean} flyingAllowed=true - If true then visitors can fly in the zone; otherwise they cannot. + * @property {boolean} ghostingAllowed=true - If true then visitors with avatar collisions turned off will not + * collide with content in the zone; otherwise visitors will always collide with content in the zone. + + * @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.
+ *
+ * function filter(properties) {
+ *     // Test and edit properties object values,
+ *     // e.g., properties.modelURL, as required.
+ *     return properties;
+ * }
+ * 
+ * + * @example Create a zone that casts a red key light along the x-axis. + * 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. + * }); + */ + QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool skipDefaults, bool allowUnknownCreateTime, bool strictSemantics) 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. @@ -491,7 +1192,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANGULAR_VELOCITY, angularVelocity); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ANGULAR_DAMPING, angularDamping); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_VISIBLE, visible); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CAN_CAST_SHADOW, canCastShadow); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CAN_CAST_SHADOW, canCastShadow); // Relevant to Shape and Model entities only. 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); @@ -500,7 +1201,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROXY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_DYNAMIC, dynamic, collisionsWillMove, getDynamic()); // legacy support COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_HREF, href); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_DESCRIPTION, description); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FACE_CAMERA, faceCamera); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FACE_CAMERA, faceCamera); // Text only. COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ACTION_DATA, actionData); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCKED, locked); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_USER_DATA, userData); @@ -521,7 +1222,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_NAME, name); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLLISION_SOUND_URL, collisionSoundURL); - // Boxes, Spheres, Light, Line, Model(??), Particle, PolyLine + // Light, Line, Model, ParticleEffect, PolyLine, Shape COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COLOR, color); // Particles only @@ -569,12 +1270,15 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool if (_type == EntityTypes::Model || _type == EntityTypes::Zone || _type == EntityTypes::ParticleEffect) { COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_SHAPE_TYPE, shapeType, getShapeTypeAsString()); } + + // 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(PROP_SHAPE, shape); } @@ -653,11 +1357,11 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool if (_type == EntityTypes::Line || _type == EntityTypes::PolyLine) { COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_WIDTH, lineWidth); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_POINTS, linePoints); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_NORMALS, normals); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_STROKE_COLORS, strokeColors); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_STROKE_WIDTHS, strokeWidths); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXTURES, textures); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_IS_UV_MODE_STRETCH, isUVModeStretch); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_NORMALS, normals); // Polyline only. + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_STROKE_COLORS, strokeColors); // Polyline only. + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_STROKE_WIDTHS, strokeWidths); // Polyline only. + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXTURES, textures); // Polyline only. + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_IS_UV_MODE_STRETCH, isUVModeStretch); // Polyline only. } // Materials @@ -671,6 +1375,14 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_MAPPING_ROT, materialMappingRot); } + /**jsdoc + * The axis-aligned bounding box of an entity. + * @typedef 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) { AABox aaBox = getAABox(); QScriptValue boundingBox = engine->newObject(); @@ -692,6 +1404,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PARENT_ID, parentID); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PARENT_JOINT_INDEX, parentJointIndex); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_QUERY_AA_CUBE, queryAACube); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_POSITION, localPosition); @@ -700,13 +1413,23 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_ANGULAR_VELOCITY, localAngularVelocity); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_DIMENSIONS, localDimensions); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CLIENT_ONLY, clientOnly); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_OWNING_AVATAR_ID, owningAvatarID); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CLIENT_ONLY, clientOnly); // Gettable but not settable + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_OWNING_AVATAR_ID, owningAvatarID); // Gettable but not settable // Rendering info if (!skipDefaults && !strictSemantics) { QScriptValue renderInfo = engine->newObject(); + /**jsdoc + * Information on how an entity is rendered. Properties are only filled in for Model entities; other + * entity types have an empty object, {}. + * @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} textureSize - The total size of the textures in the entity, in bytes. + * @property {boolean} hasTransparent - Is true if any of the textures has transparency. + * @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 @@ -719,6 +1442,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(renderInfo, renderInfo); // Gettable but not settable } + // FIXME: These properties should already have been set above. properties.setProperty("clientOnly", convertScriptValue(engine, getClientOnly())); properties.setProperty("owningAvatarID", convertScriptValue(engine, getOwningAvatarID())); diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 0838bb937a..9e5d6ddc79 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -208,7 +208,7 @@ public: DEFINE_PROPERTY(PROP_NORMALS, Normals, normals, QVector, ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC); DEFINE_PROPERTY(PROP_STROKE_COLORS, StrokeColors, strokeColors, QVector, ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC); DEFINE_PROPERTY(PROP_STROKE_WIDTHS, StrokeWidths, strokeWidths, QVector, QVector()); - DEFINE_PROPERTY(PROP_IS_UV_MODE_STRETCH, IsUVModeStretch, isUVModeStretch, bool, true); + DEFINE_PROPERTY(PROP_IS_UV_MODE_STRETCH, IsUVModeStretch, isUVModeStretch, bool, true); DEFINE_PROPERTY_REF(PROP_X_TEXTURE_URL, XTextureURL, xTextureURL, QString, ""); DEFINE_PROPERTY_REF(PROP_Y_TEXTURE_URL, YTextureURL, yTextureURL, QString, ""); DEFINE_PROPERTY_REF(PROP_Z_TEXTURE_URL, ZTextureURL, zTextureURL, QString, ""); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 93cbe781be..266ef41cff 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -538,7 +538,7 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& NestableType nestableType = nestable->getNestableType(); if (nestableType == NestableType::Overlay || nestableType == NestableType::Avatar) { qCWarning(entities) << "attempted edit on non-entity: " << id << nestable->getName(); - return QUuid(); // null UUID to indicate failure + return QUuid(); // null script value to indicate failure } } } @@ -1017,6 +1017,25 @@ QScriptValue RayToEntityIntersectionResultToScriptValue(QScriptEngine* engine, c QString faceName = ""; // handle BoxFace + /**jsdoc + *

A BoxFace specifies the face of an axis-aligned (AA) box. + * + * + * + * + * + * + * + * + * + * + * + * + * + *
ValueDescription
"MIN_X_FACE"The minimum x-axis face.
"MAX_X_FACE"The maximum x-axis face.
"MIN_Y_FACE"The minimum y-axis face.
"MAX_Y_FACE"The maximum y-axis face.
"MIN_Z_FACE"The minimum z-axis face.
"MAX_Z_FACE"The maximum z-axis face.
"UNKNOWN_FACE"Unknown value.
+ * @typedef {string} BoxFace + */ + // FIXME: Move enum to string function to BoxBase.cpp. switch (value.face) { case MIN_X_FACE: faceName = "MIN_X_FACE"; diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 6b4cd81e44..b483225390 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -52,6 +52,23 @@ private: QPointer _engine; }; +/**jsdoc + * The result of a {@link PickRay} search using {@link Entities.findRayIntersection|findRayIntersection} or + * {@link Entities.findRayIntersectionBlocking|findRayIntersectionBlocking}. + * @typedef {object} Entities.RayToEntityIntersectionResult + * @property {boolean} intersects - true if the {@link PickRay} intersected an entity, otherwise + * false. + * @property {boolean} accurate - Is always true. + * @property {Uuid} entityID - The ID if the entity intersected, if any, otherwise null. + * @property {number} distance - The distance from the {@link PickRay} origin to the intersection point. + * @property {Vec3} intersection - The intersection point. + * @property {Vec3} surfaceNormal - The surface normal of the entity at the intersection point. + * @property {BoxFace} face - The face of the entity's axis-aligned box that the ray intersects. + * @property {object} extraInfo - Extra information depending on the entity intersected. Currently, only Model + * entities provide extra information, and the information provided depends on the precisionPicking parameter + * value that the search function was called with. + */ +// "accurate" is currently always true because the ray intersection is always performed with an Octree::Lock. class RayToEntityIntersectionResult { public: RayToEntityIntersectionResult(); @@ -72,7 +89,16 @@ void RayToEntityIntersectionResultFromScriptValue(const QScriptValue& object, Ra /**jsdoc + * The Entities API provides facilities to create and interact with entities. Entities are 2D and 3D objects that are visible + * to everyone and typically are persisted to the domain. For Interface scripts, the entities available are those that + * Interface has displayed and so knows about. + * * @namespace Entities + * @property {number} currentAvatarEnergy - Deprecated + * @property {number} costMultiplier - Deprecated + * @property {Uuid} keyboardFocusEntity - Get or set the {@link Entities.EntityType|Web} entity that has keyboard focus. + * If no entity has keyboard focus, get returns null; set to null or {@link Uuid|Uuid.NULL} to + * clear keyboard focus. */ /// handles scripting of Entity commands from JS passed to assigned clients class EntityScriptingInterface : public OctreeScriptingInterface, public Dependency { @@ -107,58 +133,88 @@ public: public slots: /**jsdoc - * Returns `true` if the DomainServer will allow this Node/Avatar to make changes - * + * Check whether or not you can change the locked property of entities. Locked entities have their + * locked property set to true and cannot be edited or deleted. Whether or not you can change + * entities' locked properties is configured in the domain server's permissions. * @function Entities.canAdjustLocks - * @return {bool} `true` if the client can adjust locks, `false` if not. + * @returns {boolean} true if the client can change the locked property of entities, + * otherwise false. + * @example Set an entity's locked property to true if you can. + * if (Entities.canAdjustLocks()) { + * Entities.editEntity(entityID, { locked: true }); + * } else { + * Window.alert("You do not have the permissions to set an entity locked!"); + * } */ Q_INVOKABLE bool canAdjustLocks(); /**jsdoc + * Check whether or not you can rez (create) new entities in the domain. * @function Entities.canRez - * @return {bool} `true` if the DomainServer will allow this Node/Avatar to rez new entities + * @returns {boolean} true if the domain server will allow the script to rez (create) new entities, + * otherwise false. */ Q_INVOKABLE bool canRez(); /**jsdoc + * Check whether or not you can rez (create) new temporary entities in the domain. Temporary entities are entities with a + * finite lifetime property value set. * @function Entities.canRezTmp - * @return {bool} `true` if the DomainServer will allow this Node/Avatar to rez new temporary entities + * @returns {boolean} true if the domain server will allow the script to rez (create) new temporary + * entities, otherwise false. */ Q_INVOKABLE bool canRezTmp(); /**jsdoc - * @function Entities.canRezCertified - * @return {bool} `true` if the DomainServer will allow this Node/Avatar to rez new certified entities - */ + * Check whether or not you can rez (create) new certified entities in the domain. Certified entities are entities that have + * PoP certificates. + * @function Entities.canRezCertified + * @returns {boolean} true if the domain server will allow the script to rez (create) new certified + * entities, otherwise false. + */ Q_INVOKABLE bool canRezCertified(); /**jsdoc - * @function Entities.canRezTmpCertified - * @return {bool} `true` if the DomainServer will allow this Node/Avatar to rez new temporary certified entities - */ + * Check whether or not you can rez (create) new temporary certified entities in the domain. Temporary entities are entities + * with a finite lifetime property value set. Certified entities are entities that have PoP certificates. + * @function Entities.canRezTmpCertified + * @returns {boolean} true if the domain server will allow the script to rez (create) new temporary + * certified entities, otherwise false. + */ Q_INVOKABLE bool canRezTmpCertified(); /**jsdoc - * @function Entities.canWriteAssets - * @return {bool} `true` if the DomainServer will allow this Node/Avatar to write to the asset server - */ + * Check whether or not you can make changes to the asset server's assets. + * @function Entities.canWriteAssets + * @returns {boolean} true if the domain server will allow the script to make changes to the asset server's + * assets, otherwise false. + */ Q_INVOKABLE bool canWriteAssets(); /**jsdoc - * @function Entities.canReplaceContent - * @return {bool} `true` if the DomainServer will allow this Node/Avatar to replace the domain's content set - */ + * Check whether or not you can replace the domain's content set. + * @function Entities.canReplaceContent + * @returns {boolean} true if the domain server will allow the script to replace the domain's content set, + * otherwise false. + */ Q_INVOKABLE bool canReplaceContent(); /**jsdoc - * Add a new entity with the specified properties. If `clientOnly` is true, the entity will - * not be sent to the server and will only be visible/accessible on the local client. - * + * Add a new entity with specified properties. * @function Entities.addEntity - * @param {EntityItemProperties} properties Properties of the entity to create. - * @param {bool} [clientOnly=false] Whether the entity should only exist locally or not. - * @return {EntityID} The entity ID of the newly created entity. The ID will be a null - * UUID (`{00000000-0000-0000-0000-000000000000}`) if the entity could not be created. + * @param {Entities.EntityProperties} properties - The properties of the entity to create. + * @param {boolean} [clientOnly=false] - If true, the entity is created as an avatar entity, otherwise it + * is created on the server. An avatar entity follows you to each domain you visit, rendering at the same world + * coordinates unless it's parented to your avatar. + * @returns {Uuid} The ID of the entity if successfully created, otherwise {@link Uuid|Uuid.NULL}. + * @example Create a box entity in front of your avatar. + * var entityID = Entities.addEntity({ + * type: "Box", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })), + * rotation: MyAvatar.orientation, + * dimensions: { x: 0.5, y: 0.5, z: 0.5 } + * }); + * print("Entity created: " + entityID); */ Q_INVOKABLE QUuid addEntity(const EntityItemProperties& properties, bool clientOnly = false); @@ -168,115 +224,202 @@ public slots: bool collisionless, const glm::vec3& position, const glm::vec3& gravity); /**jsdoc - * Return the properties for the specified {EntityID}. - * not be sent to the server and will only be visible/accessible on the local client. - * @param {EntityItemProperties} properties Properties of the entity to create. - * @param {EntityPropertyFlags} [desiredProperties=[]] Array containing the names of the properties you - * would like to get. If the array is empty, all properties will be returned. - * @return {EntityItemProperties} The entity properties for the specified entity. + * Get the properties of an entity. + * @function Entities.getEntityProperties + * @param {Uuid} entityID - The ID of the entity to get the properties of. + * @param {string[]} [desiredProperties=[]] - Array of the names of the properties to get. If the array is empty, + * all properties are returned. + * @returns {Entities.EntityProperties} The properties of the entity if the entity can be found, otherwise an empty object. + * @example Report the color of a new box entity. + * var entityID = Entities.addEntity({ + * type: "Box", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })), + * rotation: MyAvatar.orientation, + * dimensions: { x: 0.5, y: 0.5, z: 0.5 } + * }); + * var properties = Entities.getEntityProperties(entityID, ["color"]); + * print("Entity color: " + JSON.stringify(properties.color)); */ Q_INVOKABLE EntityItemProperties getEntityProperties(QUuid entityID); Q_INVOKABLE EntityItemProperties getEntityProperties(QUuid identity, EntityPropertyFlags desiredProperties); /**jsdoc - * Updates an entity with the specified properties. - * + * Update an entity with specified properties. * @function Entities.editEntity - * @return {EntityID} The EntityID of the entity if the edit was successful, otherwise the null {EntityID}. + * @param {Uuid} entityID - The ID of the entity to edit. + * @param {Entities.EntityProperties} properties - The properties to update the entity with. + * @returns {Uuid} The ID of the entity if the edit was successful, otherwise null. + * @example Change the color of an entity. + * var entityID = Entities.addEntity({ + * type: "Box", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })), + * rotation: MyAvatar.orientation, + * dimensions: { x: 0.5, y: 0.5, z: 0.5 } + * }); + * var properties = Entities.getEntityProperties(entityID, ["color"]); + * print("Entity color: " + JSON.stringify(properties.color)); + * + * Entities.editEntity(entityID, { + * color: { red: 255, green: 0, blue: 0 } + * }); + * properties = Entities.getEntityProperties(entityID, ["color"]); + * print("Entity color: " + JSON.stringify(properties.color)); */ Q_INVOKABLE QUuid editEntity(QUuid entityID, const EntityItemProperties& properties); /**jsdoc - * Deletes an entity. - * + * Delete an entity. * @function Entities.deleteEntity - * @param {EntityID} entityID The ID of the entity to delete. + * @param {Uuid} entityID - The ID of the entity to delete. + * @example Delete an entity a few seconds after creating it. + * var entityID = Entities.addEntity({ + * type: "Box", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })), + * rotation: MyAvatar.orientation, + * dimensions: { x: 0.5, y: 0.5, z: 0.5 } + * }); + * + * Script.setTimeout(function () { + * Entities.deleteEntity(entityID); + * }, 3000); */ Q_INVOKABLE void deleteEntity(QUuid entityID); + /**jsdoc - * Call a method on an entity in the same context as this function is called. Allows a script - * to call a method on an entity's script. The method will execute in the entity script engine. - * If the entity does not have an entity script or the method does not exist, this call will - * have no effect. If it is running an entity script (specified by the `script` property) - * and it exposes a property with the specified name `method`, it will be called - * using `params` as the list of arguments. If this is called within an entity script, the - * method will be executed on the client in the entity script engine in which it was called. If - * this is called in an entity server script, the method will be executed on the entity server - * script engine. - * + * Call a method in a client entity script from a client script or client entity script, or call a method in a server + * entity script from a server entity script. The entity script method must be exposed as a property in the target client + * entity script. Additionally, if calling a server entity script, the server entity script must include the method's name + * in an exposed property called remotelyCallable that is an array of method names that can be called. * @function Entities.callEntityMethod - * @param {EntityID} entityID The ID of the entity to call the method on. - * @param {string} method The name of the method to call. - * @param {string[]} params The list of parameters to call the specified method with. + * @param {Uuid} entityID - The ID of the entity to call the method in. + * @param {string} method - The name of the method to call. + * @param {string[]} [parameters=[]] - The parameters to call the specified method with. */ Q_INVOKABLE void callEntityMethod(QUuid entityID, const QString& method, const QStringList& params = QStringList()); /**jsdoc - * Call a server method on an entity. Allows a client entity script to call a method on an - * entity's server script. The method will execute in the entity server script engine. If - * the entity does not have an entity server script or the method does not exist, this call will - * have no effect. If the entity is running an entity script (specified by the `serverScripts` property) - * and it exposes a property with the specified name `method`, it will be called using `params` as - * the list of arguments. - * - * @function Entities.callEntityServerMethod - * @param {EntityID} entityID The ID of the entity to call the method on. - * @param {string} method The name of the method to call. - * @param {string[]} params The list of parameters to call the specified method with. - */ + * Call a method in a server entity script from a client script or client entity script. The entity script method must be + * exposed as a property in the target server entity script. Additionally, the target server entity script must include the + * method's name in an exposed property called remotelyCallable that is an array of method names that can be + * called. + * @function Entities.callEntityServerMethod + * @param {Uuid} entityID - The ID of the entity to call the method in. + * @param {string} method - The name of the method to call. + * @param {string[]} [parameters=[]] - The parameters to call the specified method with. + */ Q_INVOKABLE void callEntityServerMethod(QUuid entityID, const QString& method, const QStringList& params = QStringList()); /**jsdoc - * Call a client method on an entity on a specific client node. Allows a server entity script to call a - * method on an entity's client script for a particular client. The method will execute in the entity script - * engine on that single client. If the entity does not have an entity script or the method does not exist, or - * the client is not connected to the domain, or you attempt to make this call outside of the entity server - * script, this call will have no effect. - * - * @function Entities.callEntityClientMethod - * @param {SessionID} clientSessionID The session ID of the client to call the method on. - * @param {EntityID} entityID The ID of the entity to call the method on. - * @param {string} method The name of the method to call. - * @param {string[]} params The list of parameters to call the specified method with. - */ - Q_INVOKABLE void callEntityClientMethod(QUuid clientSessionID, QUuid entityID, const QString& method, const QStringList& params = QStringList()); + * Call a method in a specific user's client entity script from a server entity script. The entity script method must be + * exposed as a property in the target client entity script. + * @function Entities.callEntityClientMethod + * @param {Uuid} clientSessionID - The session ID of the user to call the method in. + * @param {Uuid} entityID - The ID of the entity to call the method in. + * @param {string} method - The name of the method to call. + * @param {string[]} [parameters=[]] - The parameters to call the specified method with. + */ + Q_INVOKABLE void callEntityClientMethod(QUuid clientSessionID, QUuid entityID, const QString& method, + const QStringList& params = QStringList()); + /**jsdoc - * finds the closest model to the center point, within the radius - * will return a EntityItemID.isKnownID = false if no models are in the radius - * this function will not find any models in script engine contexts which don't have access to models + * Find the entity with a position closest to a specified point and within a specified radius. * @function Entities.findClosestEntity - * @param {vec3} center point - * @param {float} radius to search - * @return {EntityID} The EntityID of the entity that is closest and in the radius. + * @param {Vec3} center - The point about which to search. + * @param {number} radius - The radius within which to search. + * @returns {Uuid} The ID of the entity that is closest to the center and within the radius if + * there is one, otherwise null. + * @example Find the closest entity within 10m of your avatar. + * var entityID = Entities.findClosestEntity(MyAvatar.position, 10); + * print("Closest entity: " + entityID); */ + /// this function will not find any models in script engine contexts which don't have access to models Q_INVOKABLE QUuid findClosestEntity(const glm::vec3& center, float radius) const; - /// finds models within the search sphere specified by the center point and radius + /**jsdoc + * Find all entities that intersect a sphere defined by a center point and radius. + * @function Entities.findEntities + * @param {Vec3} center - The point about which to search. + * @param {number} radius - The radius within which to search. + * @returns {Uuid[]} An array of entity IDs that were found that intersect the search sphere. The array is empty if no + * entities could be found. + * @example Report how many entities are within 10m of your avatar. + * var entityIDs = Entities.findEntities(MyAvatar.position, 10); + * print("Number of entities within 10m: " + entityIDs.length); + */ /// this function will not find any models in script engine contexts which don't have access to models Q_INVOKABLE QVector findEntities(const glm::vec3& center, float radius) const; - /// finds models within the box specified by the corner and dimensions + /**jsdoc + * Find all entities whose axis-aligned boxes intersect a search axis-aligned box defined by its minimum coordinates corner + * and dimensions. + * @function Entities.findEntitiesInBox + * @param {Vec3} corner - The corner of the search AA box with minimum co-ordinate values. + * @param {Vec3} dimensions - The dimensions of the search AA box. + * @returns {Uuid[]} An array of entity IDs whose AA boxes intersect the search AA box. The array is empty if no entities + * could be found. + */ /// this function will not find any models in script engine contexts which don't have access to models Q_INVOKABLE QVector findEntitiesInBox(const glm::vec3& corner, const glm::vec3& dimensions) const; - /// finds models within the frustum - /// the frustum must have the following properties: - /// - position - /// - orientation - /// - projection - /// - centerRadius + /**jsdoc + * Find all entities whose axis-aligned boxes intersect a search frustum. + * @function Entities.findEntitiesInFrustum + * @param {ViewFrustum} frustum - The frustum to search in. The position, orientation, + * projection, and centerRadius properties must be specified. + * @returns {Uuid[]} An array of entity IDs axis-aligned boxes intersect the frustum. The array is empty if no entities + * could be found. + * @example Report the number of entities in view. + * var entityIDs = Entities.findEntitiesInFrustum(Camera.frustum); + * print("Number of entities in view: " + entityIDs.length); + */ /// this function will not find any models in script engine contexts which don't have access to entities Q_INVOKABLE QVector findEntitiesInFrustum(QVariantMap frustum) const; - /// finds entities of the indicated type within a sphere given by the center point and radius - /// @param {QString} string representation of entity type - /// @param {vec3} center point - /// @param {float} radius to search + /**jsdoc + * Find all entities of a particular type that intersect a sphere defined by a center point and radius. + * @function Entities.findEntitiesByType + * @param {Entities.EntityType} entityType - The type of entity to search for. + * @param {Vec3} center - The point about which to search. + * @param {number} radius - The radius within which to search. + * @returns {Uuid[]} An array of entity IDs of the specified type that intersect the search sphere. The array is empty if + * no entities could be found. + * @example Report the number of Model entities within 10m of your avatar. + * var entityIDs = Entities.findEntitiesByType("Model", MyAvatar.position, 10); + * print("Number of Model entities within 10m: " + entityIDs.length); + */ /// this function will not find any entities in script engine contexts which don't have access to entities Q_INVOKABLE QVector findEntitiesByType(const QString entityType, const glm::vec3& center, float radius) const; + /**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.
+ * @function Entities.findRayIntersection + * @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. + * @param {boolean} [visibleOnly=false] - If true then only entities that are + * {@link Entities.EntityProperties|visible} are searched. + * @param {boolean} [collideableOnly=false] - If true then only entities that are not + * {@link Entities.EntityProperties|collisionless} are searched. + * @returns {Entities.RayToEntityIntersectionResult} The result of the search for the first intersected entity. + * @example Find the entity directly in front of your avatar. + * var pickRay = { + * origin: MyAvatar.position, + * direction: Quat.getFront(MyAvatar.orientation) + * }; + * + * var intersection = Entities.findRayIntersection(pickRay, true); + * if (intersection.intersects) { + * print("Entity in front of avatar: " + intersection.entityID); + * } else { + * print("No entity in front of avatar."); + * } + */ /// If the scripting context has visible entities, this will determine a ray intersection, the results /// may be inaccurate if the engine is unable to access the visible entities, in which case result.accurate /// will be false. @@ -289,187 +432,1424 @@ public slots: 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()); + Q_INVOKABLE RayToEntityIntersectionResult findRayIntersectionBlocking(const PickRay& ray, bool precisionPicking = false, + const QScriptValue& entityIdsToInclude = QScriptValue(), const QScriptValue& entityIdsToDiscard = QScriptValue()); + + /**jsdoc + * Reloads an entity's server entity script such that the latest version re-downloaded. + * @function Entities.reloadServerScripts + * @param {Uuid} entityID - The ID of the entity to reload the server entity script of. + * @returns {boolean} true if the reload request was successfully sent to the server, otherwise + * false. + */ Q_INVOKABLE bool reloadServerScripts(QUuid entityID); /**jsdoc - * Query additional metadata for "magic" Entity properties like `script` and `serverScripts`. - * - * @function Entities.queryPropertyMetadata - * @param {EntityID} entityID The ID of the entity. - * @param {string} property The name of the property extended metadata is wanted for. - * @param {ResultCallback} callback Executes callback(err, result) with the query results. + * Gets the status of server entity script attached to an entity + * @function Entities.getServerScriptStatus + * @property {Uuid} entityID - The ID of the entity to get the server entity script status for. + * @property {Entities~getServerScriptStatusCallback} callback - The function to call upon completion. + * @returns {boolean} true always. */ /**jsdoc - * Query additional metadata for "magic" Entity properties like `script` and `serverScripts`. - * - * @function Entities.queryPropertyMetadata - * @param {EntityID} entityID The ID of the entity. - * @param {string} property The name of the property extended metadata is wanted for. - * @param {Object} thisObject The scoping "this" context that callback will be executed within. - * @param {ResultCallback} callbackOrMethodName Executes thisObject[callbackOrMethodName](err, result) with the query results. + * Called when {@link Entities.getServerScriptStatus} is complete. + * @callback Entities~getServerScriptStatusCallback + * @param {boolean} success - true if the server entity script status could be obtained, otherwise + * false. + * @param {boolean} isRunning - true if there is a server entity script running, otherwise false. + * @param {string} status - "running" if there is a server entity script running, otherwise an error string. + * @param {string} errorInfo - "" if there is a server entity script running, otherwise it may contain extra + * information on the error. */ - Q_INVOKABLE bool queryPropertyMetadata(QUuid entityID, QScriptValue property, QScriptValue scopeOrCallback, QScriptValue methodOrName = QScriptValue()); - Q_INVOKABLE bool getServerScriptStatus(QUuid entityID, QScriptValue callback); + /**jsdoc + * Get metadata for certain entity properties such as script and serverScripts. + * @function Entities.queryPropertyMetadata + * @param {Uuid} entityID - The ID of the entity to get the metadata for. + * @param {string} property - The property name to get the metadata for. + * @param {Entities~queryPropertyMetadataCallback} callback - The function to call upon completion. + * @returns {boolean} true if the request for metadata was successfully sent to the server, otherwise + * false. + * @throws Throws an error if property is not handled yet or callback is not a function. + */ + /**jsdoc + * Get metadata for certain entity properties such as script and serverScripts. + * @function Entities.queryPropertyMetadata + * @param {Uuid} entityID - The ID of the entity to get the metadata for. + * @param {string} property - The property name to get the metadata for. + * @param {object} scope - The "this" context that the callback will be executed within. + * @param {Entities~queryPropertyMetadataCallback} callback - The function to call upon completion. + * @returns {boolean} true if the request for metadata was successfully sent to the server, otherwise + * false. + * @throws Throws an error if property is not handled yet or callback is not a function. + */ + /**jsdoc + * Called when {@link Entities.queryPropertyMetadata} is complete. + * @callback Entities~queryPropertyMetadataCallback + * @param {string} error - undefined if there was no error, otherwise an error message. + * @param {object} result - The metadata for the requested entity property if there was no error, otherwise + * undefined. + */ + Q_INVOKABLE bool queryPropertyMetadata(QUuid entityID, QScriptValue property, QScriptValue scopeOrCallback, + QScriptValue methodOrName = QScriptValue()); + + + /**jsdoc + * Set whether or not ray picks intersect the bounding box of {@link Entities.EntityType|Light} entities. By default, Light + * entities are not intersected. The setting lasts for the Interface session. Ray picks are done using + * {@link Entities.findRayIntersection|findRayIntersection} or + * {@link Entities.findRayIntersectionBlocking|findRayIntersectionBlocking}, or the {@link Picks} and {@link RayPick} + * APIs. + * @function Entities.setLightsArePickable + * @param {boolean} value - Set true to make ray picks intersect the bounding box of + * {@link Entities.EntityType|Light} entities, otherwise false. + */ // FIXME move to a renderable entity interface Q_INVOKABLE void setLightsArePickable(bool value); + + /**jsdoc + * Get whether or not ray picks intersect the bounding box of {@link Entities.EntityType|Light} entities. Ray picks are + * done using {@link Entities.findRayIntersection|findRayIntersection} or + * {@link Entities.findRayIntersectionBlocking|findRayIntersectionBlocking}, or the {@link Picks} and {@link RayPick} + * APIs. + * @function Entities.getLightsArePickable + * @returns {boolean} true if ray picks intersect the bounding box of {@link Entities.EntityType|Light} + * entities, otherwise false. + */ + // FIXME move to a renderable entity interface Q_INVOKABLE bool getLightsArePickable() const; + /**jsdoc + * Set whether or not ray picks intersect the bounding box of {@link Entities.EntityType|Zone} entities. By default, Light + * entities are not intersected. The setting lasts for the Interface session. Ray picks are done using + * {@link Entities.findRayIntersection|findRayIntersection} or + * {@link Entities.findRayIntersectionBlocking|findRayIntersectionBlocking}, or the {@link Picks} and {@link RayPick} + * APIs. + * @function Entities.setZonesArePickable + * @param {boolean} value - Set true to make ray picks intersect the bounding box of + * {@link Entities.EntityType|Zone} entities, otherwise false. + */ // FIXME move to a renderable entity interface Q_INVOKABLE void setZonesArePickable(bool value); + + /**jsdoc + * Get whether or not ray picks intersect the bounding box of {@link Entities.EntityType|Zone} entities. Ray picks are + * done using {@link Entities.findRayIntersection|findRayIntersection} or + * {@link Entities.findRayIntersectionBlocking|findRayIntersectionBlocking}, or the {@link Picks} and {@link RayPick} + * APIs. + * @function Entities.getZonesArePickable + * @returns {boolean} true if ray picks intersect the bounding box of {@link Entities.EntityType|Zone} + * entities, otherwise false. + */ + // FIXME move to a renderable entity interface Q_INVOKABLE bool getZonesArePickable() const; + /**jsdoc + * Set whether or not {@link Entities.EntityType|Zone} entities' boundaries should be drawn. Currently not used. + * @function Entities.setDrawZoneBoundaries + * @param {boolean} value - Set to true if {@link Entities.EntityType|Zone} entities' boundaries should be + * drawn, otherwise false. + */ // FIXME move to a renderable entity interface Q_INVOKABLE void setDrawZoneBoundaries(bool value); + + /**jsdoc + * Get whether or not {@link Entities.EntityType|Zone} entities' boundaries should be drawn. Currently not used. + * @function Entities.getDrawZoneBoundaries + * @returns {boolean} true if {@link Entities.EntityType|Zone} entities' boundaries should be drawn, + * otherwise false. + */ + // FIXME move to a renderable entity interface Q_INVOKABLE bool getDrawZoneBoundaries() const; + + /**jsdoc + * Set the values of all voxels in a spherical portion of a {@link Entities.EntityType|PolyVox} entity. + * @function Entities.setVoxelSphere + * @param {Uuid} entityID - The ID of the {@link Entities.EntityType|PolyVox} entity. + * @param {Vec3} center - The center of the sphere of voxels to set, in world coordinates. + * @param {number} radius - The radius of the sphere of voxels to set, in world coordinates. + * @param {number} value - If value % 256 == 0 then each voxel is cleared, otherwise each voxel is set. + * @example Create a PolyVox sphere. + * var position = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0.5, z: -8 })); + * var polyVox = Entities.addEntity({ + * type: "PolyVox", + * position: position, + * dimensions: { x: 2, y: 2, z: 2 }, + * voxelVolumeSize: { x: 32, y: 32, z: 32 }, + * lifetime: 300 // Delete after 5 minutes. + * }); + * Entities.setVoxelSphere(polyVox, position, 0.9, 255); + */ // FIXME move to a renderable entity interface Q_INVOKABLE bool setVoxelSphere(QUuid entityID, const glm::vec3& center, float radius, int value); + + /**jsdoc + * Set the values of all voxels in a capsule-shaped portion of a {@link Entities.EntityType|PolyVox} entity. + * @function Entities.setVoxelCapsule + * @param {Uuid} entityID - The ID of the {@link Entities.EntityType|PolyVox} entity. + * @param {Vec3} start - The center of the sphere of voxels to set, in world coordinates. + * @param {Vec3} end - The center of the sphere of voxels to set, in world coordinates. + * @param {number} radius - The radius of the capsule cylinder and spherical ends, in world coordinates. + * @param {number} value - If value % 256 == 0 then each voxel is cleared, otherwise each voxel is set. + * @example Create a PolyVox capsule shape. + * var position = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0.5, z: -8 })); + * var polyVox = Entities.addEntity({ + * type: "PolyVox", + * position: position, + * dimensions: { x: 2, y: 2, z: 2 }, + * voxelVolumeSize: { x: 32, y: 32, z: 32 }, + * lifetime: 300 // Delete after 5 minutes. + * }); + * var startPosition = Vec3.sum({ x: -0.5, y: 0, z: 0 }, position); + * var endPosition = Vec3.sum({ x: 0.5, y: 0, z: 0 }, position); + * Entities.setVoxelCapsule(polyVox, startPosition, endPosition, 0.5, 255); + */ + // FIXME move to a renderable entity interface Q_INVOKABLE bool setVoxelCapsule(QUuid entityID, const glm::vec3& start, const glm::vec3& end, float radius, int value); + /**jsdoc + * Set the value of a particular voxels in a {@link Entities.EntityType|PolyVox} entity. + * @function Entities.setVoxel + * @param {Uuid} entityID - The ID of the {@link Entities.EntityType|PolyVox} entity. + * @param {Vec3} position - The position relative to the minimum axes values corner of the entity. The + * position coordinates are rounded to the nearest integer to get the voxel coordinate. The minimum axes + * corner voxel is { x: 0, y: 0, z: 0 }. + * @param {number} value - If value % 256 == 0 then voxel is cleared, otherwise the voxel is set. + * @example Create a cube PolyVox entity and clear the minimum axes corner voxel. + * var entity = Entities.addEntity({ + * type: "PolyVox", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0.5, z: -8 })), + * dimensions: { x: 2, y: 2, z: 2 }, + * voxelVolumeSize: { x: 16, y: 16, z: 16 }, + * lifetime: 300 // Delete after 5 minutes. + * }); + * Entities.setAllVoxels(entity, 1); + * Entities.setVoxel(entity, { x: 0, y: 0, z: 0 }, 0); + */ // FIXME move to a renderable entity interface Q_INVOKABLE bool setVoxel(QUuid entityID, const glm::vec3& position, int value); + + /**jsdoc + * Set the values of all voxels in a {@link Entities.EntityType|PolyVox} entity. + * @function Entities.setAllVoxels + * @param {Uuid} entityID - The ID of the {@link Entities.EntityType|PolyVox} entity. + * @param {number} value - If value % 256 == 0 then each voxel is cleared, otherwise each voxel is set. + * @example Create a PolyVox cube. + * var entity = Entities.addEntity({ + * type: "PolyVox", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0.5, z: -8 })), + * dimensions: { x: 2, y: 2, z: 2 }, + * voxelVolumeSize: { x: 16, y: 16, z: 16 }, + * lifetime: 300 // Delete after 5 minutes. + * }); + * Entities.setAllVoxels(entity, 1); + */ + // FIXME move to a renderable entity interface Q_INVOKABLE bool setAllVoxels(QUuid entityID, int value); - Q_INVOKABLE bool setVoxelsInCuboid(QUuid entityID, const glm::vec3& lowPosition, - const glm::vec3& cuboidSize, int value); - Q_INVOKABLE bool setAllPoints(QUuid entityID, const QVector& points); - Q_INVOKABLE bool appendPoint(QUuid entityID, const glm::vec3& point); - - Q_INVOKABLE void dumpTree() const; - - Q_INVOKABLE QUuid addAction(const QString& actionTypeString, const QUuid& entityID, const QVariantMap& arguments); - Q_INVOKABLE bool updateAction(const QUuid& entityID, const QUuid& actionID, const QVariantMap& arguments); - Q_INVOKABLE bool deleteAction(const QUuid& entityID, const QUuid& actionID); - Q_INVOKABLE QVector getActionIDs(const QUuid& entityID); - Q_INVOKABLE QVariantMap getActionArguments(const QUuid& entityID, const QUuid& actionID); + /**jsdoc + * Set the values of all voxels in a cubic portion of a {@link Entities.EntityType|PolyVox} entity. + * @function Entities.setVoxelsInCuboid + * @param {Uuid} entityID - The ID of the {@link Entities.EntityType|PolyVox} entity. + * @param {Vec3} lowPosition - The position of the minimum axes value corner of the cube of voxels to set, in voxel + * coordinates. + * @param {Vec3} cuboidSize - The size of the cube of voxels to set, in voxel coordinates. + * @param {number} value - If value % 256 == 0 then each voxel is cleared, otherwise each voxel is set. + * @example Create a PolyVox cube and clear the voxels in one corner. + * var polyVox = Entities.addEntity({ + * type: "PolyVox", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0.5, z: -8 })), + * rotation: MyAvatar.orientation, + * dimensions: { x: 2, y: 2, z: 2 }, + * voxelVolumeSize: { x: 16, y: 16, z: 16 }, + * lifetime: 300 // Delete after 5 minutes. + * }); + * Entities.setAllVoxels(polyVox, 1); + * var cuboidPosition = { x: 12, y: 12, z: 12 }; + * var cuboidSize = { x: 4, y: 4, z: 4 }; + * Entities.setVoxelsInCuboid(polyVox, cuboidPosition, cuboidSize, 0); + */ + // FIXME move to a renderable entity interface + Q_INVOKABLE bool setVoxelsInCuboid(QUuid entityID, const glm::vec3& lowPosition, const glm::vec3& cuboidSize, int value); + /**jsdoc + * Convert voxel coordinates in a {@link Entities.EntityType|PolyVox} entity to world coordinates. Voxel coordinates are + * relative to the minimum axes values corner of the entity with a scale of Vec3.ONE being the dimensions of + * each voxel. + * @function Entities.voxelCoordsToWorldCoords + * @param {Uuid} entityID - The ID of the {@link Entities.EntityType|PolyVox} entity. + * @param {Vec3} voxelCoords - The voxel coordinates. May be fractional and outside the entity's bounding box. + * @returns {Vec3} The world coordinates of the voxelCoords if the entityID is a + * {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3|Vec3.ZERO}. + * @example Create a PolyVox cube with the 0,0,0 voxel replaced by a sphere. + * // Cube PolyVox with 0,0,0 voxel missing. + * var polyVox = Entities.addEntity({ + * type: "PolyVox", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0.5, z: -8 })), + * dimensions: { x: 2, y: 2, z: 2 }, + * voxelVolumeSize: { x: 16, y: 16, z: 16 }, + * lifetime: 300 // Delete after 5 minutes. + * }); + * Entities.setAllVoxels(polyVox, 1); + * Entities.setVoxel(polyVox, { x: 0, y: 0, z: 0 }, 0); + * + * // Red sphere in 0,0,0 corner position. + * var cornerPosition = Entities.voxelCoordsToWorldCoords(polyVox, { x: 0, y: 0, z: 0 }); + * var voxelDimensions = Vec3.multiply(2 / 16, Vec3.ONE); + * var sphere = Entities.addEntity({ + * type: "Sphere", + * position: Vec3.sum(cornerPosition, Vec3.multiply(0.5, voxelDimensions)), + * dimensions: voxelDimensions, + * color: { red: 255, green: 0, blue: 0 }, + * lifetime: 300 // Delete after 5 minutes. + * }); + */ // FIXME move to a renderable entity interface Q_INVOKABLE glm::vec3 voxelCoordsToWorldCoords(const QUuid& entityID, glm::vec3 voxelCoords); + + /**jsdoc + * Convert world coordinates to voxel coordinates in a {@link Entities.EntityType|PolyVox} entity. Voxel coordinates are + * relative to the minimum axes values corner of the entity, with a scale of Vec3.ONE being the dimensions of + * each voxel. + * @function Entities.worldCoordsToVoxelCoords + * @param {Uuid} entityID - The ID of the {@link Entities.EntityType|PolyVox} entity. + * @param {Vec3} worldCoords - The world coordinates. May be outside the entity's bounding box. + * @returns {Vec3} The voxel coordinates of the worldCoords if the entityID is a + * {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3|Vec3.ZERO}. The value may be fractional. + */ + // FIXME move to a renderable entity interface Q_INVOKABLE glm::vec3 worldCoordsToVoxelCoords(const QUuid& entityID, glm::vec3 worldCoords); + + /**jsdoc + * Convert voxel coordinates in a {@link Entities.EntityType|PolyVox} entity to local coordinates relative to the minimum + * axes value corner of the entity, with the scale being the same as world coordinates. + * @function Entities.voxelCoordsToLocalCoords + * @param {Uuid} entityID - The ID of the {@link Entities.EntityType|PolyVox} entity. + * @param {Vec3} voxelCoords - The voxel coordinates. May be fractional and outside the entity's bounding box. + * @returns {Vec3} The local coordinates of the voxelCoords if the entityID is a + * {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3|Vec3.ZERO}. + * @example Get the world dimensions of a voxel in a PolyVox entity. + * var polyVox = Entities.addEntity({ + * type: "PolyVox", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0.5, z: -8 })), + * dimensions: { x: 2, y: 2, z: 2 }, + * voxelVolumeSize: { x: 16, y: 16, z: 16 }, + * lifetime: 300 // Delete after 5 minutes. + * }); + * var voxelDimensions = Entities.voxelCoordsToLocalCoords(polyVox, Vec3.ONE); + * print("Voxel dimensions: " + JSON.stringify(voxelDimensions)); + */ + // FIXME move to a renderable entity interface Q_INVOKABLE glm::vec3 voxelCoordsToLocalCoords(const QUuid& entityID, glm::vec3 voxelCoords); + + /**jsdoc + * Convert local coordinates to voxel coordinates in a {@link Entities.EntityType|PolyVox} entity. Local coordinates are + * relative to the minimum axes value corner of the entity, with the scale being the same as world coordinates. + * @function Entities.localCoordsToVoxelCoords + * @param {Uuid} entityID - The ID of the {@link Entities.EntityType|PolyVox} entity. + * @param {Vec3} localCoords - The local coordinates. May be outside the entity's bounding box. + * @returns {Vec3} The voxel coordinates of the worldCoords if the entityID is a + * {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3|Vec3.ZERO}. The value may be fractional. + */ + // FIXME move to a renderable entity interface Q_INVOKABLE glm::vec3 localCoordsToVoxelCoords(const QUuid& entityID, glm::vec3 localCoords); + /**jsdoc + * Set the linePoints property of a {@link Entities.EntityType|Line} entity. + * @function Entities.setAllPoints + * @param {Uuid} entityID - The ID of the {@link Entities.EntityType|Line} entity. + * @param {Vec3[]} points - The array of points to set the entity's linePoints property to. + * @returns {boolean} true if the entity's property was updated, otherwise false. The property + * may fail to be updated if the entity does not exist, the entity is not a {@link Entities.EntityType|Line} entity, + * one of the points is outside the entity's dimensions, or the number of points is greater than the maximum allowed. + * @example Change the shape of a Line entity. + * // Draw a horizontal line between two points. + * 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: 0, z: 0 }, + * { x:1, y: -0, z: 0 } + * ], + * color: { red: 255, green: 0, blue: 0 }, + * lifetime: 300 // Delete after 5 minutes. + * }); + * + * // Change the line to be a "V". + * Script.setTimeout(function () { + * Entities.setAllPoints(entity, [ + * { x: -1, y: 1, z: 0 }, + * { x: 0, y: -1, z: 0 }, + * { x: 1, y: 1, z: 0 }, + * ]); + * }, 2000); + */ + Q_INVOKABLE bool setAllPoints(QUuid entityID, const QVector& points); + + /**jsdoc + * Append a point to a {@link Entities.EntityType|Line} entity. + * @function Entities.appendPoint + * @param {Uuid} entityID - The ID of the {@link Entities.EntityType|Line} entity. + * @param {Vec3} point - The point to add to the line. The coordinates are relative to the entity's position. + * @returns {boolean} true if the point was added to the line, otherwise false. The point may + * fail to be added if the entity does not exist, the entity is not a {@link Entities.EntityType|Line} entity, the + * point is outside the entity's dimensions, or the maximum number of points has been reached. + * @example Append a point to a Line entity. + * // Draw a line between two points. + * 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 } + * ], + * color: { red: 255, green: 0, blue: 0 }, + * lifetime: 300 // Delete after 5 minutes. + * }); + * + * // Add a third point to create a "V". + * Entities.appendPoint(entity, { x: 1, y: 1, z: 0 }); + */ + Q_INVOKABLE bool appendPoint(QUuid entityID, const glm::vec3& point); + + /**jsdoc + * Dumps debug information about all entities in Interface's local in-memory tree of entities it knows about — domain + * and client-only — to the program log. + * @function Entities.dumpTree + */ + Q_INVOKABLE void dumpTree() const; + + + /**jsdoc + * Add an action to an entity. An action is registered with the physics engine and is applied every physics simulation + * step. Any entity may have more than one action associated with it, but only as many as will fit in an entity's + * actionData property. + * @function Entities.addAction + * @param {Entities.ActionType} actionType - The type of action. + * @param {Uuid} entityID - The ID of the entity to add the action to. + * @param {Entities.ActionArguments} arguments - Configure the action. + * @returns {Uuid} The ID of the action added if successfully added, otherwise null. + * @example Constrain a cube to move along a vertical line. + * var entityID = Entities.addEntity({ + * type: "Box", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0.75, z: -5 })), + * dimensions: { x: 0.5, y: 0.5, z: 0.5 }, + * dynamic: true, + * collisionless: false, + * userData: "{ \"grabbableKey\": { \"grabbable\": true, \"kinematic\": false } }", + * lifetime: 300 // Delete after 5 minutes. + * }); + * + * var actionID = Entities.addAction("slider", entityID, { + * axis: { x: 0, y: 1, z: 0 }, + * linearLow: 0, + * linearHigh: 0.6 + * }); + */ + Q_INVOKABLE QUuid addAction(const QString& actionTypeString, const QUuid& entityID, const QVariantMap& arguments); + + /**jsdoc + * Update an entity action. + * @function Entities.updateAction + * @param {Uuid} entityID - The ID of the entity with the action to update. + * @param {Uuid} actionID - The ID of the action to update. + * @param {Entities.ActionArguments} arguments - The arguments to update. + * @returns {boolean} true if the update was successful, otherwise false. + */ + Q_INVOKABLE bool updateAction(const QUuid& entityID, const QUuid& actionID, const QVariantMap& arguments); + + /**jsdoc + * Delete an action from an entity. + * @function Entities.deleteAction + * @param {Uuid} entityID - The ID of entity to delete the action from. + * @param {Uuid} actionID - The ID of the action to delete. + * @returns {boolean} true if the update was successful, otherwise false. + */ + Q_INVOKABLE bool deleteAction(const QUuid& entityID, const QUuid& actionID); + + /**jsdoc + * Get the IDs of the actions that are associated with an entity. + * @function Entities.getActionIDs + * @param {Uuid} entityID - The entity to get the action IDs for. + * @returns {Uuid[]} An array of action IDs if any are found, otherwise an empty array. + */ + Q_INVOKABLE QVector getActionIDs(const QUuid& entityID); + + /**jsdoc + * Get the arguments of an action. + * @function Entities.getActionArguments + * @param {Uuid} entityID - The ID of the entity with the action. + * @param {Uuid} actionID - The ID of the action to get the arguments of. + * @returns {Entities.ActionArguments} The arguments of the requested action if found, otherwise an empty object. + */ + Q_INVOKABLE QVariantMap getActionArguments(const QUuid& entityID, const QUuid& actionID); + + + /**jsdoc + * Get the translation of a joint in a {@link Entities.EntityType|Model} entity relative to the entity's position and + * orientation. + * @function Entities.getAbsoluteJointTranslationInObjectFrame + * @param {Uuid} entityID - The ID of the entity. + * @param {number} jointIndex - The integer index of the joint. + * @returns {Vec3} The translation of the joint relative to the entity's position and orientation if the entity is a + * {@link Entities.EntityType|Model} entity, the entity is loaded, and the joint index is valid; otherwise + * {@link Vec3(0)|Vec3.ZERO}. + */ // FIXME move to a renderable entity interface Q_INVOKABLE glm::vec3 getAbsoluteJointTranslationInObjectFrame(const QUuid& entityID, int jointIndex); + + /**jsdoc + * Get the translation of a joint in a {@link Entities.EntityType|Model} entity relative to the entity's position and + * orientation. + * @function Entities.getAbsoluteJointRotationInObjectFrame + * @param {Uuid} entityID - The ID of the entity. + * @param {number} jointIndex - The integer index of the joint. + * @returns {Quat} The rotation of the joint relative to the entity's orientation if the entity is a + * {@link Entities.EntityType|Model} entity, the entity is loaded, and the joint index is valid; otherwise + * {@link Quat(0)|Quat.IDENTITY}. + * @example Compare the local and absolute rotations of an avatar model's left hand joint. + * entityID = Entities.addEntity({ + * type: "Model", + * modelURL: "https://hifi-content.s3.amazonaws.com/milad/production/Examples/Models/Avatars/blue_suited.fbx", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })), + * rotation: MyAvatar.orientation, + * lifetime: 300 // Delete after 5 minutes. + * }); + * + * Script.setTimeout(function () { + * // Joint data aren't available until after the model has loaded. + * var index = Entities.getJointIndex(entityID, "LeftHand"); + * var localRotation = Entities.getLocalJointRotation(entityID, index); + * var absoluteRotation = Entities.getAbsoluteJointRotationInObjectFrame(entityID, index); + * print("Left hand local rotation: " + JSON.stringify(Quat.safeEulerAngles(localRotation))); + * print("Left hand absolute rotation: " + JSON.stringify(Quat.safeEulerAngles(absoluteRotation))); + * }, 2000); + */ + // FIXME move to a renderable entity interface Q_INVOKABLE glm::quat getAbsoluteJointRotationInObjectFrame(const QUuid& entityID, int jointIndex); + + /**jsdoc + * Set the translation of a joint in a {@link Entities.EntityType|Model} entity relative to the entity's position and + * orientation. + * @function Entities.setAbsoluteJointTranslationInObjectFrame + * @param {Uuid} entityID - The ID of the entity. + * @param {number} jointIndex - The integer index of the joint. + * @param {Vec3} translation - The translation to set the joint to relative to the entity's position and orientation. + * @returns {boolean} trueif the entity is a {@link Entities.EntityType|Model} entity, the entity is loaded, + * the joint index is valid, and the translation is different to the joint's current translation; otherwise + * false. + */ + // FIXME move to a renderable entity interface Q_INVOKABLE bool setAbsoluteJointTranslationInObjectFrame(const QUuid& entityID, int jointIndex, glm::vec3 translation); + + /**jsdoc + * Set the rotation of a joint in a {@link Entities.EntityType|Model} entity relative to the entity's position and + * orientation. + * @function Entities.setAbsoluteJointRotationInObjectFrame + * @param {Uuid} entityID - The ID of the entity. + * @param {number} jointIndex - The integer index of the joint. + * @param {Quat} rotation - The rotation to set the joint to relative to the entity's orientation. + * @returns {boolean} true if the entity is a {@link Entities.EntityType|Model} entity, the entity is loaded, + * the joint index is valid, and the rotation is different to the joint's current rotation; otherwise false. + * @example Raise an avatar model's left palm. + * entityID = Entities.addEntity({ + * type: "Model", + * modelURL: "https://hifi-content.s3.amazonaws.com/milad/production/Examples/Models/Avatars/blue_suited.fbx", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })), + * rotation: MyAvatar.orientation, + * lifetime: 300 // Delete after 5 minutes. + * }); + * + * Script.setTimeout(function () { + * // Joint data aren't available until after the model has loaded. + * var index = Entities.getJointIndex(entityID, "LeftHand"); + * var absoluteRotation = Entities.getAbsoluteJointRotationInObjectFrame(entityID, index); + * absoluteRotation = Quat.multiply(Quat.fromPitchYawRollDegrees(0, 0, 90), absoluteRotation); + * var success = Entities.setAbsoluteJointRotationInObjectFrame(entityID, index, absoluteRotation); + * print("Success: " + success); + * }, 2000); + */ + // FIXME move to a renderable entity interface Q_INVOKABLE bool setAbsoluteJointRotationInObjectFrame(const QUuid& entityID, int jointIndex, glm::quat rotation); + + /**jsdoc + * Get the local translation of a joint in a {@link Entities.EntityType|Model} entity. + * @function Entities.getLocalJointTranslation + * @param {Uuid} entityID - The ID of the entity. + * @param {number} jointIndex - The integer index of the joint. + * @returns {Vec3} The local translation of the joint if the entity is a {@link Entities.EntityType|Model} entity, the + * entity is loaded, and the joint index is valid; otherwise {@link Vec3(0)|Vec3.ZERO}. + */ // FIXME move to a renderable entity interface Q_INVOKABLE glm::vec3 getLocalJointTranslation(const QUuid& entityID, int jointIndex); + + /**jsdoc + * Get the local rotation of a joint in a {@link Entities.EntityType|Model} entity. + * @function Entities.getLocalJointRotation + * @param {Uuid} entityID - The ID of the entity. + * @param {number} jointIndex - The integer index of the joint. + * @returns {Quat} The local rotation of the joint if the entity is a {@link Entities.EntityType|Model} entity, the entity + * is loaded, and the joint index is valid; otherwise {@link Quat(0)|Quat.IDENTITY}. + * @example Report the local rotation of an avatar model's head joint. + * entityID = Entities.addEntity({ + * type: "Model", + * modelURL: "https://hifi-content.s3.amazonaws.com/milad/production/Examples/Models/Avatars/blue_suited.fbx", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })), + * rotation: MyAvatar.orientation, + * lifetime: 300 // Delete after 5 minutes. + * }); + * + * Script.setTimeout(function () { + * // Joint data aren't available until after the model has loaded. + * var index = Entities.getJointIndex(entityID, "Head"); + * var rotation = Entities.getLocalJointRotation(entityID, index); + * print("Head local rotation: " + JSON.stringify(Quat.safeEulerAngles(rotation))); + * }, 2000); + */ + // FIXME move to a renderable entity interface Q_INVOKABLE glm::quat getLocalJointRotation(const QUuid& entityID, int jointIndex); + + /**jsdoc + * Set the local translation of a joint in a {@link Entities.EntityType|Model} entity. + * @function Entities.setLocalJointTranslation + * @param {Uuid} entityID - The ID of the entity. + * @param {number} jointIndex - The integer index of the joint. + * @param {Vec3} translation - The local translation to set the joint to. + * @returns {boolean} trueif the entity is a {@link Entities.EntityType|Model} entity, the entity is loaded, + * the joint index is valid, and the translation is different to the joint's current translation; otherwise + * false. + */ + // FIXME move to a renderable entity interface Q_INVOKABLE bool setLocalJointTranslation(const QUuid& entityID, int jointIndex, glm::vec3 translation); + + /**jsdoc + * Set the local rotation of a joint in a {@link Entities.EntityType|Model} entity. + * @function Entities.setLocalJointRotation + * @param {Uuid} entityID - The ID of the entity. + * @param {number} jointIndex - The integer index of the joint. + * @param {Quat} rotation - The local rotation to set the joint to. + * @returns {boolean} true if the entity is a {@link Entities.EntityType|Model} entity, the entity is loaded, + * the joint index is valid, and the rotation is different to the joint's current rotation; otherwise false. + * @example Make an avatar model turn its head left. + * entityID = Entities.addEntity({ + * type: "Model", + * modelURL: "https://hifi-content.s3.amazonaws.com/milad/production/Examples/Models/Avatars/blue_suited.fbx", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })), + * rotation: MyAvatar.orientation, + * lifetime: 300 // Delete after 5 minutes. + * }); + * + * Script.setTimeout(function () { + * // Joint data aren't available until after the model has loaded. + * var index = Entities.getJointIndex(entityID, "Head"); + * var rotation = Quat.fromPitchYawRollDegrees(0, 60, 0); + * var success = Entities.setLocalJointRotation(entityID, index, rotation); + * print("Success: " + success); + * }, 2000); + */ + // FIXME move to a renderable entity interface Q_INVOKABLE bool setLocalJointRotation(const QUuid& entityID, int jointIndex, glm::quat rotation); + + /**jsdoc + * Set the local translations of joints in a {@link Entities.EntityType|Model} entity. + * @function Entities.setLocalJointTranslations + * @param {Uuid} entityID - The ID of the entity. + * @param {Vec3[]} translations - The local translations to set the joints to. + * @returns {boolean} trueif the entity is a {@link Entities.EntityType|Model} entity, the entity is loaded, + * the model has joints, and at least one of the translations is different to the model's current translations; + * otherwise false. + */ + // FIXME move to a renderable entity interface + Q_INVOKABLE bool setLocalJointTranslations(const QUuid& entityID, const QVector& translations); + + /**jsdoc + * Set the local rotations of joints in a {@link Entities.EntityType|Model} entity. + * @function Entities.setLocalJointRotations + * @param {Uuid} entityID - The ID of the entity. + * @param {Quat[]} rotations - The local rotations to set the joints to. + * @returns {boolean} true if the entity is a {@link Entities.EntityType|Model} entity, the entity is loaded, + * the model has joints, and at least one of the rotations is different to the model's current rotations; otherwise + * false. + * @example Raise both palms of an avatar model. + * entityID = Entities.addEntity({ + * type: "Model", + * modelURL: "https://hifi-content.s3.amazonaws.com/milad/production/Examples/Models/Avatars/blue_suited.fbx", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })), + * rotation: MyAvatar.orientation, + * lifetime: 300 // Delete after 5 minutes. + * }); + * + * Script.setTimeout(function () { + * // Joint data aren't available until after the model has loaded. + * + * // Get all the joint rotations. + * var jointNames = Entities.getJointNames(entityID); + * var jointRotations = []; + * for (var i = 0, length = jointNames.length; i < length; i++) { + * var index = Entities.getJointIndex(entityID, jointNames[i]); + * jointRotations.push(Entities.getLocalJointRotation(entityID, index)); + * } + * + * // Raise both palms. + * var index = jointNames.indexOf("LeftHand"); + * jointRotations[index] = Quat.multiply(Quat.fromPitchYawRollDegrees(-90, 0, 0), jointRotations[index]); + * index = jointNames.indexOf("RightHand"); + * jointRotations[index] = Quat.multiply(Quat.fromPitchYawRollDegrees(-90, 0, 0), jointRotations[index]); + * + * // Update all the joint rotations. + * var success = Entities.setLocalJointRotations(entityID, jointRotations); + * print("Success: " + success); + * }, 2000); + */ // FIXME move to a renderable entity interface Q_INVOKABLE bool setLocalJointRotations(const QUuid& entityID, const QVector& rotations); - Q_INVOKABLE bool setLocalJointTranslations(const QUuid& entityID, const QVector& translations); + + /**jsdoc + * Set the local rotations and translations of joints in a {@link Entities.EntityType|Model} entity. This is the same as + * calling both {@link Entities.setLocalJointRotations|setLocalJointRotations} and + * {@link Entities.setLocalJointTranslations|setLocalJointTranslations} at the same time. + * @function Entities.setLocalJointsData + * @param {Uuid} entityID - The ID of the entity. + * @param {Quat[]} rotations - The local rotations to set the joints to. + * @param {Vec3[]} translations - The local translations to set the joints to. + * @returns {boolean} true if the entity is a {@link Entities.EntityType|Model} entity, the entity is loaded, + * the model has joints, and at least one of the rotations or translations is different to the model's current values; + * otherwise false. + */ + // FIXME move to a renderable entity interface Q_INVOKABLE bool setLocalJointsData(const QUuid& entityID, const QVector& rotations, const QVector& translations); + + /**jsdoc + * Get the index of a named joint in a {@link Entities.EntityType|Model} entity. + * @function Entities.getJointIndex + * @param {Uuid} entityID - The ID of the entity. + * @param {string} name - The name of the joint. + * @returns {number} The integer index of the joint if the entity is a {@link Entities.EntityType|Model} entity, the entity + * is loaded, and the joint is present; otherwise -1. The joint indexes are in order per + * {@link Entities.getJointNames|getJointNames}. + * @example Report the index of a model's head joint. + * entityID = Entities.addEntity({ + * type: "Model", + * modelURL: "https://hifi-content.s3.amazonaws.com/milad/production/Examples/Models/Avatars/blue_suited.fbx", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })), + * rotation: MyAvatar.orientation, + * lifetime: 300 // Delete after 5 minutes. + * }); + * + * Script.setTimeout(function () { + * // Joint data aren't available until after the model has loaded. + * var index = Entities.getJointIndex(entityID, "Head"); + * print("Head joint index: " + index); + * }, 2000); + */ // FIXME move to a renderable entity interface Q_INVOKABLE int getJointIndex(const QUuid& entityID, const QString& name); + + /**jsdoc + * Get the names of all the joints in a {@link Entities.EntityType|Model} entity. + * @function Entities.getJointNames + * @param {Uuid} entityID - The ID of the {@link Entities.EntityType|Model} entity. + * @returns {string[]} The names of all the joints in the entity if it is a {@link Entities.EntityType|Model} entity and + * is loaded, otherwise an empty array. The joint names are in order per {@link Entities.getJointIndex|getJointIndex}. + * @example Report a model's joint names. + * entityID = Entities.addEntity({ + * type: "Model", + * modelURL: "https://hifi-content.s3.amazonaws.com/milad/production/Examples/Models/Avatars/blue_suited.fbx", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })), + * rotation: MyAvatar.orientation, + * lifetime: 300 // Delete after 5 minutes. + * }); + * + * Script.setTimeout(function () { + * // Joint data aren't available until after the model has loaded. + * var jointNames = Entities.getJointNames(entityID); + * print("Joint names: " + JSON.stringify(jointNames)); + * }, 2000); + */ + // FIXME move to a renderable entity interface Q_INVOKABLE QStringList getJointNames(const QUuid& entityID); + /**jsdoc + * Get the IDs of entities, overlays, and avatars that are directly parented to an entity. To get all descendants of an + * entity, recurse on the IDs returned by the function. + * @function Entities.getChildrenIDs + * @param {Uuid} parentID - The ID of the entity to get the children IDs of. + * @returns {Uuid[]} An array of entity, overlay, and avatar IDs that are parented directly to the parentID + * entity. Does not include children's children, etc. The array is empty if no children can be found or + * parentID cannot be found. + * @example Report the children of an entity. + * function createEntity(description, position, parent) { + * var entity = Entities.addEntity({ + * type: "Sphere", + * position: position, + * dimensions: Vec3.HALF, + * parentID: parent, + * lifetime: 300 // Delete after 5 minutes. + * }); + * print(description + ": " + entity); + * return entity; + * } + * + * var position = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 2, z: -5 })); + * var root = createEntity("Root", position, Uuid.NULL); + * var child = createEntity("Child", Vec3.sum(position, { x: 0, y: -1, z: 0 }), root); + * var grandChild = createEntity("Grandchild", Vec3.sum(position, { x: 0, y: -2, z: 0 }), child); + * + * var children = Entities.getChildrenIDs(root); + * print("Children of root: " + JSON.stringify(children)); // Only the child entity. + */ Q_INVOKABLE QVector getChildrenIDs(const QUuid& parentID); + + /**jsdoc + * Get the IDs of entities, overlays, and avatars that are directly parented to an entity, overlay, or avatar model's joint. + * @function Entities.getChildrenIDsOfJoint + * @param {Uuid} parentID - The ID of the entity, overlay, or avatar to get the children IDs of. + * @param {number} jointIndex - Integer number of the model joint to get the children IDs of. + * @returns {Uuid[]} An array of entity, overlay, and avatar IDs that are parented directly to the parentID + * entity, overlay, or avatar at the jointIndex joint. Does not include children's children, etc. The + * array is empty if no children can be found or parentID cannot be found. + * @example Report the children of your avatar's right hand. + * function createEntity(description, position, parent) { + * var entity = Entities.addEntity({ + * type: "Sphere", + * position: position, + * dimensions: Vec3.HALF, + * parentID: parent, + * lifetime: 300 // Delete after 5 minutes. + * }); + * print(description + ": " + entity); + * return entity; + * } + * + * var position = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 2, z: -5 })); + * var root = createEntity("Root", position, Uuid.NULL); + * var child = createEntity("Child", Vec3.sum(position, { x: 0, y: -1, z: 0 }), root); + * + * Entities.editEntity(root, { + * parentID: MyAvatar.sessionUUID, + * parentJointIndex: MyAvatar.getJointIndex("RightHand") + * }); + * + * var children = Entities.getChildrenIDsOfJoint(MyAvatar.sessionUUID, MyAvatar.getJointIndex("RightHand")); + * print("Children of hand: " + JSON.stringify(children)); // Only the root entity. + */ Q_INVOKABLE QVector getChildrenIDsOfJoint(const QUuid& parentID, int jointIndex); + + /**jsdoc + * Check whether an entity or overlay has an entity as an ancestor (parent, parent's parent, etc.). + * @function Entities.isChildOfParent + * @param {Uuid} childID - The ID of the child entity or overlay to test for being a child, grandchild, etc. + * @param {Uuid} parentID - The ID of the parent entity to test for being a parent, grandparent, etc. + * @returns {boolean} true if the childID entity or overlay has the parentID entity + * as a parent or grandparent etc., otherwise false. + * @example Check that a grandchild entity is a child of its grandparent. + * function createEntity(description, position, parent) { + * var entity = Entities.addEntity({ + * type: "Sphere", + * position: position, + * dimensions: Vec3.HALF, + * parentID: parent, + * lifetime: 300 // Delete after 5 minutes. + * }); + * print(description + ": " + entity); + * return entity; + * } + * + * var position = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 2, z: -5 })); + * var root = createEntity("Root", position, Uuid.NULL); + * var child = createEntity("Child", Vec3.sum(position, { x: 0, y: -1, z: 0 }), root); + * var grandChild = createEntity("Grandchild", Vec3.sum(position, { x: 0, y: -2, z: 0 }), child); + * + * print("grandChild has root as parent: " + Entities.isChildOfParent(grandChild, root)); // true + */ Q_INVOKABLE bool isChildOfParent(QUuid childID, QUuid parentID); - Q_INVOKABLE QString getNestableType(QUuid id); + /**jsdoc + * Get the type — entity, overlay, or avatar — of an in-world item. + * @function Entities.getNestableType + * @param {Uuid} entityID - The ID of the item to get the type of. + * @returns {string} The type of the item: "entity" if the item is an entity, "overlay" if the + * the item is an overlay, "avatar" if the item is an avatar; otherwise "unknown" if the item + * cannot be found. + * @example Print some nestable types. + * var entity = Entities.addEntity({ + * type: "Sphere", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 1, z: -2 })), + * lifetime: 300 // Delete after 5 minutes. + * }); + * + * print(Entities.getNestableType(entity)); // "entity" + * print(Entities.getNestableType(Uuid.generate())); // "unknown" + */ + Q_INVOKABLE QString getNestableType(QUuid entityID); + /**jsdoc + * Get the ID of the {@link Entities.EntityType|Web} entity that has keyboard focus. + * @function Entities.getKeyboardFocusEntity + * @returns {Uuid} The ID of the {@link Entities.EntityType|Web} entity that has focus, if any, otherwise null. + */ Q_INVOKABLE QUuid getKeyboardFocusEntity() const; + + /**jsdoc + * Set the {@link Entities.EntityType|Web} entity that has keyboard focus. + * @function Entities.setKeyboardFocusEntity + * @param {Uuid} entityID - The ID of the {@link Entities.EntityType|Web} entity to set keyboard focus to. Use + * null or {@link Uuid|Uuid.NULL} to unset keyboard focus from an entity. + */ Q_INVOKABLE void setKeyboardFocusEntity(const EntityItemID& id); + + /**jsdoc + * Emit a {@link Entities.mousePressOnEntity|mousePressOnEntity} event. + * @function Entities.sendMousePressOnEntity + * @param {Uuid} entityID - The ID of the entity to emit the event for. + * @param {PointerEvent} event - The event details. + */ Q_INVOKABLE void sendMousePressOnEntity(const EntityItemID& id, const PointerEvent& event); + + /**jsdoc + * Emit a {@link Entities.mouseMoveOnEntity|mouseMoveOnEntity} event. + * @function Entities.sendMouseMoveOnEntity + * @param {Uuid} entityID - The ID of the entity to emit the event for. + * @param {PointerEvent} event - The event details. + */ Q_INVOKABLE void sendMouseMoveOnEntity(const EntityItemID& id, const PointerEvent& event); + + /**jsdoc + * Emit a {@link Entities.mouseReleaseOnEntity|mouseReleaseOnEntity} event. + * @function Entities.sendMouseReleaseOnEntity + * @param {Uuid} entityID - The ID of the entity to emit the event for. + * @param {PointerEvent} event - The event details. + */ Q_INVOKABLE void sendMouseReleaseOnEntity(const EntityItemID& id, const PointerEvent& event); + /**jsdoc + * Emit a {@link Entities.clickDownOnEntity|clickDownOnEntity} event. + * @function Entities.sendClickDownOnEntity + * @param {Uuid} entityID - The ID of the entity to emit the event for. + * @param {PointerEvent} event - The event details. + */ Q_INVOKABLE void sendClickDownOnEntity(const EntityItemID& id, const PointerEvent& event); + + /**jsdoc + * Emit a {@link Entities.holdingClickOnEntity|holdingClickOnEntity} event. + * @function Entities.sendHoldingClickOnEntity + * @param {Uuid} entityID - The ID of the entity to emit the event for. + * @param {PointerEvent} event - The event details. + */ Q_INVOKABLE void sendHoldingClickOnEntity(const EntityItemID& id, const PointerEvent& event); + + /**jsdoc + * Emit a {@link Entities.clickReleaseOnEntity|clickReleaseOnEntity} event. + * @function Entities.sendClickReleaseOnEntity + * @param {Uuid} entityID - The ID of the entity to emit the event for. + * @param {PointerEvent} event - The event details. + */ Q_INVOKABLE void sendClickReleaseOnEntity(const EntityItemID& id, const PointerEvent& event); + /**jsdoc + * Emit a {@link Entities.hoverEnterEntity|hoverEnterEntity} event. + * @function Entities.sendHoverEnterEntity + * @param {Uuid} entityID - The ID of the entity to emit the event for. + * @param {PointerEvent} event - The event details. + */ Q_INVOKABLE void sendHoverEnterEntity(const EntityItemID& id, const PointerEvent& event); + + /**jsdoc + * Emit a {@link Entities.hoverOverEntity|hoverOverEntity} event. + * @function Entities.sendHoverOverEntity + * @param {Uuid} entityID - The ID of the entity to emit the event for. + * @param {PointerEvent} event - The event details. + */ Q_INVOKABLE void sendHoverOverEntity(const EntityItemID& id, const PointerEvent& event); + + /**jsdoc + * Emit a {@link Entities.hoverLeaveEntity|hoverLeaveEntity} event. + * @function Entities.sendHoverLeaveEntity + * @param {Uuid} entityID - The ID of the entity to emit the event for. + * @param {PointerEvent} event - The event details. + */ Q_INVOKABLE void sendHoverLeaveEntity(const EntityItemID& id, const PointerEvent& event); + /**jsdoc + * Check whether an entity wants hand controller pointer events. For example, a {@link Entities.EntityType|Web} entity does + * but a {@link Entities.EntityType|Shape} entity doesn't. + * @function Entities.wantsHandControllerPointerEvents + * @param {Uuid} entityID - The ID of the entity. + * @returns {boolean} true if the entity can be found and it wants hand controller pointer events, otherwise + * false. + */ Q_INVOKABLE bool wantsHandControllerPointerEvents(QUuid id); + /**jsdoc + * Send a script event over a {@link Entities.EntityType|Web} entity's EventBridge to the Web page's scripts. + * @function Entities.emitScriptEvent + * @param {Uuid} entityID - The ID of the {@link Entities.EntityType|Web} entity. + * @param {string} message - The message to send. + * @todo This function is currently not implemented. + */ Q_INVOKABLE void emitScriptEvent(const EntityItemID& entityID, const QVariant& message); + /**jsdoc + * Check whether an axis-aligned box and a capsule intersect. + * @function Entities.AABoxIntersectsCapsule + * @param {Vec3} brn - The bottom right near (minimum axes values) corner of the AA box. + * @param {Vec3} dimensions - The dimensions of the AA box. + * @param {Vec3} start - One end of the capsule. + * @param {Vec3} end - The other end of the capsule. + * @param {number} radius - The radiues of the capsule. + * @returns {boolean} true if the AA box and capsule intersect, otherwise false. + */ Q_INVOKABLE bool AABoxIntersectsCapsule(const glm::vec3& low, const glm::vec3& dimensions, const glm::vec3& start, const glm::vec3& end, float radius); + /**jsdoc + * Get the meshes in a {@link Entities.EntityType|Model} or {@link Entities.EntityType|PolyVox} entity. + * @function Entities.getMeshes + * @param {Uuid} entityID - The ID of the Model or PolyVox entity to get the meshes of. + * @param {Entities~getMeshesCallback} callback - The function to call upon completion. + * @deprecated Use the {@link Graphics} API instead. + */ + /**jsdoc + * Called when {@link Entities.getMeshes} is complete. + * @callback Entities~getMeshesCallback + * @param {MeshProxy[]} meshes - If success< is true, a {@link MeshProxy} per mesh in the + * Model or PolyVox entity; otherwise undefined. + * @param {boolean} success - true if the {@link Entities.getMeshes} call was successful, false + * otherwise. The call may be unsuccessful if the requested entity could not be found. + * @deprecated Use the {@link Graphics} API instead. + */ // FIXME move to a renderable entity interface Q_INVOKABLE void getMeshes(QUuid entityID, QScriptValue callback); /**jsdoc - * Returns object to world transform, excluding scale - * + * Get the object to world transform, excluding scale, of an entity. * @function Entities.getEntityTransform - * @param {EntityID} entityID The ID of the entity whose transform is to be returned - * @return {Mat4} Entity's object to world transform, excluding scale + * @param {Uuid} entityID - The ID of the entity. + * @returns {Mat4} The entity's object to world transform excluding scale (i.e., translation and rotation, with scale of 1) + * if the entity can be found, otherwise a transform with zero translation and rotation and a scale of 1. + * @example Position and rotation in an entity's world transform. + * var position = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 1, z: -2 })); + * var orientation = MyAvatar.orientation; + * print("Position: " + JSON.stringify(position)); + * print("Orientation: " + JSON.stringify(orientation)); + * + * var entityID = Entities.addEntity({ + * type: "Sphere", + * position: position, + * rotation: orientation, + * dimensions: Vec3.HALF, + * lifetime: 300 // Delete after 5 minutes. + * }); + * + * var transform = Entities.getEntityTransform(entityID); + * print("Transform: " + JSON.stringify(transform)); + * print("Translation: " + JSON.stringify(Mat4.extractTranslation(transform))); // Same as position. + * print("Rotation: " + JSON.stringify(Mat4.extractRotation(transform))); // Same as orientation. + * print("Scale: " + JSON.stringify(Mat4.extractScale(transform))); // { x: 1, y: 1, z: 1 } */ Q_INVOKABLE glm::mat4 getEntityTransform(const QUuid& entityID); - /**jsdoc - * Returns object to world transform, excluding scale - * + * Get the object to parent transform, excluding scale, of an entity. * @function Entities.getEntityLocalTransform - * @param {EntityID} entityID The ID of the entity whose local transform is to be returned - * @return {Mat4} Entity's object to parent transform, excluding scale - */ + * @param {Uuid} entityID - The ID of the entity. + * @returns {Mat4} The entity's object to parent transform excluding scale (i.e., translation and rotation, with scale of + * 1) if the entity can be found, otherwise a transform with zero translation and rotation and a scale of 1. + * @example Position and rotation in an entity's local transform. + * function createEntity(position, rotation, parent) { + * var entity = Entities.addEntity({ + * type: "Box", + * position: position, + * rotation: rotation, + * dimensions: Vec3.HALF, + * parentID: parent, + * lifetime: 300 // Delete after 5 minutes. + * }); + * return entity; + * } + * + * var position = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 2, z: -5 })); + * + * var parent = createEntity(position, MyAvatar.orientation, Uuid.NULL); + * + * var childTranslation = { x: 0, y: -1.5, z: 0 }; + * var childRotation = Quat.fromPitchYawRollDegrees(0, 45, 0); + * var child = createEntity(Vec3.sum(position, childTranslation), Quat.multiply(childRotation, MyAvatar.orientation), parent); + * + * var transform = Entities.getEntityLocalTransform(child); + * print("Transform: " + JSON.stringify(transform)); + * print("Translation: " + JSON.stringify(Mat4.extractTranslation(transform))); // childTranslation + * print("Rotation: " + JSON.stringify(Quat.safeEulerAngles(Mat4.extractRotation(transform)))); // childRotation + * print("Scale: " + JSON.stringify(Mat4.extractScale(transform))); // { x: 1, y: 1, z: 1 } */ Q_INVOKABLE glm::mat4 getEntityLocalTransform(const QUuid& entityID); - /**jsdoc - * Return the Static Certificate JSON for the specified {EntityID}. - * @return {QByteArray} The Static Certificate JSON for the specified entity. + * Get the static certificate for an entity. The static certificate contains static properties of the item which cannot + * be altered. + * @function Entities.getStaticCertificateJSON + * @param {Uuid} entityID - The ID of the entity to get the static certificate for. + * @returns {string} The entity's static certificate as a JSON string if the entity can be found, otherwise an empty string. */ Q_INVOKABLE QString getStaticCertificateJSON(const QUuid& entityID); + + /**jsdoc + * Verify the entity's proof of provenance, i.e., that the entity's certificateID property was produced by + * High Fidelity signing the entity's static certificate JSON. + * @function Entities.verifyStaticCertificateProperties + * @param {Uuid} entityID - The ID of the entity to verify. + * @returns {boolean} true if the entity can be found an its certificateID property is present + * and its value matches the entity's static certificate JSON; otherwise false. + */ Q_INVOKABLE bool verifyStaticCertificateProperties(const QUuid& entityID); signals: + /**jsdoc + * Triggered on the client that is the physics simulation owner during the collision of two entities. Note: Isn't triggered + * for a collision with an avatar. + * @function Entities.collisionWithEntity + * @param {Uuid} idA - The ID of one entity in the collision. For an entity script, this is the ID of the entity containing + * the script. + * @param {Uuid} idB - The ID of the other entity in the collision. + * @param {Collision} collision - The details of the collision. + * @returns {Signal} + * @example Change the color of an entity when it collides with another entity. + * var entityScript = (function () { + * function randomInteger(min, max) { + * return Math.floor(Math.random() * (max - min + 1)) + min; + * } + * + * this.collisionWithEntity = function (myID, otherID, collision) { + * Entities.editEntity(myID, { + * color: { + * red: randomInteger(128, 255), + * green: randomInteger(128, 255), + * blue: randomInteger(128, 255) + * } + * }); + * }; + * }); + * + * var entityID = Entities.addEntity({ + * type: "Box", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })), + * dimensions: { x: 0.5, y: 0.5, z: 0.5 }, + * color: { red: 128, green: 128, blue: 128 }, + * gravity: { x: 0, y: -9.8, z: 0 }, + * velocity: { x: 0, y: 0.1, z: 0 }, // Kick off physics. + * dynamic: true, + * collisionless: false, // So that collision events are generated. + * script: "(" + entityScript + ")", // Could host the script on a Web server instead. + * lifetime: 300 // Delete after 5 minutes. + * }); + */ void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); + /**jsdoc + * Triggered when your ability to change the locked property of entities changes. + * @function Entities.canAdjustLocksChanged + * @param {boolean} canAdjustLocks - true if the script can change the locked property of an + * entity, otherwise false. + * @returns {Signal} + * @example Report when your ability to change locks changes. + * function onCanAdjustLocksChanged(canAdjustLocks) { + * print("You can adjust entity locks: " + canAdjustLocks); + * } + * Entities.canAdjustLocksChanged.connect(onCanAdjustLocksChanged); + */ void canAdjustLocksChanged(bool canAdjustLocks); + + /**jsdoc + * Triggered when your ability to rez (create) entities changes. + * @function Entities.canRezChanged + * @param {boolean} canRez - true if the script can rez (create) entities, otherwise false. + * @returns {Signal} + */ void canRezChanged(bool canRez); - void canRezTmpChanged(bool canRez); - void canRezCertifiedChanged(bool canRez); - void canRezTmpCertifiedChanged(bool canRez); + + /**jsdoc + * Triggered when your ability to rez (create) temporary entities changes. Temporary entities are entities with a finite + * lifetime property value set. + * @function Entities.canRezTmpChanged + * @param {boolean} canRezTmp - true if the script can rez (create) temporary entities, otherwise + * false. + * @returns {Signal} + */ + void canRezTmpChanged(bool canRezTmp); + + /**jsdoc + * Triggered when your ability to rez (create) certified entities changes. Certified entities are entities that have PoP + * certificates. + * @function Entities.canRezCertifiedChanged + * @param {boolean} canRezCertified - true if the script can rez (create) certified entities, otherwise + * false. + * @returns {Signal} + */ + void canRezCertifiedChanged(bool canRezCertified); + + /**jsdoc + * Triggered when your ability to rez (create) temporary certified entities changes. Temporary entities are entities with a + * finite lifetime property value set. Certified entities are entities that have PoP certificates. + * @function Entities.canRezTmpCertifiedChanged + * @param {boolean} canRezTmpCertified - true if the script can rez (create) temporary certified entities, + * otherwise false. + * @returns {Signal} + */ + void canRezTmpCertifiedChanged(bool canRezTmpCertified); + + /**jsdoc + * Triggered when your ability to make changes to the asset server's assets changes. + * @function Entities.canWriteAssetsChanged + * @param {boolean} canWriteAssets - true if the script can change the ? property of an entity, + * otherwise false. + * @returns {Signal} + */ void canWriteAssetsChanged(bool canWriteAssets); + + /**jsdoc + * Triggered when a mouse button is clicked while the mouse cursor is on an entity, or a controller trigger is fully + * pressed while its laser is on an entity. + * @function Entities.mousePressOnEntity + * @param {Uuid} entityID - The ID of the entity that was pressed. + * @param {PointerEvent} event - Details of the event. + * @returns {Signal} + * @example Report when an entity is clicked with the mouse or laser. + * function onMousePressOnEntity(entityID, event) { + * print("Clicked on entity: " + entityID); + * } + * + * Entities.mousePressOnEntity.connect(onMousePressOnEntity); + */ void mousePressOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); + + /**jsdoc + * Triggered when a mouse button is double-clicked while the mouse cursor is on an entity. + * @function Entities.mousePressOnEntity + * @param {Uuid} entityID - The ID of the entity that was double-pressed. + * @param {PointerEvent} event - Details of the event. + * @returns {Signal} + */ void mouseDoublePressOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); + + /**jsdoc + * Repeatedly triggered while the mouse cursor or controller laser moves on an entity. + * @function Entities.mouseMoveOnEntity + * @param {Uuid} entityID - The ID of the entity that was moved on. + * @param {PointerEvent} event - Details of the event. + * @returns {Signal} + */ void mouseMoveOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); + + /**jsdoc + * Triggered when a mouse button is released after clicking on an entity or the controller trigger is partly or fully + * released after pressing on an entity, even if the mouse pointer or controller laser has moved off the entity. + * @function Entities.mouseReleaseOnEntity + * @param {Uuid} entityID - The ID of the entity that was originally pressed. + * @param {PointerEvent} event - Details of the event. + * @returns {Signal} + */ void mouseReleaseOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); + + /**jsdoc + * Triggered when a mouse button is clicked while the mouse cursor is not on an entity. + * @function Entities.mousePressOffEntity + * @param {PointerEvent} event - Details of the event. + * @returns {Signal} + */ void mousePressOffEntity(); + + /**jsdoc + * Triggered when a mouse button is double-clicked while the mouse cursor is not on an entity. + * @function Entities.mouseDoublePressOffEntity + * @param {PointerEvent} event - Details of the event. + * @returns {Signal} + */ void mouseDoublePressOffEntity(); + + /**jsdoc + * Triggered when a mouse button is clicked while the mouse cursor is on an entity. Note: Not triggered by controller. + * @function Entities.clickDownOnEntity + * @param {Uuid} entityID - The ID of the entity that was clicked. + * @param {PointerEvent} event - Details of the event. + * @returns {Signal} + */ void clickDownOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); + + /**jsdoc + * Repeatedly triggered while a mouse button continues to be held after clicking an entity, even if the mouse cursor has + * moved off the entity. Note: Not triggered by controller. + * @function Entities.holdingClickOnEntity + * @param {Uuid} entityID - The ID of the entity that was originally clicked. + * @param {PointerEvent} event - Details of the event. + * @returns {Signal} + */ void holdingClickOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); + + /**jsdoc + * Triggered when a mouse button is released after clicking on an entity, even if the mouse cursor has moved off the + * entity. Note: Not triggered by controller. + * @function Entities.clickReleaseOnEntity + * @param {Uuid} entityID - The ID of the entity that was originally clicked. + * @param {PointerEvent} event - Details of the event. + * @returns {Signal} + */ void clickReleaseOnEntity(const EntityItemID& entityItemID, const PointerEvent& event); + /**jsdoc + * Triggered when the mouse cursor or controller laser starts hovering on an entity. + * @function Entities.hoverEnterEntity + * @param {Uuid} entityID - The ID of the entity that is being hovered. + * @param {PointerEvent} event - Details of the event. + * @returns {Signal} + */ void hoverEnterEntity(const EntityItemID& entityItemID, const PointerEvent& event); + + /**jsdoc + * Repeatedly triggered when the mouse cursor or controller laser moves while hovering over an entity. + * @function Entities.hoverOverEntity + * @param {Uuid} entityID - The ID of the entity that is being hovered. + * @param {PointerEvent} event - Details of the event. + * @returns {Signal} + */ void hoverOverEntity(const EntityItemID& entityItemID, const PointerEvent& event); + + /**jsdoc + * Triggered when the mouse cursor or controller laser stops hovering over an entity. + * @function Entities.hoverLeaveEntity + * @param {Uuid} entityID - The ID of the entity that was being hovered. + * @param {PointerEvent} event - Details of the event. + * @returns {Signal} + */ void hoverLeaveEntity(const EntityItemID& entityItemID, const PointerEvent& event); + + /**jsdoc + * Triggered when an avatar enters an entity. + * @function Entities.enterEntity + * @param {Uuid} entityID - The ID of the entity that the avatar entered. + * @returns {Signal} + * @example Change the color of an entity when an avatar enters or leaves. + * var entityScript = (function () { + * this.enterEntity = function (entityID) { + * print("Enter entity"); + * Entities.editEntity(entityID, { + * color: { red: 255, green: 64, blue: 64 }, + * }); + * }; + * this.leaveEntity = function (entityID) { + * print("Leave entity"); + * Entities.editEntity(entityID, { + * color: { red: 128, green: 128, blue: 128 }, + * }); + * }; + * }); + * + * var entityID = Entities.addEntity({ + * type: "Sphere", + * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })), + * dimensions: { x: 3, y: 3, z: 3 }, + * color: { red: 128, green: 128, blue: 128 }, + * collisionless: true, // So that avatar can walk through entity. + * script: "(" + entityScript + ")", // Could host the script on a Web server instead. + * lifetime: 300 // Delete after 5 minutes. + * }); + */ void enterEntity(const EntityItemID& entityItemID); + + /**jsdoc + * Triggered when an avatar leaves an entity. + * @function Entities.leaveEntity + * @param {Uuid} entityID - The ID of the entity that the avatar left. + * @returns {Signal} + */ void leaveEntity(const EntityItemID& entityItemID); + + /**jsdoc + * Triggered when an entity is deleted. + * @function Entities.deletingEntity + * @param {Uuid} entityID - The ID of the entity deleted. + * @returns {Signal} + * @example Report when an entity is deleted. + * Entities.deletingEntity.connect(function (entityID) { + * print("Deleted entity: " + entityID); + * }); + */ void deletingEntity(const EntityItemID& entityID); + + /**jsdoc + * Triggered when an entity is added to Interface's local in-memory tree of entities it knows about. This may occur when + * entities are loaded upon visiting a domain, when the user rotates their view so that more entities become visible, and + * when a domain or client-only entity is added (e.g., by {@Entities.addEntity|addEntity}). + * @function Entities.addingEntity + * @param {Uuid} entityID - The ID of the entity added. + * @returns {Signal} + * @example Report when an entity is added. + * Entities.addingEntity.connect(function (entityID) { + * print("Added entity: " + entityID); + * }); + */ void addingEntity(const EntityItemID& entityID); + + /**jsdoc + * Triggered when you disconnect from a domain, at which time Interface's local in-memory tree of entities it knows about + * is cleared. + * @function Entities.clearingEntities + * @returns {Signal} + * @example Report when Interfaces's entity tree is cleared. + * Entities.clearingEntities.connect(function () { + * print("Entities cleared"); + * }); + */ void clearingEntities(); + + /**jsdoc + * @function Entities.debitEnergySource + * @param {number} value - The amount to debit. + * @returns {Signal} + * @deprecated This function is deprecated and will soon be removed. + */ void debitEnergySource(float value); + /**jsdoc + * Triggered in when a script in a {@link Entities.EntityType|Web} entity's Web page script sends an event over the + * script's EventBridge. + * @function Entities.webEventReceived + * @param {Uuid} entityID - The ID of the entity that event was received from. + * @param {string} message - The message received. + * @returns {Signal} + */ void webEventReceived(const EntityItemID& entityItemID, const QVariant& message); protected: diff --git a/libraries/entities/src/EntityTypes.h b/libraries/entities/src/EntityTypes.h index 62011c6e26..0e2fca8180 100644 --- a/libraries/entities/src/EntityTypes.h +++ b/libraries/entities/src/EntityTypes.h @@ -35,6 +35,56 @@ typedef EntityItemPointer (*EntityTypeFactory)(const EntityItemID& entityID, con class EntityTypes { public: + /**jsdoc + *

An entity may be one of the following types:

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
ValueDescriptionProperties
"Box"A rectangular prism. This is a synonym of "Shape" for the case + * where the entity's shape property value is "Cube".
+ * If an entity is created with its type + * set to "Box" it will always be created with a shape property value of + * "Cube". If an entity of type Shape or Sphere has its shape set + * to "Cube" then its type will be reported as "Box". + *
{@link Entities.EntityProperties-Box|EntityProperties-Box}
"Light"A local lighting effect.{@link Entities.EntityProperties-Light|EntityProperties-Light}
"Line"A sequence of one or more simple straight lines.{@link Entities.EntityProperties-Line|EntityProperties-Line}
"Material"Modifies the existing materials on Model entities, Shape entities (albedo + * only), {@link Overlays.OverlayType|model overlays}, and avatars.{@link Entities.EntityProperties-Material|EntityProperties-Material}
"Model"A mesh model from an FBX or OBJ file.{@link Entities.EntityProperties-Model|EntityProperties-Model}
"ParticleEffect"A particle system that can be used to simulate things such as fire, + * smoke, snow, magic spells, etc.{@link Entities.EntityProperties-ParticleEffect|EntityProperties-ParticleEffect}
"PolyLine"A sequence of one or more textured straight lines.{@link Entities.EntityProperties-PolyLine|EntityProperties-PolyLine}
"PolyVox"A set of textured voxels.{@link Entities.EntityProperties-PolyVox|EntityProperties-PolyVox}
"Shape"A basic entity such as a cube. + * See also, the "Box" and "Sphere" entity types.{@link Entities.EntityProperties-Shape|EntityProperties-Shape}
"Sphere"A sphere. This is a synonym of "Shape" for the case + * where the entity's shape property value is "Sphere".
+ * If an entity is created with its type + * set to "Sphere" it will always be created with a shape property value of + * "Sphere". If an entity of type Box or Shape has its shape set + * to "Sphere" then its type will be reported as "Sphere". + *
{@link Entities.EntityProperties-Sphere|EntityProperties-Sphere}
"Text"A pane of text oriented in space.{@link Entities.EntityProperties-Text|EntityProperties-Text}
"Web"A browsable Web page.{@link Entities.EntityProperties-Web|EntityProperties-Web}
"Zone"A volume of lighting effects and avatar permissions.{@link Entities.EntityProperties-Zone|EntityProperties-Zone}
+ * @typedef {string} Entities.EntityType + */ typedef enum EntityType_t { Unknown, Model, diff --git a/libraries/entities/src/HazePropertyGroup.h b/libraries/entities/src/HazePropertyGroup.h index 939391caf9..e992aefbf3 100644 --- a/libraries/entities/src/HazePropertyGroup.h +++ b/libraries/entities/src/HazePropertyGroup.h @@ -40,6 +40,35 @@ static const float INITIAL_HAZE_BACKGROUND_BLEND{ 0.0f }; static const float INITIAL_KEY_LIGHT_RANGE{ 1000.0f }; static const float INITIAL_KEY_LIGHT_ALTITUDE{ 200.0f }; +// FIXME: Document hazeAttenuationKeyLight, hazeKeyLightRange, and hazeKeyLightAltitude once they're working and are provided +// in the Create app's UI. +/**jsdoc + * Haze is defined by the following properties. + * @typedef {object} Entities.Haze + * + * @property {number} hazeRange=1000 - The horizontal distance at which visibility is reduced to 95%; i.e., 95% of each pixel's + * color is haze. + * @property {Color} hazeColor=128,154,179 - The color of the haze when looking away from the key light. + * @property {boolean} hazeEnableGlare=false - If true then the haze is colored with glare from the key light; + * hazeGlareColor and hazeGlareAngle are used. + * @property {Color} hazeGlareColor=255,299,179 - The color of the haze when looking towards the key light. + * @property {number} hazeGlareAngle=20 - The angle in degrees across the circle around the key light that the glare color and + * haze color are blended 50/50. + * + * @property {boolean} hazeAltitudeEffect=false - If true then haze decreases with altitude as defined by the + * entity's local coordinate system; hazeBaseRef and
hazeCeiling
are used. + * @property {number} hazeBaseRef=0 - The y-axis value in the entity's local coordinate system at which the haze density starts + * reducing with altitude. + * @property {number} hazeCeiling=200 - The y-axis value in the entity's local coordinate system at which the haze density has + * reduced to 5%. + * + * @property {number} hazeBackgroundBlend=0 - The proportion of the skybox image to show through the haze: 0.0 + * displays no skybox image; 1.0 displays no haze. + * + * @property {boolean} hazeAttenuateKeyLight=false - Currently not supported. + * @property {number} hazeKeyLightRange=1000 - Currently not supported. + * @property {number} hazeKeyLightAltitude=200 - Currently not supported. + */ class HazePropertyGroup : public PropertyGroup { public: // EntityItemProperty related helpers diff --git a/libraries/entities/src/KeyLightPropertyGroup.h b/libraries/entities/src/KeyLightPropertyGroup.h index 5e13a6afa6..2be33787de 100644 --- a/libraries/entities/src/KeyLightPropertyGroup.h +++ b/libraries/entities/src/KeyLightPropertyGroup.h @@ -27,6 +27,16 @@ class OctreePacketData; class EntityTreeElementExtraEncodeData; class ReadBitstreamToTreeParams; +/**jsdoc + * A key light is defined by the following properties. + * @typedef {object} Entities.KeyLight + * @property {Color} color=255,255,255 - The color of the light. + * @property {number} intensity=1 - The intensity of the light. + * @property {Vec3} direction=0,-1,0 - The direction the light is shining. + * @property {boolean} castShadows=false - If true then shadows are cast. Shadows are cast by avatars, plus + * {@link Entities.EntityType|Model} and {@link Entities.EntityType|Shape} entities that have their + * {@link Entities.EntityProperties|canCastShadows} property set to true. + */ class KeyLightPropertyGroup : public PropertyGroup { public: // EntityItemProperty related helpers diff --git a/libraries/entities/src/PolyVoxEntityItem.h b/libraries/entities/src/PolyVoxEntityItem.h index 90982fe448..0ddfe3e8cc 100644 --- a/libraries/entities/src/PolyVoxEntityItem.h +++ b/libraries/entities/src/PolyVoxEntityItem.h @@ -59,6 +59,25 @@ class PolyVoxEntityItem : public EntityItem { virtual int getOnCount() const { return 0; } + /**jsdoc + *

A PolyVoxSurfaceStyle may be one of the following:

+ * + * + * + * + * + * + * + * + * + * + *
ValueTypeDescription
0Marching cubes.Chamfered edges. Open volume. + * Joins neighboring PolyVox entities reasonably well.
1Cubic.Square edges. Open volume. + * Joins neighboring PolyVox entities cleanly.
2Edged cubic.Square edges. Enclosed volume. + * Joins neighboring PolyVox entities cleanly.
3Edged marching cubes.Chamfered edges. Enclosed volume. + * Doesn't join neighboring PolyVox entities.
+ * @typedef {number} Entities.PolyVoxSurfaceStyle + */ enum PolyVoxSurfaceStyle { SURFACE_MARCHING_CUBES, SURFACE_CUBIC, diff --git a/libraries/entities/src/ShapeEntityItem.cpp b/libraries/entities/src/ShapeEntityItem.cpp index db3d6798be..60ba429938 100644 --- a/libraries/entities/src/ShapeEntityItem.cpp +++ b/libraries/entities/src/ShapeEntityItem.cpp @@ -20,6 +20,33 @@ #include "ShapeEntityItem.h" namespace entity { + + /**jsdoc + *

A Shape, Box, or Sphere {@link Entities.EntityType|EntityType} may display as + * one of the following geometrical shapes:

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
ValueDimensionsNotes
"Circle"2DA circle oriented in 3D.
"Cube"3D
"Cone"3D
"Cylinder"3D
"Dodecahedron"3D
"Hexagon"3DA hexagonal prism.
"Icosahedron"3D
"Octagon"3DAn octagonal prism.
"Octahedron"3D
"Quad"2DA square oriented in 3D.
"Sphere"3D
"Tetrahedron"3D
"Torus"3DNot implemented.
"Triangle"3DA triangular prism.
+ * @typedef {string} Entities.Shape + */ static const std::array shapeStrings { { "Triangle", "Quad", @@ -32,7 +59,7 @@ namespace entity { "Octahedron", "Dodecahedron", "Icosahedron", - "Torus", + "Torus", // Not implemented yet. "Cone", "Cylinder" } }; diff --git a/libraries/entities/src/ShapeEntityItem.h b/libraries/entities/src/ShapeEntityItem.h index 46d696f979..97202afcf7 100644 --- a/libraries/entities/src/ShapeEntityItem.h +++ b/libraries/entities/src/ShapeEntityItem.h @@ -105,7 +105,7 @@ public: protected: - float _alpha { 1 }; + float _alpha { 1 }; // FIXME: This property is not used. rgbColor _color; entity::Shape _shape { entity::Shape::Sphere }; diff --git a/libraries/entities/src/SkyboxPropertyGroup.h b/libraries/entities/src/SkyboxPropertyGroup.h index 8298a7b74e..d7b422bf11 100644 --- a/libraries/entities/src/SkyboxPropertyGroup.h +++ b/libraries/entities/src/SkyboxPropertyGroup.h @@ -27,6 +27,13 @@ class OctreePacketData; class EntityTreeElementExtraEncodeData; class ReadBitstreamToTreeParams; +/**jsdoc + * A skybox is defined by the following properties. + * @typedef {object} Entities.Skybox + * @property {Color} color=0,0,0 - Sets the color of the sky if url is "", otherwise modifies the + * color of the cube map image. + * @property {string} url="" - A cube map image that is used to render the sky. + */ class SkyboxPropertyGroup : public PropertyGroup { public: // EntityItemProperty related helpers diff --git a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.h b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.h index 84c6cb6fa8..526352804b 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.h +++ b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.h @@ -38,7 +38,7 @@ public slots: * Returns a model reference object associated with the specified UUID ({@link EntityID}, {@link OverlayID}, or {@link AvatarID}). * * @function Graphics.getModel - * @param {UUID} The objectID of the model whose meshes are to be retrieved. + * @param {UUID} entityID - The objectID of the model whose meshes are to be retrieved. * @return {Graphics.Model} the resulting Model object */ scriptable::ScriptableModelPointer getModel(QUuid uuid); diff --git a/libraries/model-networking/src/model-networking/MaterialCache.cpp b/libraries/model-networking/src/model-networking/MaterialCache.cpp index 85f2f43652..cf3e255e0c 100644 --- a/libraries/model-networking/src/model-networking/MaterialCache.cpp +++ b/libraries/model-networking/src/model-networking/MaterialCache.cpp @@ -28,6 +28,25 @@ void NetworkMaterialResource::downloadFinished(const QByteArray& data) { finishedLoading(true); } +/**jsdoc + *

An RGB or SRGB color value.

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
IndexTypeAttributesDefaultValue
0numberRed component value. Number in the range 0.01.0.
1numberGreen component value. Number in the range 0.01.0.
2numberBlue component value. Number in the range 0.01.0.
3boolean<optional>falseIf true then the color is an SRGB color.
+ * @typedef {array} RGBS + */ bool NetworkMaterialResource::parseJSONColor(const QJsonValue& array, glm::vec3& color, bool& isSRGB) { if (array.isArray()) { QJsonArray colorArray = array.toArray(); @@ -50,6 +69,12 @@ bool NetworkMaterialResource::parseJSONColor(const QJsonValue& array, glm::vec3& return false; } +/**jsdoc + * A material or set of materials such as may be used by a {@link Entities.EntityType|Material} entity. + * @typedef {object} MaterialResource + * @property {number} materialVersion=1 - The version of the material. Currently not used. + * @property {Material|Material[]} materials - The details of the material or materials. + */ NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMaterials(const QJsonDocument& materialJSON) { ParsedMaterials toReturn; if (!materialJSON.isNull() && materialJSON.isObject()) { @@ -83,6 +108,36 @@ NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMater return toReturn; } +/**jsdoc + * A material such as may be used by a {@link Entities.EntityType|Material} entity. + * @typedef {object} Material + * @property {string} name="" - A name for the material. + * @property {string} model="hifi_pbr" - Currently not used. + * @property {Vec3Color|RGBS} emissive - The emissive color, i.e., the color that the material emits. A {@link Vec3Color} value + * is treated as sRGB. A {@link RGBS} value can be either RGB or sRGB. + * @property {number} opacity=1.0 - The opacity, 0.01.0. + * @property {boolean} unlit=false - If true, the material is not lit. + * @property {Vec3Color|RGBS} albedo - The albedo color. A {@link Vec3Color} value is treated as sRGB. A {@link RGBS} value can + * be either RGB or sRGB. + * @property {number} roughness - The roughness, 0.01.0. + * @property {number} metallic - The metallicness, 0.01.0. + * @property {number} scattering - The scattering, 0.01.0. + * @property {string} emissiveMap - URL of emissive texture image. + * @property {string} albedoMap - URL of albedo texture image. + * @property {string} opacityMap - URL of opacity texture image. Set value the same as the albedoMap value for + * transparency. + * @property {string} roughnessMap - URL of roughness texture image. Can use this or glossMap, but not both. + * @property {string} glossMap - URL of gloss texture image. Can use this or roughnessMap, but not both. + * @property {string} metallicMap - URL of metallic texture image. Can use this or specularMap, but not both. + * @property {string} specularMap - URL of specular texture image. Can use this or metallicMap, but not both. + * @property {string} normalMap - URL of normal texture image. Can use this or bumpMap, but not both. + * @property {string} bumpMap - URL of bump texture image. Can use this or normalMap, but not both. + * @property {string} occlusionMap - URL of occlusion texture image. + * @property {string} scatteringMap - URL of scattering texture image. Only used if normalMap or + * bumpMap is specified. + * @property {string} lightMap - URL of light map texture image. Currently not used. + */ +// Note: See MaterialEntityItem.h for default values used in practice. std::pair> NetworkMaterialResource::parseJSONMaterial(const QJsonObject& materialJSON) { std::string name = ""; std::shared_ptr material = std::make_shared(); diff --git a/libraries/octree/src/OctreeScriptingInterface.h b/libraries/octree/src/OctreeScriptingInterface.h index c31da94532..e501dd166a 100644 --- a/libraries/octree/src/OctreeScriptingInterface.h +++ b/libraries/octree/src/OctreeScriptingInterface.h @@ -35,48 +35,126 @@ private slots: void cleanupManagedObjects(); public slots: + + /**jsdoc + * Set the maximum number of entity packets that the client can send per second. + * @function Entities.setPacketsPerSecond + * @param {number} packetsPerSecond - Integer maximum number of entity packets that the client can send per second. + */ /// set the max packets per second send rate void setPacketsPerSecond(int packetsPerSecond) { return _packetSender->setPacketsPerSecond(packetsPerSecond); } + /**jsdoc + * Get the maximum number of entity packets that the client can send per second. + * @function Entities.getPacketsPerSecond + * @returns {number} Integer maximum number of entity packets that the client can send per second. + */ /// get the max packets per second send rate int getPacketsPerSecond() const { return _packetSender->getPacketsPerSecond(); } - /// does a particle server exist to send to + /**jsdoc + * Check whether servers exist for the client to send entity packets to, i.e., whether you are connected to a domain and + * its entity server is working. + * @function Entities.serversExist + * @returns {boolean} true if servers exist for the client to send entity packets to, otherwise + * false. + */ + /// does a server exist to send to bool serversExist() const { return _packetSender->serversExist(); } + /**jsdoc + * Check whether the client has entity packets waiting to be sent. + * @function Entities.hasPacketsToSend + * @returns {boolean} true if the client has entity packets waiting to be sent, otherwise false. + */ /// are there packets waiting in the send queue to be sent bool hasPacketsToSend() const { return _packetSender->hasPacketsToSend(); } + /**jsdoc + * Get the number of entity packets the client has waiting to be sent. + * @function Entities.packetsToSendCount + * @returns {number} Integer number of entity packets the client has waiting to be sent. + */ /// how many packets are there in the send queue waiting to be sent int packetsToSendCount() const { return (int)_packetSender->packetsToSendCount(); } + /**jsdoc + * Get the entity packets per second send rate of the client over its lifetime. + * @function Entities.getLifetimePPS + * @returns {number} Entity packets per second send rate of the client over its lifetime. + */ /// returns the packets per second send rate of this object over its lifetime float getLifetimePPS() const { return _packetSender->getLifetimePPS(); } + /**jsdoc + * Get the entity bytes per second send rate of the client over its lifetime. + * @function Entities.getLifetimeBPS + * @returns {number} Entity bytes per second send rate of the client over its lifetime. + */ /// returns the bytes per second send rate of this object over its lifetime float getLifetimeBPS() const { return _packetSender->getLifetimeBPS(); } + /**jsdoc + * Get the entity packets per second queued rate of the client over its lifetime. + * @function Entities.getLifetimePPSQueued + * @returns {number} Entity packets per second queued rate of the client over its lifetime. + */ /// returns the packets per second queued rate of this object over its lifetime float getLifetimePPSQueued() const { return _packetSender->getLifetimePPSQueued(); } + /**jsdoc + * Get the entity bytes per second queued rate of the client over its lifetime. + * @function Entities.getLifetimeBPSQueued + * @returns {number} Entity bytes per second queued rate of the client over its lifetime. + */ /// returns the bytes per second queued rate of this object over its lifetime float getLifetimeBPSQueued() const { return _packetSender->getLifetimeBPSQueued(); } + /**jsdoc + * Get the lifetime of the client from the first entity packet sent until now, in microseconds. + * @function Entities.getLifetimeInUsecs + * @returns {number} Lifetime of the client from the first entity packet sent until now, in microseconds. + */ /// returns lifetime of this object from first packet sent to now in usecs long long unsigned int getLifetimeInUsecs() const { return _packetSender->getLifetimeInUsecs(); } - /// returns lifetime of this object from first packet sent to now in usecs + /**jsdoc + * Get the lifetime of the client from the first entity packet sent until now, in seconds. + * @function Entities.getLifetimeInSeconds + * @returns {number} Lifetime of the client from the first entity packet sent until now, in seconds. + */ + /// returns lifetime of this object from first packet sent to now in secs float getLifetimeInSeconds() const { return _packetSender->getLifetimeInSeconds(); } + /**jsdoc + * Get the total number of entity packets sent by the client over its lifetime. + * @function Entities.getLifetimePacketsSent + * @returns {number} The total number of entity packets sent by the client over its lifetime. + */ /// returns the total packets sent by this object over its lifetime long long unsigned int getLifetimePacketsSent() const { return _packetSender->getLifetimePacketsSent(); } + /**jsdoc + * Get the total bytes of entity packets sent by the client over its lifetime. + * @function Entities.getLifetimeBytesSent + * @returns {number} The total bytes of entity packets sent by the client over its lifetime. + */ /// returns the total bytes sent by this object over its lifetime long long unsigned int getLifetimeBytesSent() const { return _packetSender->getLifetimeBytesSent(); } + /**jsdoc + * Get the total number of entity packets queued by the client over its lifetime. + * @function Entities.getLifetimePacketsQueued + * @returns {number} The total number of entity packets queued by the client over its lifetime. + */ /// returns the total packets queued by this object over its lifetime long long unsigned int getLifetimePacketsQueued() const { return _packetSender->getLifetimePacketsQueued(); } + /**jsdoc + * Get the total bytes of entity packets queued by the client over its lifetime. + * @function Entities.getLifetimeBytesQueued + * @returns {number} The total bytes of entity packets queued by the client over its lifetime. + */ /// returns the total bytes queued by this object over its lifetime long long unsigned int getLifetimeBytesQueued() const { return _packetSender->getLifetimeBytesQueued(); } diff --git a/libraries/physics/src/ObjectActionOffset.cpp b/libraries/physics/src/ObjectActionOffset.cpp index c1fb397e19..e90862266b 100644 --- a/libraries/physics/src/ObjectActionOffset.cpp +++ b/libraries/physics/src/ObjectActionOffset.cpp @@ -142,6 +142,18 @@ bool ObjectActionOffset::updateArguments(QVariantMap arguments) { return true; } +/**jsdoc + * The "offset" {@link Entities.ActionType|ActionType} moves an entity so that it is a set distance away from a + * target point. + * It has arguments in addition to the common {@link Entities.ActionArguments|ActionArguments}. + * + * @typedef {object} Entities.ActionArguments-Offset + * @property {Vec3} pointToOffsetFrom=0,0,0 - The target point to offset the entity from. + * @property {number} linearDistance=0 - The distance away from the target point to position the entity. + * @property {number} linearTimeScale=34e+38 - Controls how long it takes for the entity's position to catch up with the + * target offset. The value is the time for the action to catch up to 1/e = 0.368 of the target value, where the action + * is applied using an exponential decay. + */ QVariantMap ObjectActionOffset::getArguments() { QVariantMap arguments = ObjectDynamic::getArguments(); withReadLock([&] { diff --git a/libraries/physics/src/ObjectActionTractor.cpp b/libraries/physics/src/ObjectActionTractor.cpp index 03e6533c87..bc68d6de73 100644 --- a/libraries/physics/src/ObjectActionTractor.cpp +++ b/libraries/physics/src/ObjectActionTractor.cpp @@ -307,6 +307,23 @@ bool ObjectActionTractor::updateArguments(QVariantMap arguments) { return true; } +/**jsdoc + * The "tractor" {@link Entities.ActionType|ActionType} moves and rotates an entity to a target position and + * orientation, optionally relative to another entity. + * It has arguments in addition to the common {@link Entities.ActionArguments|ActionArguments}. + * + * @typedef {object} Entities.ActionArguments-Tractor + * @property {Vec3} targetPosition=0,0,0 - The target position. + * @property {Quat} targetRotation=0,0,0,1 - The target rotation. + * @property {Uuid} otherID=null - If an entity ID, the targetPosition and targetRotation are + * relative to this entity's position and rotation. + * @property {number} linearTimeScale=3.4e+38 - Controls how long it takes for the entity's position to catch up with the + * target position. The value is the time for the action to catch up to 1/e = 0.368 of the target value, where the action + * is applied using an exponential decay. + * @property {number} angularTimeScale=3.4e+38 - Controls how long it takes for the entity's orientation to catch up with the + * target orientation. The value is the time for the action to catch up to 1/e = 0.368 of the target value, where the + * action is applied using an exponential decay. + */ QVariantMap ObjectActionTractor::getArguments() { QVariantMap arguments = ObjectDynamic::getArguments(); withReadLock([&] { diff --git a/libraries/physics/src/ObjectActionTravelOriented.cpp b/libraries/physics/src/ObjectActionTravelOriented.cpp index 8ab24511d7..accade8695 100644 --- a/libraries/physics/src/ObjectActionTravelOriented.cpp +++ b/libraries/physics/src/ObjectActionTravelOriented.cpp @@ -146,6 +146,17 @@ bool ObjectActionTravelOriented::updateArguments(QVariantMap arguments) { return true; } +/**jsdoc + * The "travel-oriented" {@link Entities.ActionType|ActionType} orients an entity to align with its direction of + * travel. + * It has arguments in addition to the common {@link Entities.ActionArguments|ActionArguments}. + * + * @typedef {object} Entities.ActionArguments-TravelOriented + * @property {Vec3} forward=0,0,0 - The axis of the entity to align with the entity's direction of travel. + * @property {number} angularTimeScale=0.1 - Controls how long it takes for the entity's orientation to catch up with the + * direction of travel. The value is the time for the action to catch up to 1/e = 0.368 of the target value, where the + * action is applied using an exponential decay. + */ QVariantMap ObjectActionTravelOriented::getArguments() { QVariantMap arguments = ObjectDynamic::getArguments(); withReadLock([&] { diff --git a/libraries/physics/src/ObjectConstraintBallSocket.cpp b/libraries/physics/src/ObjectConstraintBallSocket.cpp index 9dd85954a3..70613d46ae 100644 --- a/libraries/physics/src/ObjectConstraintBallSocket.cpp +++ b/libraries/physics/src/ObjectConstraintBallSocket.cpp @@ -181,6 +181,15 @@ bool ObjectConstraintBallSocket::updateArguments(QVariantMap arguments) { return true; } +/**jsdoc + * The "ball-socket" {@link Entities.ActionType|ActionType} connects two entities with a ball and socket joint. + * It has arguments in addition to the common {@link Entities.ActionArguments|ActionArguments}. + * + * @typedef {object} Entities.ActionArguments-BallSocket + * @property {Vec3} pivot=0,0,0 - The local offset of the joint relative to the entity's position. + * @property {Uuid} otherEntityID=null - The ID of the other entity that is connected to the joint. + * @property {Vec3} otherPivot=0,0,0 - The local offset of the joint relative to the other entity's position. + */ QVariantMap ObjectConstraintBallSocket::getArguments() { QVariantMap arguments = ObjectDynamic::getArguments(); withReadLock([&] { diff --git a/libraries/physics/src/ObjectConstraintConeTwist.cpp b/libraries/physics/src/ObjectConstraintConeTwist.cpp index 49f926af81..86f1f21c63 100644 --- a/libraries/physics/src/ObjectConstraintConeTwist.cpp +++ b/libraries/physics/src/ObjectConstraintConeTwist.cpp @@ -261,6 +261,21 @@ bool ObjectConstraintConeTwist::updateArguments(QVariantMap arguments) { return true; } +/**jsdoc + * The "cone-twist" {@link Entities.ActionType|ActionType} connects two entities with a joint that can move + * through a cone and can twist. + * It has arguments in addition to the common {@link Entities.ActionArguments|ActionArguments}. + * + * @typedef {object} Entities.ActionArguments-ConeTwist + * @property {Vec3} pivot=0,0,0 - The local offset of the joint relative to the entity's position. + * @property {Vec3} axis=1,0,0 - The axis of the entity that moves through the cone. Must be a non-zero vector. + * @property {Uuid} otherEntityID=null - The ID of the other entity that is connected to the joint. + * @property {Vec3} otherPivot=0,0,0 - The local offset of the joint relative to the other entity's position. + * @property {Vec3} otherAxis=1,0,0 - The axis of the other entity that moves through the cone. Must be a non-zero vector. + * @property {number} swingSpan1=6.238 - The angle through which the joint can move in one axis of the cone, in radians. + * @property {number} swingSpan2=6.238 - The angle through which the joint can move in the other axis of the cone, in radians. + * @property {number} twistSpan=6.238 - The angle through with the joint can twist, in radians. + */ QVariantMap ObjectConstraintConeTwist::getArguments() { QVariantMap arguments = ObjectDynamic::getArguments(); withReadLock([&] { diff --git a/libraries/physics/src/ObjectConstraintHinge.cpp b/libraries/physics/src/ObjectConstraintHinge.cpp index 52be64796a..99ddd45abd 100644 --- a/libraries/physics/src/ObjectConstraintHinge.cpp +++ b/libraries/physics/src/ObjectConstraintHinge.cpp @@ -245,6 +245,22 @@ bool ObjectConstraintHinge::updateArguments(QVariantMap arguments) { return true; } +/**jsdoc + * The "hinge" {@link Entities.ActionType|ActionType} lets an entity pivot about an axis or connects two entities + * with a hinge joint. + * It has arguments in addition to the common {@link Entities.ActionArguments|ActionArguments}. + * + * @typedef {object} Entities.ActionArguments-Hinge + * @property {Vec3} pivot=0,0,0 - The local offset of the joint relative to the entity's position. + * @property {Vec3} axis=1,0,0 - The axis of the entity that it pivots about. Must be a non-zero vector. + * @property {Uuid} otherEntityID=null - The ID of the other entity that is connected to the joint, if any. If none is + * specified then the first entity simply pivots about its specified axis. + * @property {Vec3} otherPivot=0,0,0 - The local offset of the joint relative to the other entity's position. + * @property {Vec3} otherAxis=1,0,0 - The axis of the other entity that it pivots about. Must be a non-zero vector. + * @property {number} low=-6.283 - The most negative angle that the hinge can take, in radians. + * @property {number} high=6.283 - The most positive angle that the hinge can take, in radians. + * @property {number} angle=0 - The current angle of the hinge. Read-only. + */ QVariantMap ObjectConstraintHinge::getArguments() { QVariantMap arguments = ObjectDynamic::getArguments(); withReadLock([&] { diff --git a/libraries/physics/src/ObjectConstraintSlider.cpp b/libraries/physics/src/ObjectConstraintSlider.cpp index ded9ad47e6..c236afc10d 100644 --- a/libraries/physics/src/ObjectConstraintSlider.cpp +++ b/libraries/physics/src/ObjectConstraintSlider.cpp @@ -261,6 +261,31 @@ bool ObjectConstraintSlider::updateArguments(QVariantMap arguments) { return true; } +/**jsdoc + * The "slider" {@link Entities.ActionType|ActionType} lets an entity slide and rotate along an axis, or connects + * two entities that slide and rotate along a shared axis. + * It has arguments in addition to the common {@link Entities.ActionArguments|ActionArguments}. + * + * @typedef {object} Entities.ActionArguments-Slider + * @property {Vec3} point=0,0,0 - The local position of a point in the entity that slides along the axis. + * @property {Vec3} axis=1,0,0 - The axis of the entity that slides along the joint. Must be a non-zero vector. + * @property {Uuid} otherEntityID=null - The ID of the other entity that is connected to the joint, if any. If non is + * specified then the first entity simply slides and rotates about its specified axis. + * @property {Vec3} otherPoint=0,0,0 - The local position of a point in the other entity that slides along the axis. + * @property {Vec3} axis=1,0,0 - The axis of the other entity that slides along the joint. Must be a non-zero vector. + * @property {number} linearLow=1.17e-38 - The most negative linear offset from the entity's initial point that the entity can + * have along the slider. + * @property {number} linearHigh=3.40e+38 - The most positive linear offset from the entity's initial point that the entity can + * have along the slider. + * @property {number} angularLow=-6.283 - The most negative angle that the entity can rotate about the axis if the action + * involves only one entity, otherwise the most negative angle the rotation can be between the two entities. In radians. + * @property {number} angularHigh=6.283 - The most positive angle that the entity can rotate about the axis if the action + * involves only one entity, otherwise the most positive angle the rotation can be between the two entities. In radians. + * @property {number} linearPosition=0 - The current linear offset the entity is from its initial point if the action involves + * only one entity, otherwise the linear offset between the two entities' action points. Read-only. + * @property {number} angularPosition=0 - The current angular offset of the entity from its initial rotation if the action + * involves only one entity, otherwise the angular offset between the two entities. Read-only. + */ QVariantMap ObjectConstraintSlider::getArguments() { QVariantMap arguments = ObjectDynamic::getArguments(); withReadLock([&] { diff --git a/libraries/physics/src/ObjectDynamic.cpp b/libraries/physics/src/ObjectDynamic.cpp index 3deadd6468..5bbb5981d1 100644 --- a/libraries/physics/src/ObjectDynamic.cpp +++ b/libraries/physics/src/ObjectDynamic.cpp @@ -93,6 +93,38 @@ bool ObjectDynamic::updateArguments(QVariantMap arguments) { return somethingChanged; } +/**jsdoc +* Different entity action types have different arguments: some common to all actions (listed below) and some specific to each +* {@link Entities.ActionType|ActionType} (linked to below). The arguments are accessed as an object of property names and +* values. +* +* @typedef {object} Entities.ActionArguments +* @property {Entities.ActionType} type - The type of action. +* @property {string} tag="" - A string that a script can use for its own purposes. +* @property {number} ttl=0 - How long the action should exist, in seconds, before it is automatically deleted. A value of +* 0 means that the action should not be deleted. +* @property {boolean} isMine=true - Is true if you created the action during your current Interface session, +* false otherwise. Read-only. +* @property {boolean} ::no-motion-state - Is present when the entity hasn't been registered with the physics engine yet (e.g., +* if the action hasn't been properly configured), otherwise undefined. Read-only. +* @property {boolean} ::active - Is true when the action is modifying the entity's motion, false +* otherwise. Is present once the entity has been registered with the physics engine, otherwise undefined. +* Read-only. +* @property {Entities.PhysicsMotionType} ::motion-type - How the entity moves with the action. Is present once the entity has +* been registered with the physics engine, otherwise undefined. Read-only. +* +* @see The different action types have additional arguments as follows: +* @see {@link Entities.ActionArguments-FarGrab|ActionArguments-FarGrab} +* @see {@link Entities.ActionArguments-Hold|ActionArguments-Hold} +* @see {@link Entities.ActionArguments-Offset|ActionArguments-Offset} +* @see {@link Entities.ActionArguments-Tractor|ActionArguments-Tractor} +* @see {@link Entities.ActionArguments-TravelOriented|ActionArguments-TravelOriented} +* @see {@link Entities.ActionArguments-Hinge|ActionArguments-Hinge} +* @see {@link Entities.ActionArguments-Slider|ActionArguments-Slider} +* @see {@link Entities.ActionArguments-ConeTwist|ActionArguments-ConeTwist} +* @see {@link Entities.ActionArguments-BallSocket|ActionArguments-BallSocket} +*/ +// Note: The "type" property is set in EntityItem::getActionArguments(). QVariantMap ObjectDynamic::getArguments() { QVariantMap arguments; withReadLock([&]{ diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index 0b91ede574..7f583ca9ca 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -29,6 +29,23 @@ enum PhysicsMotionType { MOTION_TYPE_KINEMATIC // keyframed motion }; +/**jsdoc + *

An entity's physics motion type may be one of the following:

+ * + * + * + * + * + * + * + * + * + *
ValueDescription
"static"There is no motion because the entity is locked — its locked + * property is set to true.
"kinematic"Motion is applied without physical laws (e.g., damping) because the entity is + * not locked and has its dynamic property set to false.
"dynamic"Motion is applied according to physical laws (e.g., damping) because the entity + * is not locked and has its dynamic property set to true.
+ * @typedef {string} Entities.PhysicsMotionType + */ inline QString motionTypeToString(PhysicsMotionType motionType) { switch(motionType) { case MOTION_TYPE_STATIC: return QString("static"); diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 7455da13b6..212cf5eae1 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -75,32 +75,6 @@ static std::array MAPPING GeometryCache::Cylinder, } }; -/**jsdoc -*

{@link Entities} and {@link Overlays} may have the following geometrical shapes:

-* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -* -*
ValueDescription
LineA 1D line oriented in 3 dimensions.
TriangleA triangular prism.
QuadA 2D square oriented in 3 dimensions.
HexagonA hexagonal prism.
OctagonAn octagonal prism.
CircleA 2D circle oriented in 3 dimensions.
CubeA cube.
SphereA sphere.
TetrahedronA tetrahedron.
OctahedronAn octahedron.
DodecahedronA dodecahedron.
IcosahedronAn icosahedron.
TorusA torus. Not implemented.
ConeA cone.
CylinderA cylinder.
-* @typedef {string} Shape -*/ static const std::array GEOCACHE_SHAPE_STRINGS{ { "Line", "Triangle", diff --git a/libraries/script-engine/src/Quat.h b/libraries/script-engine/src/Quat.h index 23e8e3b896..68b4dcd408 100644 --- a/libraries/script-engine/src/Quat.h +++ b/libraries/script-engine/src/Quat.h @@ -35,7 +35,7 @@ * of gimbal lock. * @namespace Quat * @variation 0 - * @property IDENTITY {Quat} The identity rotation, i.e., no rotation. + * @property IDENTITY {Quat} The identity rotation, i.e., no rotation. Its value is { x: 0, y: 0, z: 0, w: 1 }. * @example Print the IDENTITY value. * print(JSON.stringify(Quat.IDENTITY)); // { x: 0, y: 0, z: 0, w: 1 } * print(JSON.stringify(Quat.safeEulerAngles(Quat.IDENTITY))); // { x: 0, y: 0, z: 0 } diff --git a/libraries/script-engine/src/Vec3.h b/libraries/script-engine/src/Vec3.h index 1e1cd917a3..7ed0fd9e8b 100644 --- a/libraries/script-engine/src/Vec3.h +++ b/libraries/script-engine/src/Vec3.h @@ -25,27 +25,36 @@ * A 2-dimensional vector. * * @typedef {object} Vec2 - * @property {float} x X-coordinate of the vector. - * @property {float} y Y-coordinate of the vector. + * @property {number} x - X-coordinate of the vector. + * @property {number} y - Y-coordinate of the vector. */ /**jsdoc * A 3-dimensional vector. * * @typedef {object} Vec3 - * @property {float} x X-coordinate of the vector. - * @property {float} y Y-coordinate of the vector. - * @property {float} z Z-coordinate of the vector. + * @property {number} x - X-coordinate of the vector. + * @property {number} y - Y-coordinate of the vector. + * @property {number} z - Z-coordinate of the vector. */ /**jsdoc * A 4-dimensional vector. * * @typedef {object} Vec4 - * @property {float} x X-coordinate of the vector. - * @property {float} y Y-coordinate of the vector. - * @property {float} z Z-coordinate of the vector. - * @property {float} w W-coordinate of the vector. + * @property {number} x - X-coordinate of the vector. + * @property {number} y - Y-coordinate of the vector. + * @property {number} z - Z-coordinate of the vector. + * @property {number} w - W-coordinate of the vector. + */ + +/**jsdoc + * A color vector. + * + * @typedef {object} Vec3Color + * @property {number} x - Red component value. Integer in the range 0 - 255. + * @property {number} y - Green component value. Integer in the range 0 - 255. + * @property {number} z - Blue component value. Integer in the range 0 - 255. */ /// Scriptable interface a Vec3ernion helper class object. Used exclusively in the JavaScript API diff --git a/libraries/shared/src/PhysicsCollisionGroups.h b/libraries/shared/src/PhysicsCollisionGroups.h index 794f338dc5..edec61dc67 100644 --- a/libraries/shared/src/PhysicsCollisionGroups.h +++ b/libraries/shared/src/PhysicsCollisionGroups.h @@ -64,6 +64,25 @@ const int16_t BULLET_COLLISION_MASK_OTHER_AVATAR = BULLET_COLLISION_MASK_DEFAULT // COLLISIONLESS gets an empty mask. const int16_t BULLET_COLLISION_MASK_COLLISIONLESS = 0; +/**jsdoc + *

An entity may collide with the following types of items:

+ * + * + * + * + * + * + * + * + * + * + * + *
ValueDescription
1Static entities — non-dynamic entities with no velocity.
2Dynamic entities — entities that have their dynamic property set to + * true.
4Kinematic entities — non-dynamic entities with velocity.
8My avatar.
16Other avatars.
+ *

The values for the collision types that are enabled are added together to give the CollisionMask value. For example, a + * value of 31 means that an entity will collide with all item types.

+ * @typedef {number} Entities.CollisionMask + */ // The USER collision groups are exposed to script and can be used to generate per-object collision masks. // They are not necessarily the same as the BULLET_COLLISION_GROUPS, but we start them off with matching numbers. diff --git a/libraries/shared/src/RegisteredMetaTypes.cpp b/libraries/shared/src/RegisteredMetaTypes.cpp index 7b455beae5..a3d312b9c1 100644 --- a/libraries/shared/src/RegisteredMetaTypes.cpp +++ b/libraries/shared/src/RegisteredMetaTypes.cpp @@ -689,6 +689,15 @@ QScriptValue qColorToScriptValue(QScriptEngine* engine, const QColor& color) { return object; } +/**jsdoc + * An axis-aligned cube, defined as the bottom right near (minimum axes values) corner of the cube plus the dimension of its + * sides. + * @typedef {object} AACube + * @property {number} x - X coordinate of the brn corner of the cube. + * @property {number} y - Y coordinate of the brn corner of the cube. + * @property {number} z - Z coordinate of the brn corner of the cube. + * @property {number} scale - The dimensions of each side of the cube. + */ QScriptValue aaCubeToScriptValue(QScriptEngine* engine, const AACube& aaCube) { QScriptValue obj = engine->newObject(); const glm::vec3& corner = aaCube.getCorner(); @@ -765,6 +774,15 @@ void pickRayFromScriptValue(const QScriptValue& object, PickRay& pickRay) { } } +/**jsdoc + * @typedef {object} Collision + * @property {ContactEventType} type - The contact type of the collision event. + * @property {Uuid} idA - The ID of one of the entities in the collision. + * @property {Uuid} idB - The ID of the other of the entities in the collision. + * @property {Vec3} penetration - The amount of penetration between the two entities. + * @property {Vec3} contactPoint - The point of contact. + * @property {Vec3} velocityChange - The change in relative velocity of the two entities, in m/s. + */ QScriptValue collisionToScriptValue(QScriptEngine* engine, const Collision& collision) { QScriptValue obj = engine->newObject(); obj.setProperty("type", collision.type); diff --git a/libraries/shared/src/RegisteredMetaTypes.h b/libraries/shared/src/RegisteredMetaTypes.h index 4dbbd190ff..4fee78a0db 100644 --- a/libraries/shared/src/RegisteredMetaTypes.h +++ b/libraries/shared/src/RegisteredMetaTypes.h @@ -140,7 +140,7 @@ public: * * @typedef {object} PickRay * @property {Vec3} origin - The starting position of the PickRay. - * @property {Quat} direction - The direction that the PickRay travels. + * @property {Vec3} direction - The direction that the PickRay travels. */ class PickRay : public MathPick { public: @@ -265,6 +265,20 @@ namespace std { }; } +/**jsdoc + *

The type of a collision contact event. + * + * + * + * + * + * + * + * + * + *
ValueDescription
0Start of the collision.
1Continuation of the collision.
2End of the collision.
+ * @typedef {number} ContactEventType + */ enum ContactEventType { CONTACT_EVENT_TYPE_START, CONTACT_EVENT_TYPE_CONTINUE, @@ -328,13 +342,32 @@ namespace graphics { using MeshPointer = std::shared_ptr; - +/**jsdoc + * A handle for a mesh in an entity, such as returned by {@link Entities.getMeshes}. + * @class MeshProxy + * @deprecated Use the {@link Graphics} API instead. + */ class MeshProxy : public QObject { Q_OBJECT public: virtual MeshPointer getMeshPointer() const = 0; + + /**jsdoc + * Get the number of vertices in the mesh. + * @function MeshProxy#getNumVertices + * @returns {number} Integer number of vertices in the mesh. + * @deprecated Use the {@link Graphics} API instead. + */ Q_INVOKABLE virtual int getNumVertices() const = 0; + + /**jsdoc + * Get the position of a vertex in the mesh. + * @function MeshProxy#getPos3 + * @param {number} index - Integer index of the mesh vertex. + * @returns {Vec3} Local position of the vertex relative to the mesh. + * @deprecated Use the {@link Graphics} API instead. + */ Q_INVOKABLE virtual glm::vec3 getPos3(int index) const = 0; }; diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index 8cdc4bcf14..968292da87 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -1,6 +1,6 @@ // // ShapeInfo.cpp -// libraries/physics/src +// libraries/shared/src // // Created by Andrew Meadows 2014.10.29 // Copyright 2014 High Fidelity, Inc. @@ -15,6 +15,33 @@ #include "NumericalConstants.h" // for MILLIMETERS_PER_METER +/**jsdoc + *

A ShapeType defines the shape used for collisions or zones.

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
ValueDescription
"none"No shape.
"box"A cube.
"sphere"A sphere.
"capsule-x"A capsule (cylinder with spherical ends) oriented on the x-axis.
"capsule-y"A capsule (cylinder with spherical ends) oriented on the y-axis.
"capsule-z"A capsule (cylinder with spherical ends) oriented on the z-axis.
"cylinder-x"A cylinder oriented on the x-axis.
"cylinder-y"A cylinder oriented on the y-axis.
"cylinder-z"A cylinder oriented on the z-axis.
"hull"Not used.
"compound"A compound convex hull specified in an OBJ file.
"simple-hull"A convex hull automatically generated from the model.
"simple-compound"A compound convex hull automatically generated from the model, using + * sub-meshes.
"static-mesh"The exact shape of the model.
"plane"A plane.
+ * @typedef {string} ShapeType + */ // Originally within EntityItemProperties.cpp const char* shapeTypeNames[] = { "none", diff --git a/libraries/ui/src/ui/TabletScriptingInterface.h b/libraries/ui/src/ui/TabletScriptingInterface.h index 34827117f0..a8c8ddd9c8 100644 --- a/libraries/ui/src/ui/TabletScriptingInterface.h +++ b/libraries/ui/src/ui/TabletScriptingInterface.h @@ -78,7 +78,7 @@ public: QObject* getFlags(); signals: - /** jsdoc + /**jsdoc * Signaled when a tablet message or dialog is created * @function TabletProxy#tabletNotification * @returns {Signal} @@ -205,7 +205,7 @@ public: - /** jsdoc + /**jsdoc * Check if the tablet has a message dialog open * @function TabletProxy#isMessageDialogOpen */ @@ -291,7 +291,7 @@ signals: */ void screenChanged(QVariant type, QVariant url); - /** jsdoc + /**jsdoc * Signaled when the tablet becomes visible or becomes invisible * @function TabletProxy#isTabletShownChanged * @returns {Signal} diff --git a/scripts/developer/tests/dynamics/dynamicsTests.js b/scripts/developer/tests/dynamics/dynamicsTests.js index e9262c9308..db089f09ee 100644 --- a/scripts/developer/tests/dynamics/dynamicsTests.js +++ b/scripts/developer/tests/dynamics/dynamicsTests.js @@ -186,7 +186,7 @@ var prevEntityID = null; for (var i = 0; i < 7; i++) { var newID = Entities.addEntity({ - name: "hinge test " + i, + name: "slider test " + i, type: "Box", color: { blue: 128, green: 40 * i, red: 20 }, dimensions: { x: 0.2, y: 0.1, z: 0.2 }, diff --git a/tools/jsdoc/plugins/hifi.js b/tools/jsdoc/plugins/hifi.js index bb556814e8..1f73f14b2b 100644 --- a/tools/jsdoc/plugins/hifi.js +++ b/tools/jsdoc/plugins/hifi.js @@ -24,13 +24,16 @@ exports.handlers = { '../../libraries/animation/src', '../../libraries/avatars/src', '../../libraries/controllers/src/controllers/', + '../../libraries/graphics-scripting/src/graphics-scripting/', '../../libraries/entities/src', + '../../libraries/model-networking/src/model-networking/', + '../../libraries/octree/src', '../../libraries/networking/src', + '../../libraries/physics/src', '../../libraries/pointers/src', - '../../libraries/render-utils/src', + '../../libraries/script-engine/src', '../../libraries/shared/src', '../../libraries/shared/src/shared', - '../../libraries/script-engine/src', ]; var exts = ['.h', '.cpp'];