From 6ecf850159d4d1f43826aa2a6ca47fcab3d665f6 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 6 Nov 2018 12:37:55 -0800 Subject: [PATCH 1/4] clarify ShapeInfo::setCapsuleY() API and use it correctly --- .../src/avatars-renderer/Avatar.cpp | 17 ++++++------- libraries/shared/src/ShapeInfo.cpp | 24 +++++++++---------- libraries/shared/src/ShapeInfo.h | 2 +- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index f694148b30..03938dd3de 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -1724,22 +1724,23 @@ void Avatar::computeShapeInfo(ShapeInfo& shapeInfo) { } void Avatar::getCapsule(glm::vec3& start, glm::vec3& end, float& radius) { - // FIXME: this doesn't take into account Avatar rotation ShapeInfo shapeInfo; computeShapeInfo(shapeInfo); - glm::vec3 halfExtents = shapeInfo.getHalfExtents(); // x = radius, y = halfHeight - start = getWorldPosition() - glm::vec3(0, halfExtents.y, 0) + shapeInfo.getOffset(); - end = getWorldPosition() + glm::vec3(0, halfExtents.y, 0) + shapeInfo.getOffset(); + glm::vec3 halfExtents = shapeInfo.getHalfExtents(); // x = radius, y = cylinderHalfHeight + radius radius = halfExtents.x; + glm::vec3 halfCylinderAxis(0.0f, halfExtents.y - radius, 0.0f); + Transform transform = getTransform(); + start = transform.getTranslation() + transform.getRotation() * (shapeInfo.getOffset() - halfCylinderAxis); + end = transform.getTranslation() + transform.getRotation() * (shapeInfo.getOffset() + halfCylinderAxis); } glm::vec3 Avatar::getWorldFeetPosition() { ShapeInfo shapeInfo; - computeShapeInfo(shapeInfo); - glm::vec3 halfExtents = shapeInfo.getHalfExtents(); // x = radius, y = halfHeight - glm::vec3 localFeet(0.0f, shapeInfo.getOffset().y - halfExtents.y - halfExtents.x, 0.0f); - return getWorldOrientation() * localFeet + getWorldPosition(); + glm::vec3 halfExtents = shapeInfo.getHalfExtents(); // x = radius, y = cylinderHalfHeight + radius + glm::vec3 localFeet(0.0f, shapeInfo.getOffset().y - halfExtents.y, 0.0f); + Transform transform = getTransform(); + return transform.getTranslation() + transform.getRotation() * localFeet; } float Avatar::computeMass() { diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index 152e305bf2..52a8ad7254 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -148,12 +148,12 @@ void ShapeInfo::setPointCollection(const ShapeInfo::PointCollection& pointCollec _hashKey.clear(); } -void ShapeInfo::setCapsuleY(float radius, float halfHeight) { +void ShapeInfo::setCapsuleY(float radius, float cylinderHalfHeight) { _url = ""; _type = SHAPE_TYPE_CAPSULE_Y; radius = glm::max(radius, MIN_HALF_EXTENT); - halfHeight = glm::max(halfHeight, 0.0f); - _halfExtents = glm::vec3(radius, halfHeight, radius); + cylinderHalfHeight = glm::max(cylinderHalfHeight, 0.0f); + _halfExtents = glm::vec3(radius, cylinderHalfHeight + radius, radius); _hashKey.clear(); } @@ -262,26 +262,26 @@ bool ShapeInfo::contains(const glm::vec3& point) const { return glm::length(glm::vec2(point.x, point.y)) <= _halfExtents.y; case SHAPE_TYPE_CAPSULE_X: { if (glm::abs(point.x) <= _halfExtents.x) { - return glm::length(glm::vec2(point.y, point.z)) <= _halfExtents.z; + return glm::length(glm::vec2(point.y, point.z)) <= _halfExtents.y; } else { - glm::vec3 absPoint = glm::abs(point) - _halfExtents.x; - return glm::length(absPoint) <= _halfExtents.z; + glm::vec3 absPoint = glm::abs(point) - glm::vec3(_halfExtents.x, 0.0f, 0.0f); + return glm::length(absPoint) <= _halfExtents.y; } } case SHAPE_TYPE_CAPSULE_Y: { if (glm::abs(point.y) <= _halfExtents.y) { - return glm::length(glm::vec2(point.x, point.z)) <= _halfExtents.x; + return glm::length(glm::vec2(point.x, point.z)) <= _halfExtents.z; } else { - glm::vec3 absPoint = glm::abs(point) - _halfExtents.y; - return glm::length(absPoint) <= _halfExtents.x; + glm::vec3 absPoint = glm::abs(point) - glm::vec3(0.0f, _halfExtents.y, 0.0f); + return glm::length(absPoint) <= _halfExtents.z; } } case SHAPE_TYPE_CAPSULE_Z: { if (glm::abs(point.z) <= _halfExtents.z) { - return glm::length(glm::vec2(point.x, point.y)) <= _halfExtents.y; + return glm::length(glm::vec2(point.x, point.y)) <= _halfExtents.x; } else { - glm::vec3 absPoint = glm::abs(point) - _halfExtents.z; - return glm::length(absPoint) <= _halfExtents.y; + glm::vec3 absPoint = glm::abs(point) - glm::vec3(0.0f, 0.0f, _halfExtents.z); + return glm::length(absPoint) <= _halfExtents.x; } } case SHAPE_TYPE_BOX: diff --git a/libraries/shared/src/ShapeInfo.h b/libraries/shared/src/ShapeInfo.h index 5020e492cf..16e260d9db 100644 --- a/libraries/shared/src/ShapeInfo.h +++ b/libraries/shared/src/ShapeInfo.h @@ -67,7 +67,7 @@ public: void setBox(const glm::vec3& halfExtents); void setSphere(float radius); void setPointCollection(const PointCollection& pointCollection); - void setCapsuleY(float radius, float halfHeight); + void setCapsuleY(float radius, float cylinderHalfHeight); void setOffset(const glm::vec3& offset); ShapeType getType() const { return _type; } From b38c263e604ef9663ce3e4ab1d4e644ecb7b3eee Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 6 Nov 2018 12:44:14 -0800 Subject: [PATCH 2/4] use correct capsule dimensions in teleport.js --- .../controllers/controllerModules/teleport.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/scripts/system/controllers/controllerModules/teleport.js b/scripts/system/controllers/controllerModules/teleport.js index 1aba6b92f6..44aa04b497 100644 --- a/scripts/system/controllers/controllerModules/teleport.js +++ b/scripts/system/controllers/controllerModules/teleport.js @@ -358,9 +358,9 @@ Script.include("/~/system/libraries/controllers.js"); var sensorToWorldScale = MyAvatar.getSensorToWorldScale(); - var radius = capsuleData.radius / sensorToWorldScale; - var height = (Vec3.distance(capsuleData.start, capsuleData.end) + (capsuleData.radius * 2.0)) / sensorToWorldScale; - var capsuleRatio = 10.0 * radius / height; + var diameter = 2.0 * capsuleData.radius / sensorToWorldScale; + var height = (Vec3.distance(capsuleData.start, capsuleData.end) + diameter) / sensorToWorldScale; + var capsuleRatio = 5.0 * diameter / height; var offset = _this.pickHeightOffset * capsuleRatio; _this.teleportHandCollisionPick = Picks.createPick(PickType.Collision, { @@ -370,9 +370,9 @@ Script.include("/~/system/libraries/controllers.js"); shape: { shapeType: "capsule-y", dimensions: { - x: radius * 2.0, - y: height - (radius * 2.0), - z: radius * 2.0 + x: diameter, + y: height, + z: diameter } }, position: { x: 0, y: offset + height * 0.5, z: 0 }, @@ -386,9 +386,9 @@ Script.include("/~/system/libraries/controllers.js"); shape: { shapeType: "capsule-y", dimensions: { - x: radius * 2.0, - y: height - (radius * 2.0), - z: radius * 2.0 + x: diameter, + y: height, + z: diameter } }, position: { x: 0, y: offset + height * 0.5, z: 0 }, From 91f6a5057a884ee1b226043d74f64c84ec772a00 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 6 Nov 2018 12:54:56 -0800 Subject: [PATCH 3/4] correct capsule height when building btCapsuleShape --- libraries/physics/src/ShapeFactory.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/physics/src/ShapeFactory.cpp b/libraries/physics/src/ShapeFactory.cpp index 8057eb0e0c..d7ba2f0661 100644 --- a/libraries/physics/src/ShapeFactory.cpp +++ b/libraries/physics/src/ShapeFactory.cpp @@ -307,21 +307,21 @@ const btCollisionShape* ShapeFactory::createShapeFromInfo(const ShapeInfo& info) case SHAPE_TYPE_CAPSULE_Y: { glm::vec3 halfExtents = info.getHalfExtents(); float radius = halfExtents.x; - float height = 2.0f * halfExtents.y; + float height = 2.0f * (halfExtents.y - radius); shape = new btCapsuleShape(radius, height); } break; case SHAPE_TYPE_CAPSULE_X: { glm::vec3 halfExtents = info.getHalfExtents(); float radius = halfExtents.y; - float height = 2.0f * halfExtents.x; + float height = 2.0f * (halfExtents.x - radius); shape = new btCapsuleShapeX(radius, height); } break; case SHAPE_TYPE_CAPSULE_Z: { glm::vec3 halfExtents = info.getHalfExtents(); float radius = halfExtents.x; - float height = 2.0f * halfExtents.z; + float height = 2.0f * (halfExtents.z - radius); shape = new btCapsuleShapeZ(radius, height); } break; From 5bfb9c1f71bf2f6a569956f6911f1a27db2a5847 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 8 Nov 2018 08:39:43 -0800 Subject: [PATCH 4/4] fix ShapeInfo::contains() logic for capsule shapes --- libraries/shared/src/ShapeInfo.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index 52a8ad7254..df8e61114d 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -261,7 +261,7 @@ bool ShapeInfo::contains(const glm::vec3& point) const { case SHAPE_TYPE_CYLINDER_Z: return glm::length(glm::vec2(point.x, point.y)) <= _halfExtents.y; case SHAPE_TYPE_CAPSULE_X: { - if (glm::abs(point.x) <= _halfExtents.x) { + if (glm::abs(point.x) <= _halfExtents.x - _halfExtents.y) { return glm::length(glm::vec2(point.y, point.z)) <= _halfExtents.y; } else { glm::vec3 absPoint = glm::abs(point) - glm::vec3(_halfExtents.x, 0.0f, 0.0f); @@ -269,7 +269,7 @@ bool ShapeInfo::contains(const glm::vec3& point) const { } } case SHAPE_TYPE_CAPSULE_Y: { - if (glm::abs(point.y) <= _halfExtents.y) { + if (glm::abs(point.y) <= _halfExtents.y - _halfExtents.z) { return glm::length(glm::vec2(point.x, point.z)) <= _halfExtents.z; } else { glm::vec3 absPoint = glm::abs(point) - glm::vec3(0.0f, _halfExtents.y, 0.0f); @@ -277,7 +277,7 @@ bool ShapeInfo::contains(const glm::vec3& point) const { } } case SHAPE_TYPE_CAPSULE_Z: { - if (glm::abs(point.z) <= _halfExtents.z) { + if (glm::abs(point.z) <= _halfExtents.z - _halfExtents.x) { return glm::length(glm::vec2(point.x, point.y)) <= _halfExtents.x; } else { glm::vec3 absPoint = glm::abs(point) - glm::vec3(0.0f, 0.0f, _halfExtents.z);