Merge pull request #14358 from AndrewMeadows/fix-capsuleY

Case 18436: consistent handling of CapsuleShape dimensions
This commit is contained in:
John Conklin II 2018-11-12 15:25:42 -08:00 committed by GitHub
commit 0370c60398
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 37 additions and 36 deletions

View file

@ -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() {

View file

@ -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;

View file

@ -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();
}
@ -261,27 +261,27 @@ 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) {
return glm::length(glm::vec2(point.y, point.z)) <= _halfExtents.z;
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) - _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;
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) - _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;
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) - _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:

View file

@ -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; }

View file

@ -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 },