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();
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 localPoint = point - (getWorldPosition() + getWorldOrientation() * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()) + getPivot()));
const float HALF_SQUARED = 0.25f;
return glm::length2(localPoint) < HALF_SQUARED * glm::length2(dimensions);
if (dimensions.x == dimensions.y && dimensions.y == dimensions.z) {
glm::vec3 localPoint = point - (getWorldPosition() + getWorldOrientation() * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()) + getPivot()));
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
@ -1805,6 +1803,7 @@ bool EntityItem::contains(const glm::vec3& point) const {
localPoint = glm::abs(localPoint);
return glm::all(glm::lessThanEqual(localPoint, glm::vec3(NORMALIZED_HALF_SIDE)));
}
case SHAPE_TYPE_SPHERE:
case SHAPE_TYPE_ELLIPSOID: {
// since we've transformed into the normalized space this is just a sphere-point intersection test
return glm::length2(localPoint) <= NORMALIZED_RADIUS_SQUARED;

View file

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

View file

@ -278,12 +278,6 @@ const btCollisionShape* ShapeFactory::createShapeFromInfo(const ShapeInfo& info)
shape = new btBoxShape(glmToBullet(info.getHalfExtents()));
}
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: {
std::vector<btVector3> positions;
std::vector<float> radiuses;
@ -297,6 +291,7 @@ const btCollisionShape* ShapeFactory::createShapeFromInfo(const ShapeInfo& info)
shape->setMargin(MULTI_SPHERE_MARGIN);
}
break;
case SHAPE_TYPE_SPHERE:
case SHAPE_TYPE_ELLIPSOID: {
glm::vec3 halfExtents = info.getHalfExtents();
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_MULTISPHERE:
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: {
_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;
break;
}
case SHAPE_TYPE_ELLIPSOID:
case SHAPE_TYPE_SPHERE: {
volume = 4.0f * PI * _halfExtents.x * _halfExtents.y * _halfExtents.z / 3.0f;
break;

View file

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

View file

@ -13,6 +13,7 @@
var SHAPETYPE_TO_SHAPE = {
"box": "Cube",
"ellipsoid": "Sphere",
"sphere": "Sphere",
"cylinder-y": "Cylinder",
};
@ -35,14 +36,6 @@ function getEntityShapePropertiesForType(properties) {
modelURL: properties.compoundShapeURL,
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;
}