diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h
index b1d69972aa..a259638371 100644
--- a/libraries/entities/src/EntityScriptingInterface.h
+++ b/libraries/entities/src/EntityScriptingInterface.h
@@ -928,6 +928,23 @@ public slots:
* @returns {Quat} The rotation of the joint in the entity's coordinate frame 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);
@@ -953,6 +970,23 @@ public slots:
* @param {Quat} rotation - The rotation relative to the entity's coordinate frame 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 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);
@@ -976,6 +1010,21 @@ public slots:
* @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);
@@ -1001,6 +1050,22 @@ public slots:
* @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);
@@ -1026,6 +1091,36 @@ public slots:
* @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);
@@ -1054,6 +1149,20 @@ public slots:
* @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);
@@ -1064,6 +1173,20 @@ public slots:
* @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);