From 231d1373b6ac8c48c09f1e9d8e408fcb85fb9878 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Wed, 5 Jun 2019 08:38:34 +1200
Subject: [PATCH 01/30] Update MyAvatar, Avatar JSDoc per recent changes
---
.../src/avatars/ScriptableAvatar.h | 6 +-
interface/src/avatar/MyAvatar.h | 85 +++++++++++++------
libraries/avatars/src/AvatarData.h | 6 ++
3 files changed, 68 insertions(+), 29 deletions(-)
diff --git a/assignment-client/src/avatars/ScriptableAvatar.h b/assignment-client/src/avatars/ScriptableAvatar.h
index 34dc25914f..3ef908bedb 100644
--- a/assignment-client/src/avatars/ScriptableAvatar.h
+++ b/assignment-client/src/avatars/ScriptableAvatar.h
@@ -74,7 +74,8 @@
* avatar. Read-only.
* @property {number} sensorToWorldScale - The scale that transforms dimensions in the user's real world to the avatar's
* size in the virtual world. Read-only.
- * @property {boolean} hasPriority - is the avatar in a Hero zone? Read-only.
+ * @property {boolean} hasPriority - true
if the avatar is in a "hero" zone, false
if it isn't.
+ * Read-only.
*
* @example Create a scriptable avatar.
* (function () {
@@ -138,6 +139,9 @@ public:
/// Returns the index of the joint with the specified name, or -1 if not found/unknown.
Q_INVOKABLE virtual int getJointIndex(const QString& name) const override;
+ /**jsdoc
+ * @comment Uses the base class's JSDoc.
+ */
Q_INVOKABLE virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override;
/**jsdoc
diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h
index 058603f320..95f55c1cf0 100755
--- a/interface/src/avatar/MyAvatar.h
+++ b/interface/src/avatar/MyAvatar.h
@@ -39,6 +39,23 @@ class ModelItemID;
class MyHead;
class DetailedMotionState;
+/**jsdoc
+ * Locomotion control types.
+ *
+ *
+ * Value | Name | Description |
+ *
+ *
+ * 0 | Default | Your walking speed is constant; it doesn't change depending on how far
+ * forward you push your controller's joystick. Fully pushing your joystick forward makes your avatar run. |
+ * 1 | Analog | Your walking speed changes in steps based on how far forward you push your
+ * controller's joystick. Fully pushing your joystick forward makes your avatar run. |
+ * 2 | AnalogPlus | Your walking speed changes proportionally to how far forward you push
+ * your controller's joystick. Fully pushing your joystick forward makes your avatar run. |
+ *
+ *
+ * @typedef {number} MyAvatar.LocomotionControlsMode
+ */
enum LocomotionControlsMode {
CONTROLS_DEFAULT = 0,
CONTROLS_ANALOG,
@@ -128,6 +145,8 @@ class MyAvatar : public Avatar {
* avatar. Read-only.
* @property {number} sensorToWorldScale - The scale that transforms dimensions in the user's real world to the avatar's
* size in the virtual world. Read-only.
+ * @property {boolean} hasPriority - true
if the avatar is in a "hero" zone, false
if it isn't.
+ * Read-only.
*
* @comment IMPORTANT: This group of properties is copied from Avatar.h; they should NOT be edited here.
* @property {Vec3} skeletonOffset - Can be used to apply a translation offset between the avatar's position and the
@@ -239,9 +258,14 @@ class MyAvatar : public Avatar {
* where MyAvatar.sessionUUID is not available (e.g., if not connected to a domain). Note: Likely to be deprecated.
* Read-only.
*
- * @property {number} walkSpeed - The walk speed of your avatar.
- * @property {number} walkBackwardSpeed - The walk backward speed of your avatar.
- * @property {number} sprintSpeed - The sprint speed of your avatar.
+ * @property {number} walkSpeed - The walk speed of your avatar for the current control scheme (see
+ * {@link MyAvatar.getControlScheme|getControlScheme}).
+ * @property {number} walkBackwardSpeed - The walk backward speed of your avatar for the current control scheme (see
+ * {@link MyAvatar.getControlScheme|getControlScheme}).
+ * @property {number} sprintSpeed - The sprint (run) speed of your avatar for the current control scheme (see
+ * {@link MyAvatar.getControlScheme|getControlScheme}).
+ * @property {number} analogPlusWalkSpeed - The walk speed of your avatar for the "AnalogPlus" control scheme.
+ * @property {number} analogPlusSprintSpeed - The sprint speed of your avatar for the "AnalogPlus" control scheme.
* @property {MyAvatar.SitStandModelType} userRecenterModel - Controls avatar leaning and recentering behavior.
* @property {number} isInSittingState - true
if your avatar is sitting (avatar leaning is disabled,
* recenntering is enabled), false
if it is standing (avatar leaning is enabled, and avatar recenters if it
@@ -281,6 +305,7 @@ class MyAvatar : public Avatar {
* @borrows Avatar.updateAvatarEntity as updateAvatarEntity
* @borrows Avatar.clearAvatarEntity as clearAvatarEntity
* @borrows Avatar.setForceFaceTrackerConnected as setForceFaceTrackerConnected
+ * @borrows Avatar.setSkeletonModelURL as setSkeletonModelURL
* @borrows Avatar.getAttachmentData as getAttachmentData
* @borrows Avatar.setAttachmentData as setAttachmentData
* @borrows Avatar.attach as attach
@@ -308,7 +333,6 @@ class MyAvatar : public Avatar {
* @comment Avatar.setAbsoluteJointTranslationInObjectFrame as setAbsoluteJointTranslationInObjectFrame - Don't borrow because implementation is different.
* @borrows Avatar.getTargetScale as getTargetScale
* @borrows Avatar.resetLastSent as resetLastSent
- * @borrows Avatar.hasPriority as hasPriority
*/
// FIXME: `glm::vec3 position` is not accessible from QML, so this exposes position in a QML-native type
Q_PROPERTY(QVector3D qmlPosition READ getQmlPosition)
@@ -789,26 +813,34 @@ public:
*/
Q_INVOKABLE void setSnapTurn(bool on) { _useSnapTurn = on; }
- /**
+ /**jsdoc
+ * Gets the control scheme that is in use.
* @function MyAvatar.getControlScheme
- * @returns {number}
- */
+ * @returns {MyAvatar.LocomotionControlsMode} The control scheme that is in use.
+ */
Q_INVOKABLE int getControlScheme() const { return _controlSchemeIndex; }
- /**
+ /**jsdoc
+ * Sets the control scheme to use.
* @function MyAvatar.setControlScheme
- * @param {number} index
- */
+ * @param {MyAvatar.LocomotionControlsMode} controlScheme - The control scheme to use.
+ */
Q_INVOKABLE void setControlScheme(int index) { _controlSchemeIndex = (index >= 0 && index <= 2) ? index : 0; }
/**jsdoc
+ * Gets whether your avatar hovers when its feet are not on the ground.
* @function MyAvatar.hoverWhenUnsupported
- * @returns {boolean}
+ * @returns {boolean} true
if your avatar hovers when its feet are not on the ground, false
if it
+ * falls.
*/
+ // FIXME: Should be named, getHoverWhenUnsupported().
Q_INVOKABLE bool hoverWhenUnsupported() const { return _hoverWhenUnsupported; }
+
/**jsdoc
+ * Sets whether your avatar hovers when its feet are not on the ground.
* @function MyAvatar.setHoverWhenUnsupported
- * @param {boolean} on
+ * @param {boolean} hover - true
if your avatar hovers when its feet are not on the ground, false
+ * if it falls.
*/
Q_INVOKABLE void setHoverWhenUnsupported(bool on) { _hoverWhenUnsupported = on; }
@@ -826,15 +858,19 @@ public:
* @returns {string} "left"
for the left hand, "right"
for the right hand.
*/
Q_INVOKABLE QString getDominantHand() const;
+
/**jsdoc
- * @function MyAVatar.setStrafeEnabled
- * @param {bool} enabled
- */
+ * Sets whether strafing is enabled.
+ * @function MyAvatar.setStrafeEnabled
+ * @param {boolean} enabled - true
if strafing is enabled, false
if it isn't.
+ */
Q_INVOKABLE void setStrafeEnabled(bool enabled);
+
/**jsdoc
- * @function MyAvatar.getStrafeEnabled
- * @returns {bool}
- */
+ * Gets whether strafing is enabled.
+ * @function MyAvatar.getStrafeEnabled
+ * @returns {boolean} true
if strafing is enabled, false
if it isn't.
+ */
Q_INVOKABLE bool getStrafeEnabled() const;
/**jsdoc
* @function MyAvatar.setHmdAvatarAlignmentType
@@ -1495,18 +1531,8 @@ public:
*/
Q_INVOKABLE float getDriveGear5();
- /**jsdoc
- * Choose the control scheme.
- * @function MyAvatar.setControlSchemeIndex
- * @param {number} Choose the control scheme to be used.
- */
void setControlSchemeIndex(int index);
- /**jsdoc
- * Check what control scheme is in use.
- * @function MyAvatar.getControlSchemeIndex
- * @returns {number} Returns the index associated with a given control scheme.
- */
int getControlSchemeIndex();
/**jsdoc
@@ -2409,6 +2435,9 @@ private:
void updateEyeContactTarget(float deltaTime);
// These are made private for MyAvatar so that you will use the "use" methods instead
+ /**jsdoc
+ * @comment Borrows the base class's JSDoc.
+ */
Q_INVOKABLE virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override;
virtual void updatePalms() override {}
diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h
index e5131ff94b..5c62e0b2c6 100755
--- a/libraries/avatars/src/AvatarData.h
+++ b/libraries/avatars/src/AvatarData.h
@@ -1211,6 +1211,12 @@ public:
const QString& getDisplayName() const { return _displayName; }
const QString& getSessionDisplayName() const { return _sessionDisplayName; }
bool getLookAtSnappingEnabled() const { return _lookAtSnappingEnabled; }
+
+ /**jsdoc
+ * Sets the avatar's skeleton model.
+ * @function Avatar.setSkeletonModelURL
+ * @param {string} url - The avatar's FST file.
+ */
Q_INVOKABLE virtual void setSkeletonModelURL(const QUrl& skeletonModelURL);
virtual void setDisplayName(const QString& displayName);
From f91c6dec3a24bfefc861ec9ef0c278e4c7973938 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Wed, 5 Jun 2019 08:38:52 +1200
Subject: [PATCH 02/30] Miscellaneous fixes noticed in passing
---
interface/src/avatar/MyAvatar.h | 64 ++++++++++++++++-----------------
1 file changed, 32 insertions(+), 32 deletions(-)
diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h
index 95f55c1cf0..d78aebe0c1 100755
--- a/interface/src/avatar/MyAvatar.h
+++ b/interface/src/avatar/MyAvatar.h
@@ -607,14 +607,13 @@ public:
* the avatar will move in unpredictable ways. For more information about avatar joint orientation standards, see
* Avatar Standards.
* @function MyAvatar.overrideAnimation
- * @param url {string} The URL to the animation file. Animation files need to be FBX format, but only need to contain the
+ * @param {string} url - The URL to the animation file. Animation files need to be FBX format, but only need to contain the
* avatar skeleton and animation data.
- * @param fps {number} The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
- * @param loop {boolean} Set to true if the animation should loop.
- * @param firstFrame {number} The frame the animation should start at.
- * @param lastFrame {number} The frame the animation should end at.
+ * @param {number} fps - The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
+ * @param {boolean} loop - true
if the animation should loop, false
if it shouldn't.
+ * @param {number} firstFrame - The frame to start the animation at.
+ * @param {number} lastFrame - The frame to end the animation at.
* @example Play a clapping animation on your avatar for three seconds.
- * // Clap your hands for 3 seconds then restore animation back to the avatar.
* var ANIM_URL = "https://s3.amazonaws.com/hifi-public/animations/ClapAnimations/ClapHands_Standing.fbx";
* MyAvatar.overrideAnimation(ANIM_URL, 30, true, 0, 53);
* Script.setTimeout(function () {
@@ -625,18 +624,18 @@ public:
Q_INVOKABLE void overrideAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame);
/**jsdoc
- * overrideHandAnimation()
Gets the overrides the default hand poses that are triggered with controller buttons.
- * use {@link MyAvatar.restoreHandAnimation}. to restore the default poses.
+ * Overrides the default hand poses that are triggered with controller buttons.
+ * Use {@link MyAvatar.restoreHandAnimation} to restore the default poses.
* @function MyAvatar.overrideHandAnimation
- * @param isLeft {boolean} Set true if using the left hand
- * @param url {string} The URL to the animation file. Animation files need to be FBX format, but only need to contain the
+ * @param isLeft {boolean} true
to override the left hand, false
to override the right hand.
+ * @param {string} url - The URL of the animation file. Animation files need to be FBX format, but only need to contain the
* avatar skeleton and animation data.
- * @param fps {number} The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
- * @param loop {boolean} Set to true if the animation should loop.
- * @param firstFrame {number} The frame the animation should start at.
- * @param lastFrame {number} The frame the animation should end at
- * @example Override left hand animation for three seconds.
- * // Override the left hand pose then restore the default pose.
+ * @param {number} fps - The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
+ * @param {boolean} loop - true
if the animation should loop, false
if it shouldn't.
+ * @param {number} firstFrame - The frame to start the animation at.
+ * @param {number} lastFrame - The frame to end the animation at.
+ * @example Override left hand animation for three seconds.
+ * var ANIM_URL = "https://s3.amazonaws.com/hifi-public/animations/ClapAnimations/ClapHands_Standing.fbx";
* MyAvatar.overrideHandAnimation(isLeft, ANIM_URL, 30, true, 0, 53);
* Script.setTimeout(function () {
* MyAvatar.restoreHandAnimation();
@@ -653,7 +652,6 @@ public:
* animation, this function has no effect.
* @function MyAvatar.restoreAnimation
* @example Play a clapping animation on your avatar for three seconds.
- * // Clap your hands for 3 seconds then restore animation back to the avatar.
* var ANIM_URL = "https://s3.amazonaws.com/hifi-public/animations/ClapAnimations/ClapHands_Standing.fbx";
* MyAvatar.overrideAnimation(ANIM_URL, 30, true, 0, 53);
* Script.setTimeout(function () {
@@ -663,16 +661,15 @@ public:
Q_INVOKABLE void restoreAnimation();
/**jsdoc
- * Restores the default hand animation state machine that is driven by the state machine in the avatar-animation json.
+ * Restores the default hand animation state machine that is driven by the state machine in the avatar-animation JSON.
* The avatar animation system includes a set of default animations along with rules for how those animations are blended
* together with procedural data (such as look at vectors, hand sensors etc.). Playing your own custom animations will
* override the default animations. restoreHandAnimation()
is used to restore the default hand poses
- * If you aren't currently playing an override hand
- * animation, this function has no effect.
+ * If you aren't currently playing an override hand animation, this function has no effect.
* @function MyAvatar.restoreHandAnimation
* @param isLeft {boolean} Set to true if using the left hand
* @example Override left hand animation for three seconds.
- * // Override the left hand pose then restore the default pose.
+ * var ANIM_URL = "https://s3.amazonaws.com/hifi-public/animations/ClapAnimations/ClapHands_Standing.fbx";
* MyAvatar.overrideHandAnimation(isLeft, ANIM_URL, 30, true, 0, 53);
* Script.setTimeout(function () {
* MyAvatar.restoreHandAnimation();
@@ -713,12 +710,13 @@ public:
* the avatar will move in unpredictable ways. For more information about avatar joint orientation standards, see
* Avatar Standards.
* @function MyAvatar.overrideRoleAnimation
- * @param role {string} The animation role to override
- * @param url {string} The URL to the animation file. Animation files need to be in FBX format, but only need to contain the avatar skeleton and animation data.
- * @param fps {number} The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
- * @param loop {boolean} Set to true if the animation should loop
- * @param firstFrame {number} The frame the animation should start at
- * @param lastFrame {number} The frame the animation should end at
+ * @param {string} role - The animation role to override
+ * @param {string} url - The URL to the animation file. Animation files need to be in FBX format, but only need to contain
+ * the avatar skeleton and animation data.
+ * @param {number} fps - The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
+ * @param {boolean} loop - true
if the animation should loop, false
if it shouldn't.
+ * @param {number} firstFrame - The frame the animation should start at.
+ * @param {number} lastFrame - The frame the animation should end at.
* @example The default avatar-animation.json defines an "idleStand" animation role. This role specifies that when the avatar is not moving,
* an animation clip of the avatar idling with hands hanging at its side will be used. It also specifies that when the avatar moves, the animation
* will smoothly blend to the walking animation used by the "walkFwd" animation role.
@@ -806,8 +804,9 @@ public:
* mode.
*/
Q_INVOKABLE bool getSnapTurn() const { return _useSnapTurn; }
+
/**jsdoc
- * Sets whether your should do snap turns or smooth turns in HMD mode.
+ * Sets whether you do snap turns or smooth turns in HMD mode.
* @function MyAvatar.setSnapTurn
* @param {boolean} on - true
to do snap turns in HMD mode; false
to do smooth turns in HMD mode.
*/
@@ -872,16 +871,17 @@ public:
* @returns {boolean} true
if strafing is enabled, false
if it isn't.
*/
Q_INVOKABLE bool getStrafeEnabled() const;
+
/**jsdoc
+ * Sets the HMD alignment relative to your avatar.
* @function MyAvatar.setHmdAvatarAlignmentType
* @param {string} type - "head"
to align your head and your avatar's head, "eyes"
to align your
* eyes and your avatar's eyes.
- *
*/
Q_INVOKABLE void setHmdAvatarAlignmentType(const QString& type);
/**jsdoc
- * Gets the HMD alignment for your avatar.
+ * Gets the HMD alignment relative to your avatar.
* @function MyAvatar.getHmdAvatarAlignmentType
* @returns {string} "head"
if aligning your head and your avatar's head, "eyes"
if aligning your
* eyes and your avatar's eyes.
@@ -1610,8 +1610,8 @@ public:
Q_INVOKABLE bool getCharacterControllerEnabled(); // deprecated
/**jsdoc
- * @comment Different behavior to the Avatar version of this method.
* Gets the rotation of a joint relative to the avatar.
+ * @comment Different behavior to the Avatar version of this method.
* @function MyAvatar.getAbsoluteJointRotationInObjectFrame
* @param {number} index - The index of the joint.
* @returns {Quat} The rotation of the joint relative to the avatar.
@@ -1623,8 +1623,8 @@ public:
virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override;
/**jsdoc
- * @comment Different behavior to the Avatar version of this method.
* Gets the translation of a joint relative to the avatar.
+ * @comment Different behavior to the Avatar version of this method.
* @function MyAvatar.getAbsoluteJointTranslationInObjectFrame
* @param {number} index - The index of the joint.
* @returns {Vec3} The translation of the joint relative to the avatar.
From caf29dc45a83ec0bb6e262c37943934f3df3a178 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Thu, 6 Jun 2019 11:24:10 +1200
Subject: [PATCH 03/30] Doc review
---
interface/src/avatar/MyAvatar.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h
index d78aebe0c1..b02ff0d805 100755
--- a/interface/src/avatar/MyAvatar.h
+++ b/interface/src/avatar/MyAvatar.h
@@ -265,6 +265,8 @@ class MyAvatar : public Avatar {
* @property {number} sprintSpeed - The sprint (run) speed of your avatar for the current control scheme (see
* {@link MyAvatar.getControlScheme|getControlScheme}).
* @property {number} analogPlusWalkSpeed - The walk speed of your avatar for the "AnalogPlus" control scheme.
+ * Warning: Setting this value also sets the value of analogPlusSprintSpeed
to twice
+ * the value.
* @property {number} analogPlusSprintSpeed - The sprint speed of your avatar for the "AnalogPlus" control scheme.
* @property {MyAvatar.SitStandModelType} userRecenterModel - Controls avatar leaning and recentering behavior.
* @property {number} isInSittingState - true
if your avatar is sitting (avatar leaning is disabled,
@@ -664,7 +666,7 @@ public:
* Restores the default hand animation state machine that is driven by the state machine in the avatar-animation JSON.
* The avatar animation system includes a set of default animations along with rules for how those animations are blended
* together with procedural data (such as look at vectors, hand sensors etc.). Playing your own custom animations will
- * override the default animations. restoreHandAnimation()
is used to restore the default hand poses
+ * override the default animations. restoreHandAnimation()
is used to restore the default hand poses.
* If you aren't currently playing an override hand animation, this function has no effect.
* @function MyAvatar.restoreHandAnimation
* @param isLeft {boolean} Set to true if using the left hand
From 22d602a33406477d3c312f9ce8fe3cc725b32e3e Mon Sep 17 00:00:00 2001
From: Seth Alves
Date: Fri, 7 Jun 2019 14:39:53 -0700
Subject: [PATCH 04/30] CREATE app will now recognize newer-style baked models
and skyboxes as baked in entity-list
---
scripts/system/libraries/entityList.js | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/scripts/system/libraries/entityList.js b/scripts/system/libraries/entityList.js
index d19da2b342..6498c92f17 100644
--- a/scripts/system/libraries/entityList.js
+++ b/scripts/system/libraries/entityList.js
@@ -10,7 +10,7 @@
/* global EntityListTool, Tablet, selectionManager, Entities, Camera, MyAvatar, Vec3, Menu, Messages,
cameraManager, MENU_EASE_ON_FOCUS, deleteSelectedEntities, toggleSelectedEntitiesLocked, toggleSelectedEntitiesVisible,
- keyUpEventFromUIWindow */
+ keyUpEventFromUIWindow, Script, SelectionDisplay, SelectionManager, Clipboard */
var PROFILING_ENABLED = false;
var profileIndent = '';
@@ -148,6 +148,20 @@ EntityListTool = function(shouldUseEditTabletApp) {
return value !== undefined ? value : "";
}
+ function entityIsBaked(properties) {
+ if (properties.type === "Model") {
+ var lowerModelURL = properties.modelURL.toLowerCase();
+ return lowerModelURL.endsWith(".baked.fbx") || lowerModelURL.endsWith(".baked.fst");
+ } else if (properties.type === "Zone") {
+ var lowerSkyboxURL = properties.skybox ? properties.skybox.url.toLowerCase() : "";
+ var lowerAmbientURL = properties.ambientLight ? properties.ambientLight.ambientURL.toLowerCase() : "";
+ return (lowerSkyboxURL === "" || lowerSkyboxURL.endsWith(".texmeta.json")) &&
+ (lowerAmbientURL === "" || lowerAmbientURL.endsWith(".texmeta.json"));
+ } else {
+ return false;
+ }
+ }
+
that.sendUpdate = function() {
PROFILE('Script-sendUpdate', function() {
var entities = [];
@@ -164,7 +178,8 @@ EntityListTool = function(shouldUseEditTabletApp) {
var cameraPosition = Camera.position;
PROFILE("getMultipleProperties", function () {
var multipleProperties = Entities.getMultipleEntityProperties(ids, ['name', 'type', 'locked',
- 'visible', 'renderInfo', 'modelURL', 'materialURL', 'imageURL', 'script', 'certificateID']);
+ 'visible', 'renderInfo', 'modelURL', 'materialURL', 'imageURL', 'script', 'certificateID',
+ 'skybox.url', 'ambientLight.url']);
for (var i = 0; i < multipleProperties.length; i++) {
var properties = multipleProperties[i];
@@ -193,7 +208,7 @@ EntityListTool = function(shouldUseEditTabletApp) {
valueIfDefined(properties.renderInfo.texturesSize) : ""),
hasTransparent: (properties.renderInfo !== undefined ?
valueIfDefined(properties.renderInfo.hasTransparent) : ""),
- isBaked: properties.type === "Model" ? url.toLowerCase().endsWith(".baked.fbx") : false,
+ isBaked: entityIsBaked(properties),
drawCalls: (properties.renderInfo !== undefined ?
valueIfDefined(properties.renderInfo.drawCalls) : ""),
hasScript: properties.script !== ""
From 9c6ca601087c6ea8331c022955020a4deea5631b Mon Sep 17 00:00:00 2001
From: Howard Stearns
Date: Mon, 10 Jun 2019 12:08:51 -0700
Subject: [PATCH 05/30] get windows error first, check for socket changes, and
fix bad Q_OS_WINDOWS ref
---
libraries/networking/src/udt/Socket.cpp | 26 ++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp
index 406c2ff213..6e27fd2483 100644
--- a/libraries/networking/src/udt/Socket.cpp
+++ b/libraries/networking/src/udt/Socket.cpp
@@ -59,10 +59,12 @@ void Socket::bind(const QHostAddress& address, quint16 port) {
auto sd = _udpSocket.socketDescriptor();
int val = IP_PMTUDISC_DONT;
setsockopt(sd, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val));
-#elif defined(Q_OS_WINDOWS)
+#elif defined(Q_OS_WIN)
auto sd = _udpSocket.socketDescriptor();
int val = 0; // false
- setsockopt(sd, IPPROTO_IP, IP_DONTFRAGMENT, &val, sizeof(val));
+ if (setsockopt(sd, IPPROTO_IP, IP_DONTFRAGMENT, (const char *)&val, sizeof(val))) {
+ qCWarning(networking) << "Socket::bind Cannot setsockopt IP_DONTFRAGMENT" << WSAGetLastError();
+ }
#endif
}
}
@@ -231,14 +233,14 @@ qint64 Socket::writeDatagram(const QByteArray& datagram, const HifiSockAddr& soc
return -1;
}
qint64 bytesWritten = _udpSocket.writeDatagram(datagram, sockAddr.getAddress(), sockAddr.getPort());
-
- if (bytesWritten < 0) {
- qCDebug(networking) << "udt::writeDatagram (" << _udpSocket.state() << ") error - " << _udpSocket.error() << "(" << _udpSocket.errorString() << ")";
-
+ int pending = _udpSocket.bytesToWrite();
+ if (bytesWritten < 0 || pending) {
+ int wsaError = 0;
#ifdef WIN32
- int wsaError = WSAGetLastError();
- qCDebug(networking) << "windows socket error " << wsaError;
+ wsaError = WSAGetLastError();
#endif
+ qCDebug(networking) << "udt::writeDatagram (" << _udpSocket.state() << ") error - " << wsaError << _udpSocket.error() << "(" << _udpSocket.errorString() << ")"
+ << (pending ? "pending bytes:" : "pending:") << pending;
#ifdef DEBUG_EVENT_QUEUE
int nodeListQueueSize = ::hifi::qt::getEventQueueSize(thread());
@@ -506,11 +508,13 @@ std::vector Socket::getConnectionSockAddrs() {
}
void Socket::handleSocketError(QAbstractSocket::SocketError socketError) {
- qCDebug(networking) << "udt::Socket (" << _udpSocket.state() << ") error - " << socketError << "(" << _udpSocket.errorString() << ")";
+ int wsaError = 0;
#ifdef WIN32
- int wsaError = WSAGetLastError();
- qCDebug(networking) << "windows socket error " << wsaError;
+ wsaError = WSAGetLastError();
#endif
+ int pending = _udpSocket.bytesToWrite();
+ qCDebug(networking) << "udt::Socket (" << _udpSocket.state() << ") error - " << wsaError << socketError << "(" << _udpSocket.errorString() << ")"
+ << (pending ? "pending bytes:" : "pending:") << pending;
#ifdef DEBUG_EVENT_QUEUE
int nodeListQueueSize = ::hifi::qt::getEventQueueSize(thread());
qCDebug(networking) << "Networking queue size - " << nodeListQueueSize;
From a400cea0404dc5b936799031ee23e1d1271528e7 Mon Sep 17 00:00:00 2001
From: sabrina-shanman
Date: Mon, 10 Jun 2019 14:00:05 -0700
Subject: [PATCH 06/30] Fix crash when using null DisplayPlugin in
GraphicsEngine during shutdown
---
interface/src/graphics/GraphicsEngine.cpp | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/interface/src/graphics/GraphicsEngine.cpp b/interface/src/graphics/GraphicsEngine.cpp
index 4f8b86cc0c..7f9a612697 100644
--- a/interface/src/graphics/GraphicsEngine.cpp
+++ b/interface/src/graphics/GraphicsEngine.cpp
@@ -132,6 +132,10 @@ static const int THROTTLED_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / THROTTLED_SI
bool GraphicsEngine::shouldPaint() const {
auto displayPlugin = qApp->getActiveDisplayPlugin();
+ if (!displayPlugin) {
+ // We're shutting down
+ return false;
+ }
#ifdef DEBUG_PAINT_DELAY
static uint64_t paintDelaySamples{ 0 };
@@ -175,6 +179,10 @@ void GraphicsEngine::render_performFrame() {
{
PROFILE_RANGE(render, "/getActiveDisplayPlugin");
displayPlugin = qApp->getActiveDisplayPlugin();
+ if (!displayPlugin) {
+ // We're shutting down
+ return;
+ }
}
{
From 67995a8677f1ac15eb5de9610a06de80ea394e46 Mon Sep 17 00:00:00 2001
From: Seth Alves
Date: Mon, 10 Jun 2019 14:25:44 -0700
Subject: [PATCH 07/30] don't divide by zero if a grid entity-item has a zero
dimension
---
libraries/render-utils/src/GeometryCache.cpp | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp
index 7bd6f88d71..88cca1693b 100644
--- a/libraries/render-utils/src/GeometryCache.cpp
+++ b/libraries/render-utils/src/GeometryCache.cpp
@@ -939,6 +939,11 @@ void GeometryCache::renderWireSphere(gpu::Batch& batch, const glm::vec4& color)
void GeometryCache::renderGrid(gpu::Batch& batch, const glm::vec2& minCorner, const glm::vec2& maxCorner,
int majorRows, int majorCols, float majorEdge, int minorRows, int minorCols, float minorEdge,
const glm::vec4& color, bool forward, int id) {
+
+ if (majorRows == 0 || majorCols == 0) {
+ return;
+ }
+
Vec2FloatPair majorKey(glm::vec2(majorRows, majorCols), majorEdge);
Vec2FloatPair minorKey(glm::vec2(minorRows, minorCols), minorEdge);
Vec2FloatPairPair key(majorKey, minorKey);
@@ -962,8 +967,8 @@ void GeometryCache::renderGrid(gpu::Batch& batch, const glm::vec2& minCorner, co
gridBuffer.edit().period = glm::vec4(majorRows, majorCols, minorRows, minorCols);
gridBuffer.edit().offset.x = -(majorEdge / majorRows) / 2;
gridBuffer.edit().offset.y = -(majorEdge / majorCols) / 2;
- gridBuffer.edit().offset.z = -(minorEdge / minorRows) / 2;
- gridBuffer.edit().offset.w = -(minorEdge / minorCols) / 2;
+ gridBuffer.edit().offset.z = minorRows == 0 ? 0 : -(minorEdge / minorRows) / 2;
+ gridBuffer.edit().offset.w = minorCols == 0 ? 0 : -(minorEdge / minorCols) / 2;
gridBuffer.edit().edge = glm::vec4(glm::vec2(majorEdge),
// If rows or columns are not set, do not draw minor gridlines
glm::vec2((minorRows != 0 && minorCols != 0) ? minorEdge : 0.0f));
From 654b5775e17bf14f0a5d6dad7d86927698ae833a Mon Sep 17 00:00:00 2001
From: "Anthony J. Thibault"
Date: Mon, 10 Jun 2019 15:05:34 -0700
Subject: [PATCH 08/30] Crash fix for ResourceCache::getResource()
A wrong 'read' locker is used around a critical section that actually modifies the _resources QHash.
This can result in memory corruption and seg faults.
---
libraries/networking/src/ResourceCache.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp
index 44d3d1ee4d..ef8a7b577d 100644
--- a/libraries/networking/src/ResourceCache.cpp
+++ b/libraries/networking/src/ResourceCache.cpp
@@ -346,7 +346,7 @@ void ResourceCache::setRequestLimit(uint32_t limit) {
QSharedPointer ResourceCache::getResource(const QUrl& url, const QUrl& fallback, void* extra, size_t extraHash) {
QSharedPointer resource;
{
- QReadLocker locker(&_resourcesLock);
+ QWriteLocker locker(&_resourcesLock);
auto& resourcesWithExtraHash = _resources[url];
auto resourcesWithExtraHashIter = resourcesWithExtraHash.find(extraHash);
if (resourcesWithExtraHashIter != resourcesWithExtraHash.end()) {
From dbce9768873f57dd089cf2dcd069b7fb3131c6c7 Mon Sep 17 00:00:00 2001
From: Andrew Meadows
Date: Mon, 10 Jun 2019 15:34:18 -0700
Subject: [PATCH 09/30] fix another crash in
MyAvatar::getAvatarEntitiesVariant()
---
interface/src/avatar/MyAvatar.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp
index b91217da63..3800a330bb 100644
--- a/interface/src/avatar/MyAvatar.cpp
+++ b/interface/src/avatar/MyAvatar.cpp
@@ -2488,12 +2488,12 @@ QVariantList MyAvatar::getAvatarEntitiesVariant() {
QVariantMap avatarEntityData;
avatarEntityData["id"] = entityID;
EntityItemProperties entityProperties = entity->getProperties(desiredProperties);
- QScriptValue scriptProperties;
{
std::lock_guard guard(_scriptEngineLock);
+ QScriptValue scriptProperties;
scriptProperties = EntityItemPropertiesToScriptValue(_scriptEngine, entityProperties);
+ avatarEntityData["properties"] = scriptProperties.toVariant();
}
- avatarEntityData["properties"] = scriptProperties.toVariant();
avatarEntitiesData.append(QVariant(avatarEntityData));
}
}
From 7ce5f7ac0b3a4bbd172bf17419d8de4b130478fc Mon Sep 17 00:00:00 2001
From: "Anthony J. Thibault"
Date: Mon, 10 Jun 2019 16:27:03 -0700
Subject: [PATCH 10/30] Adjust run and jog anims to better align head with 1p
camera
Added adjust forward run and jog animations to better align with first person camera.
In some instances, such as looking down, you could sometimes see your body lead your camera.
https://highfidelity.atlassian.net/browse/BUGZ-240
---
.../resources/avatar/animations/jog_fwd.fbx | Bin 892208 -> 928272 bytes
.../resources/avatar/animations/run_fwd.fbx | Bin 940272 -> 940528 bytes
.../resources/avatar/avatar-animation.json | 10 +++++-----
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/interface/resources/avatar/animations/jog_fwd.fbx b/interface/resources/avatar/animations/jog_fwd.fbx
index 3c3b8118ab9ecf2988df13b7534ddeac181d72ec..f389fea36414926df660370b1ed73206bc752ad7 100644
GIT binary patch
literal 928272
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