Merge pull request #1033 from HifiExperiments/skyboxShape

Non-uniformly scaled sphere zones and models behave like ellipsoids (and fix EntityItem::contains sphere case)
This commit is contained in:
Kalila 2021-03-03 16:15:47 -05:00 committed by GitHub
commit 053548cd14
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 24 additions and 33 deletions

View file

@ -1772,13 +1772,11 @@ bool EntityItem::contains(const glm::vec3& point) const {
ShapeType shapeType = getShapeType(); ShapeType shapeType = getShapeType();
if (shapeType == SHAPE_TYPE_SPHERE) { if (shapeType == SHAPE_TYPE_SPHERE) {
// SPHERE case is special:
// anything with shapeType == SPHERE must collide as a bounding sphere in the world-frame regardless of dimensions
// therefore we must do math using an unscaled localPoint relative to sphere center
glm::vec3 dimensions = getScaledDimensions(); glm::vec3 dimensions = getScaledDimensions();
glm::vec3 localPoint = point - (getWorldPosition() + getWorldOrientation() * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()) + getPivot())); if (dimensions.x == dimensions.y && dimensions.y == dimensions.z) {
const float HALF_SQUARED = 0.25f; glm::vec3 localPoint = point - (getWorldPosition() + getWorldOrientation() * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()) + getPivot()));
return glm::length2(localPoint) < HALF_SQUARED * glm::length2(dimensions); return glm::length2(localPoint) < glm::length2(0.5f * dimensions.x);
}
} }
// we transform into the "normalized entity-frame" where the bounding box is centered on the origin // we transform into the "normalized entity-frame" where the bounding box is centered on the origin
@ -1805,6 +1803,7 @@ bool EntityItem::contains(const glm::vec3& point) const {
localPoint = glm::abs(localPoint); localPoint = glm::abs(localPoint);
return glm::all(glm::lessThanEqual(localPoint, glm::vec3(NORMALIZED_HALF_SIDE))); return glm::all(glm::lessThanEqual(localPoint, glm::vec3(NORMALIZED_HALF_SIDE)));
} }
case SHAPE_TYPE_SPHERE:
case SHAPE_TYPE_ELLIPSOID: { case SHAPE_TYPE_ELLIPSOID: {
// since we've transformed into the normalized space this is just a sphere-point intersection test // since we've transformed into the normalized space this is just a sphere-point intersection test
return glm::length2(localPoint) <= NORMALIZED_RADIUS_SQUARED; return glm::length2(localPoint) <= NORMALIZED_RADIUS_SQUARED;

View file

@ -270,7 +270,6 @@ void ZoneEntityItem::debugDump() const {
} }
void ZoneEntityItem::setShapeType(ShapeType type) { void ZoneEntityItem::setShapeType(ShapeType type) {
ShapeType oldShapeType = _shapeType;
switch(type) { switch(type) {
case SHAPE_TYPE_NONE: case SHAPE_TYPE_NONE:
case SHAPE_TYPE_CAPSULE_X: case SHAPE_TYPE_CAPSULE_X:
@ -288,7 +287,12 @@ void ZoneEntityItem::setShapeType(ShapeType type) {
default: default:
break; break;
} }
_shapeType = type;
ShapeType oldShapeType;
withWriteLock([&] {
oldShapeType = _shapeType;
_shapeType = type;
});
if (type == SHAPE_TYPE_COMPOUND) { if (type == SHAPE_TYPE_COMPOUND) {
if (type != oldShapeType) { if (type != oldShapeType) {
@ -300,16 +304,21 @@ void ZoneEntityItem::setShapeType(ShapeType type) {
} }
ShapeType ZoneEntityItem::getShapeType() const { ShapeType ZoneEntityItem::getShapeType() const {
return _shapeType; return resultWithReadLock<ShapeType>([&] {
return _shapeType;
});
} }
void ZoneEntityItem::setCompoundShapeURL(const QString& url) { void ZoneEntityItem::setCompoundShapeURL(const QString& url) {
QString oldCompoundShapeURL = _compoundShapeURL; QString oldCompoundShapeURL;
ShapeType shapeType;
withWriteLock([&] { withWriteLock([&] {
oldCompoundShapeURL = _compoundShapeURL;
_compoundShapeURL = url; _compoundShapeURL = url;
shapeType = _shapeType;
}); });
if (oldCompoundShapeURL != url) { if (oldCompoundShapeURL != url) {
if (_shapeType == SHAPE_TYPE_COMPOUND) { if (shapeType == SHAPE_TYPE_COMPOUND) {
fetchCollisionGeometryResource(); fetchCollisionGeometryResource();
} else { } else {
_shapeResource.reset(); _shapeResource.reset();
@ -333,7 +342,7 @@ bool ZoneEntityItem::findDetailedParabolaIntersection(const glm::vec3& origin, c
bool ZoneEntityItem::contains(const glm::vec3& point) const { bool ZoneEntityItem::contains(const glm::vec3& point) const {
GeometryResource::Pointer resource = _shapeResource; GeometryResource::Pointer resource = _shapeResource;
if (_shapeType == SHAPE_TYPE_COMPOUND && resource) { if (getShapeType() == SHAPE_TYPE_COMPOUND && resource) {
if (resource->isLoaded()) { if (resource->isLoaded()) {
const HFMModel& hfmModel = resource->getHFMModel(); const HFMModel& hfmModel = resource->getHFMModel();

View file

@ -278,12 +278,6 @@ const btCollisionShape* ShapeFactory::createShapeFromInfo(const ShapeInfo& info)
shape = new btBoxShape(glmToBullet(info.getHalfExtents())); shape = new btBoxShape(glmToBullet(info.getHalfExtents()));
} }
break; break;
case SHAPE_TYPE_SPHERE: {
glm::vec3 halfExtents = info.getHalfExtents();
float radius = glm::max(halfExtents.x, glm::max(halfExtents.y, halfExtents.z));
shape = new btSphereShape(radius);
}
break;
case SHAPE_TYPE_MULTISPHERE: { case SHAPE_TYPE_MULTISPHERE: {
std::vector<btVector3> positions; std::vector<btVector3> positions;
std::vector<float> radiuses; std::vector<float> radiuses;
@ -297,6 +291,7 @@ const btCollisionShape* ShapeFactory::createShapeFromInfo(const ShapeInfo& info)
shape->setMargin(MULTI_SPHERE_MARGIN); shape->setMargin(MULTI_SPHERE_MARGIN);
} }
break; break;
case SHAPE_TYPE_SPHERE:
case SHAPE_TYPE_ELLIPSOID: { case SHAPE_TYPE_ELLIPSOID: {
glm::vec3 halfExtents = info.getHalfExtents(); glm::vec3 halfExtents = info.getHalfExtents();
float radius = halfExtents.x; float radius = halfExtents.x;

View file

@ -115,12 +115,6 @@ void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString
case SHAPE_TYPE_HULL: case SHAPE_TYPE_HULL:
case SHAPE_TYPE_MULTISPHERE: case SHAPE_TYPE_MULTISPHERE:
break; break;
case SHAPE_TYPE_SPHERE: {
float radius = glm::length(halfExtents) / SQUARE_ROOT_OF_3;
radius = glm::max(radius, MIN_HALF_EXTENT);
_halfExtents = glm::vec3(radius);
}
break;
case SHAPE_TYPE_CIRCLE: { case SHAPE_TYPE_CIRCLE: {
_halfExtents = glm::vec3(_halfExtents.x, MIN_HALF_EXTENT, _halfExtents.z); _halfExtents = glm::vec3(_halfExtents.x, MIN_HALF_EXTENT, _halfExtents.z);
} }
@ -228,6 +222,7 @@ float ShapeInfo::computeVolume() const {
volume = 8.0f * _halfExtents.x * _halfExtents.y * _halfExtents.z; volume = 8.0f * _halfExtents.x * _halfExtents.y * _halfExtents.z;
break; break;
} }
case SHAPE_TYPE_ELLIPSOID:
case SHAPE_TYPE_SPHERE: { case SHAPE_TYPE_SPHERE: {
volume = 4.0f * PI * _halfExtents.x * _halfExtents.y * _halfExtents.z / 3.0f; volume = 4.0f * PI * _halfExtents.x * _halfExtents.y * _halfExtents.z / 3.0f;
break; break;

View file

@ -292,7 +292,7 @@ const GROUPS = [
{ {
label: "Shape Type", label: "Shape Type",
type: "dropdown", type: "dropdown",
options: { "box": "Box", "sphere": "Sphere", "ellipsoid": "Ellipsoid", options: { "box": "Box", "sphere": "Sphere",
"cylinder-y": "Cylinder", "compound": "Use Compound Shape URL" }, "cylinder-y": "Cylinder", "compound": "Use Compound Shape URL" },
propertyID: "zoneShapeType", propertyID: "zoneShapeType",
propertyName: "shapeType", // actual entity property name propertyName: "shapeType", // actual entity property name

View file

@ -13,6 +13,7 @@
var SHAPETYPE_TO_SHAPE = { var SHAPETYPE_TO_SHAPE = {
"box": "Cube", "box": "Cube",
"ellipsoid": "Sphere", "ellipsoid": "Sphere",
"sphere": "Sphere",
"cylinder-y": "Cylinder", "cylinder-y": "Cylinder",
}; };
@ -35,14 +36,6 @@ function getEntityShapePropertiesForType(properties) {
modelURL: properties.compoundShapeURL, modelURL: properties.compoundShapeURL,
localDimensions: properties.localDimensions localDimensions: properties.localDimensions
}; };
} else if (properties.shapeType === "sphere") {
var sphereDiameter = Math.max(properties.localDimensions.x, properties.localDimensions.y,
properties.localDimensions.z);
return {
type: "Sphere",
modelURL: properties.compoundShapeURL,
localDimensions: {x: sphereDiameter, y: sphereDiameter, z: sphereDiameter}
};
} }
break; break;
} }