mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 12:57:59 +02:00
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:
commit
053548cd14
6 changed files with 24 additions and 33 deletions
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue