Bug fixes for Avatar::getEyeHeight() when no feet joints are present

This commit is contained in:
Anthony J. Thibault 2017-08-25 18:23:19 -07:00
parent 3ac09b7716
commit 937f400534
2 changed files with 12 additions and 5 deletions

View file

@ -103,6 +103,7 @@ class MyAvatar : public Avatar {
* @property useAdvancedMovementControls {bool} Stores the user preference only, does not change user mappings, this is done in the defaultScript
* "scripts/system/controllers/toggleAdvancedMovementForHandControllers.js".
* @property userHeight {number} The height of the user in sensor space. (meters).
* @property userEyeHeight {number} Estimated height of the users eyes in sensor space. (meters)
*/
// FIXME: `glm::vec3 position` is not accessible from QML, so this exposes position in a QML-native type
@ -145,6 +146,7 @@ class MyAvatar : public Avatar {
Q_PROPERTY(float hmdRollControlRate READ getHMDRollControlRate WRITE setHMDRollControlRate)
Q_PROPERTY(float userHeight READ getUserHeight WRITE setUserHeight)
Q_PROPERTY(float userEyeHeight READ getUserEyeHeight)
const QString DOMINANT_LEFT_HAND = "left";
const QString DOMINANT_RIGHT_HAND = "right";
@ -525,8 +527,8 @@ public:
Q_INVOKABLE bool isUp(const glm::vec3& direction) { return glm::dot(direction, _worldUpDirection) > 0.0f; }; // true iff direction points up wrt avatar's definition of up.
Q_INVOKABLE bool isDown(const glm::vec3& direction) { return glm::dot(direction, _worldUpDirection) < 0.0f; };
float getUserHeight() const;
void setUserHeight(float value);
float getUserHeight() const;
float getUserEyeHeight() const;
public slots:

View file

@ -1579,6 +1579,8 @@ float Avatar::getEyeHeight() const {
}
// TODO: if performance becomes a concern we can cache this value rather then computing it everytime.
// Makes assumption that the y = 0 plane in geometry is the ground plane.
// We also make that assumption in Rig::computeAvatarBoundingCapsule()
float avatarScale = getUniformScale();
if (_skeletonModel) {
auto& rig = _skeletonModel->getRig();
@ -1592,7 +1594,8 @@ float Avatar::getEyeHeight() const {
return eyeHeight;
} else if (eyeJoint >= 0) {
// measure eyes to y = 0 plane.
float eyeHeight = rig.getAbsoluteDefaultPose(eyeJoint).trans().y;
float groundHeight = transformPoint(rig.getGeometryToRigTransform(), glm::vec3(0.0f)).y;
float eyeHeight = rig.getAbsoluteDefaultPose(eyeJoint).trans().y - groundHeight;
return eyeHeight;
} else if (headTopJoint >= 0 && toeJoint >= 0) {
// measure toe to top of head. Note: default poses already include avatar scale factor
@ -1601,12 +1604,14 @@ float Avatar::getEyeHeight() const {
return height - height * ratio;
} else if (headTopJoint >= 0) {
const float ratio = DEFAULT_AVATAR_EYE_TO_TOP_OF_HEAD / DEFAULT_AVATAR_HEIGHT;
float height = rig.getAbsoluteDefaultPose(headTopJoint).trans().y;
return height - height * ratio;
float groundHeight = transformPoint(rig.getGeometryToRigTransform(), glm::vec3(0.0f)).y;
float headHeight = rig.getAbsoluteDefaultPose(headTopJoint).trans().y - groundHeight;
return headHeight - headHeight * ratio;
} else if (headJoint >= 0) {
float groundHeight = transformPoint(rig.getGeometryToRigTransform(), glm::vec3(0.0f)).y;
const float DEFAULT_AVATAR_NECK_TO_EYE = DEFAULT_AVATAR_NECK_TO_TOP_OF_HEAD - DEFAULT_AVATAR_EYE_TO_TOP_OF_HEAD;
const float ratio = DEFAULT_AVATAR_NECK_TO_EYE / DEFAULT_AVATAR_NECK_HEIGHT;
float neckHeight = rig.getAbsoluteDefaultPose(headJoint).trans().y;
float neckHeight = rig.getAbsoluteDefaultPose(headJoint).trans().y - groundHeight;
return neckHeight + neckHeight * ratio;
} else {
return avatarScale * DEFAULT_AVATAR_EYE_HEIGHT;