From 0072684d98c5037e5aad89b61dc6e70eba53bd1a Mon Sep 17 00:00:00 2001 From: Andrew Meadows <andrew@highfidelity.io> Date: Mon, 19 Nov 2018 17:26:00 -0800 Subject: [PATCH 01/12] remove cruft and fix error in transform to mesh frame --- .../src/RenderableModelEntityItem.cpp | 4 +- libraries/render-utils/src/Model.cpp | 57 ++----------------- libraries/render-utils/src/Model.h | 2 +- 3 files changed, 9 insertions(+), 54 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index dcad562ba7..3c4aeb2686 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -726,7 +726,9 @@ int RenderableModelEntityItem::avatarJointIndex(int modelJointIndex) { bool RenderableModelEntityItem::contains(const glm::vec3& point) const { auto model = getModel(); if (EntityItem::contains(point) && model && _compoundShapeResource && _compoundShapeResource->isLoaded()) { - return _compoundShapeResource->getHFMModel().convexHullContains(worldToEntity(point)); + glm::mat4 worldToHFMMatrix = model->getWorldToHFMMatrix(); + glm::vec3 hfmPoint = worldToHFMMatrix * glm::vec4(point, 1.0f); + return _compoundShapeResource->getHFMModel().convexHullContains(hfmPoint); } return false; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 9cefbf65a8..ec29fb009e 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -614,58 +614,11 @@ bool Model::findParabolaIntersectionAgainstSubMeshes(const glm::vec3& origin, co return intersectedSomething; } -bool Model::convexHullContains(glm::vec3 point) { - // if we aren't active, we can't compute that yet... - if (!isActive()) { - return false; - } - - // extents is the entity relative, scaled, centered extents of the entity - glm::vec3 position = _translation; - glm::mat4 rotation = glm::mat4_cast(_rotation); - glm::mat4 translation = glm::translate(position); - glm::mat4 modelToWorldMatrix = translation * rotation; - glm::mat4 worldToModelMatrix = glm::inverse(modelToWorldMatrix); - - Extents modelExtents = getMeshExtents(); // NOTE: unrotated - - glm::vec3 dimensions = modelExtents.maximum - modelExtents.minimum; - glm::vec3 corner = -(dimensions * _registrationPoint); - AABox modelFrameBox(corner, dimensions); - - glm::vec3 modelFramePoint = glm::vec3(worldToModelMatrix * glm::vec4(point, 1.0f)); - - // we can use the AABox's contains() by mapping our point into the model frame - // and testing there. - if (modelFrameBox.contains(modelFramePoint)){ - QMutexLocker locker(&_mutex); - - if (!_triangleSetsValid) { - calculateTriangleSets(getHFMModel()); - } - - // If we are inside the models box, then consider the submeshes... - glm::mat4 meshToModelMatrix = glm::scale(_scale) * glm::translate(_offset); - glm::mat4 meshToWorldMatrix = createMatFromQuatAndPos(_rotation, _translation) * meshToModelMatrix; - glm::mat4 worldToMeshMatrix = glm::inverse(meshToWorldMatrix); - glm::vec3 meshFramePoint = glm::vec3(worldToMeshMatrix * glm::vec4(point, 1.0f)); - - for (auto& meshTriangleSets : _modelSpaceMeshTriangleSets) { - for (auto &partTriangleSet : meshTriangleSets) { - const AABox& box = partTriangleSet.getBounds(); - if (box.contains(meshFramePoint)) { - if (partTriangleSet.convexHullContains(meshFramePoint)) { - // It's inside this mesh, return true. - return true; - } - } - } - } - - - } - // It wasn't in any mesh, return false. - return false; +glm::mat4 Model::getWorldToHFMMatrix() const { + glm::mat4 hfmToModelMatrix = glm::scale(_scale) * glm::translate(_offset); + glm::mat4 modelToWorldMatrix = createMatFromQuatAndPos(_rotation, _translation); + glm::mat4 worldToHFMMatrix = glm::inverse(modelToWorldMatrix * hfmToModelMatrix); + return worldToHFMMatrix; } // TODO: deprecate and remove diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 93a0626d28..0f8eb782c3 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -192,7 +192,7 @@ public: bool didVisualGeometryRequestFail() const { return _visualGeometryRequestFailed; } bool didCollisionGeometryRequestFail() const { return _collisionGeometryRequestFailed; } - bool convexHullContains(glm::vec3 point); + glm::mat4 getWorldToHFMMatrix() const; QStringList getJointNames() const; From 1fabaf0db43b3f1d5a64502ab76dc64bf6938eb7 Mon Sep 17 00:00:00 2001 From: Andrew Meadows <andrew@highfidelity.io> Date: Mon, 19 Nov 2018 17:27:18 -0800 Subject: [PATCH 02/12] rename getCollisionGeometryResource to fetchCollisionGeometryResource --- .../src/RenderableModelEntityItem.cpp | 10 +++++----- .../entities-renderer/src/RenderableModelEntityItem.h | 3 +-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 3c4aeb2686..5693778e3a 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -279,7 +279,7 @@ bool RenderableModelEntityItem::findDetailedParabolaIntersection(const glm::vec3 face, surfaceNormal, extraInfo, precisionPicking, false); } -void RenderableModelEntityItem::getCollisionGeometryResource() { +void RenderableModelEntityItem::fetchCollisionGeometryResource() { QUrl hullURL(getCollisionShapeURL()); QUrlQuery queryArgs(hullURL); queryArgs.addQueryItem("collision-hull", ""); @@ -289,7 +289,7 @@ void RenderableModelEntityItem::getCollisionGeometryResource() { bool RenderableModelEntityItem::computeShapeFailedToLoad() { if (!_compoundShapeResource) { - getCollisionGeometryResource(); + fetchCollisionGeometryResource(); } return (_compoundShapeResource && _compoundShapeResource->isFailed()); @@ -300,7 +300,7 @@ void RenderableModelEntityItem::setShapeType(ShapeType type) { auto shapeType = getShapeType(); if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) { if (!_compoundShapeResource && !getCollisionShapeURL().isEmpty()) { - getCollisionGeometryResource(); + fetchCollisionGeometryResource(); } } else if (_compoundShapeResource && !getCompoundShapeURL().isEmpty()) { // the compoundURL has been set but the shapeType does not agree @@ -317,7 +317,7 @@ void RenderableModelEntityItem::setCompoundShapeURL(const QString& url) { ModelEntityItem::setCompoundShapeURL(url); if (getCompoundShapeURL() != currentCompoundShapeURL || !getModel()) { if (getShapeType() == SHAPE_TYPE_COMPOUND) { - getCollisionGeometryResource(); + fetchCollisionGeometryResource(); } } } @@ -340,7 +340,7 @@ bool RenderableModelEntityItem::isReadyToComputeShape() const { if (model->isLoaded()) { if (!shapeURL.isEmpty() && !_compoundShapeResource) { - const_cast<RenderableModelEntityItem*>(this)->getCollisionGeometryResource(); + const_cast<RenderableModelEntityItem*>(this)->fetchCollisionGeometryResource(); } if (_compoundShapeResource && _compoundShapeResource->isLoaded()) { diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index ba185dee96..725c1d96c3 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -122,7 +122,7 @@ private: void autoResizeJointArrays(); void copyAnimationJointDataToModel(); bool readyToAnimate() const; - void getCollisionGeometryResource(); + void fetchCollisionGeometryResource(); GeometryResource::Pointer _compoundShapeResource; std::vector<int> _jointMap; @@ -179,7 +179,6 @@ private: bool _hasModel { false }; ModelPointer _model; - GeometryResource::Pointer _compoundShapeResource; QString _lastTextures; bool _texturesLoaded { false }; int _lastKnownCurrentFrame { -1 }; From b4807204095dffc31752f15d05cacc9a4c50f810 Mon Sep 17 00:00:00 2001 From: Andrew Meadows <andrew@highfidelity.io> Date: Mon, 19 Nov 2018 17:32:28 -0800 Subject: [PATCH 03/12] proper shape support for EntityItem::contains(point) --- libraries/entities/src/EntityItem.cpp | 57 ++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index bfa238d695..5000a8c2ea 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1680,15 +1680,54 @@ void EntityItem::adjustShapeInfoByRegistration(ShapeInfo& info) const { } bool EntityItem::contains(const glm::vec3& point) const { - if (getShapeType() == SHAPE_TYPE_COMPOUND) { - bool success; - bool result = getAABox(success).contains(point); - return result && success; - } else { - ShapeInfo info; - info.setParams(getShapeType(), glm::vec3(0.5f)); - adjustShapeInfoByRegistration(info); - return info.contains(worldToEntity(point)); + // we transform into the "normalized entity-frame" where the bounding box is centered on the origin + // and has dimensions <1,1,1> + glm::vec3 localPoint = glm::vec3(glm::inverse(getEntityToWorldMatrix()) * glm::vec4(point, 1.0f)); + + const float NORMALIZED_HALF_SIDE = 0.5f; + const float NORMALIZED_RADIUS_SQUARED = NORMALIZED_HALF_SIDE * NORMALIZED_HALF_SIDE; + ShapeType shapeType = getShapeType(); + switch(shapeType) { + case SHAPE_TYPE_NONE: + return false; + case SHAPE_TYPE_CAPSULE_X: + case SHAPE_TYPE_CAPSULE_Y: + case SHAPE_TYPE_CAPSULE_Z: + case SHAPE_TYPE_HULL: + case SHAPE_TYPE_PLANE: + case SHAPE_TYPE_COMPOUND: + case SHAPE_TYPE_SIMPLE_HULL: + case SHAPE_TYPE_SIMPLE_COMPOUND: + case SHAPE_TYPE_STATIC_MESH: + case SHAPE_TYPE_CIRCLE: + // the above cases not yet supported --> fall through to BOX case + case SHAPE_TYPE_BOX: { + localPoint = glm::abs(localPoint); + return localPoint.x <= NORMALIZED_HALF_SIDE && + localPoint.y <= NORMALIZED_HALF_SIDE && + localPoint.z <= NORMALIZED_HALF_SIDE; + } + case SHAPE_TYPE_SPHERE: + case SHAPE_TYPE_ELLIPSOID: { + return glm::length2(localPoint) <= NORMALIZED_RADIUS_SQUARED; + } + case SHAPE_TYPE_CYLINDER_X: + if (fabsf(localPoint.x) <= NORMALIZED_HALF_SIDE) { + return (localPoint.y * localPoint.y + localPoint.z * localPoint.z <= NORMALIZED_RADIUS_SQUARED); + } + return false; + case SHAPE_TYPE_CYLINDER_Y: + if (fabsf(localPoint.x) <= NORMALIZED_HALF_SIDE) { + return (localPoint.z * localPoint.z + localPoint.x * localPoint.x <= NORMALIZED_RADIUS_SQUARED); + } + return false; + case SHAPE_TYPE_CYLINDER_Z: + if (fabsf(localPoint.x) <= NORMALIZED_HALF_SIDE) { + return (localPoint.x * localPoint.x + localPoint.y * localPoint.y <= NORMALIZED_RADIUS_SQUARED); + } + return false; + default: + return false; } } From bb15b3a5d594fa96b558cdc38871b16ef89ce52d Mon Sep 17 00:00:00 2001 From: Andrew Meadows <andrew@highfidelity.io> Date: Mon, 19 Nov 2018 17:33:45 -0800 Subject: [PATCH 04/12] remove ShapeInfo::contains() which was a Bad Idea --- libraries/shared/src/ShapeInfo.cpp | 44 ------------------------------ libraries/shared/src/ShapeInfo.h | 4 --- 2 files changed, 48 deletions(-) diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index df8e61114d..3118fce891 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -250,50 +250,6 @@ float ShapeInfo::computeVolume() const { return volume; } -bool ShapeInfo::contains(const glm::vec3& point) const { - switch(_type) { - case SHAPE_TYPE_SPHERE: - return glm::length(point) <= _halfExtents.x; - case SHAPE_TYPE_CYLINDER_X: - return glm::length(glm::vec2(point.y, point.z)) <= _halfExtents.z; - case SHAPE_TYPE_CYLINDER_Y: - return glm::length(glm::vec2(point.x, point.z)) <= _halfExtents.x; - 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 - _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); - return glm::length(absPoint) <= _halfExtents.y; - } - } - case SHAPE_TYPE_CAPSULE_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); - return glm::length(absPoint) <= _halfExtents.z; - } - } - case SHAPE_TYPE_CAPSULE_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); - return glm::length(absPoint) <= _halfExtents.x; - } - } - case SHAPE_TYPE_BOX: - default: { - glm::vec3 absPoint = glm::abs(point); - return absPoint.x <= _halfExtents.x - && absPoint.y <= _halfExtents.y - && absPoint.z <= _halfExtents.z; - } - } -} - const HashKey& ShapeInfo::getHash() const { // NOTE: we cache the key so we only ever need to compute it once for any valid ShapeInfo instance. if (_hashKey.isNull() && _type != SHAPE_TYPE_NONE) { diff --git a/libraries/shared/src/ShapeInfo.h b/libraries/shared/src/ShapeInfo.h index 16e260d9db..a2092c7f00 100644 --- a/libraries/shared/src/ShapeInfo.h +++ b/libraries/shared/src/ShapeInfo.h @@ -86,10 +86,6 @@ public: float computeVolume() const; - /// Returns whether point is inside the shape - /// For compound shapes it will only return whether it is inside the bounding box - bool contains(const glm::vec3& point) const; - const HashKey& getHash() const; protected: From a8325b5c00d850f8f91c76b3fc200cb635328e5d Mon Sep 17 00:00:00 2001 From: Andrew Meadows <andrew@highfidelity.io> Date: Mon, 19 Nov 2018 17:35:35 -0800 Subject: [PATCH 05/12] add ZoneEntityItem::contains() and support for shapes --- assignment-client/CMakeLists.txt | 1 + .../src/entities/EntityServer.cpp | 1 + libraries/entities/CMakeLists.txt | 2 +- libraries/entities/src/ZoneEntityItem.cpp | 87 ++++++++++++++++--- libraries/entities/src/ZoneEntityItem.h | 13 ++- libraries/physics/CMakeLists.txt | 7 +- 6 files changed, 94 insertions(+), 17 deletions(-) diff --git a/assignment-client/CMakeLists.txt b/assignment-client/CMakeLists.txt index 229e3641d0..f28dc90b7d 100644 --- a/assignment-client/CMakeLists.txt +++ b/assignment-client/CMakeLists.txt @@ -14,6 +14,7 @@ link_hifi_libraries( audio avatars octree gpu graphics shaders fbx hfm entities networking animation recording shared script-engine embedded-webserver controllers physics plugins midi image + model-networking ktx shaders ) add_dependencies(${TARGET_NAME} oven) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 089fb3e52f..22308071eb 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -45,6 +45,7 @@ EntityServer::EntityServer(ReceivedMessage& message) : DependencyManager::registerInheritance<EntityDynamicFactoryInterface, AssignmentDynamicFactory>(); DependencyManager::set<AssignmentDynamicFactory>(); + DependencyManager::set<ModelCache>(); auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver(); packetReceiver.registerListenerForTypes({ PacketType::EntityAdd, diff --git a/libraries/entities/CMakeLists.txt b/libraries/entities/CMakeLists.txt index c51ae28d5f..542f6eb0e2 100644 --- a/libraries/entities/CMakeLists.txt +++ b/libraries/entities/CMakeLists.txt @@ -6,4 +6,4 @@ include_hifi_library_headers(fbx) include_hifi_library_headers(gpu) include_hifi_library_headers(image) include_hifi_library_headers(ktx) -link_hifi_libraries(shared shaders networking octree avatars graphics model-networking) \ No newline at end of file +link_hifi_libraries(shared shaders networking octree model-networking avatars graphics model-networking) diff --git a/libraries/entities/src/ZoneEntityItem.cpp b/libraries/entities/src/ZoneEntityItem.cpp index a265fe16cd..4c379f7290 100644 --- a/libraries/entities/src/ZoneEntityItem.cpp +++ b/libraries/entities/src/ZoneEntityItem.cpp @@ -11,7 +11,9 @@ #include "ZoneEntityItem.h" +#include <glm/gtx/transform.hpp> #include <QDebug> +#include <QUrlQuery> #include <ByteCountCoding.h> @@ -275,22 +277,53 @@ void ZoneEntityItem::debugDump() const { _bloomProperties.debugDump(); } -ShapeType ZoneEntityItem::getShapeType() const { - // Zones are not allowed to have a SHAPE_TYPE_NONE... they are always at least a SHAPE_TYPE_BOX - if (_shapeType == SHAPE_TYPE_COMPOUND) { - return hasCompoundShapeURL() ? SHAPE_TYPE_COMPOUND : DEFAULT_SHAPE_TYPE; +void ZoneEntityItem::setShapeType(ShapeType type) { + //ShapeType typeArgument = type; + ShapeType oldShapeType = _shapeType; + switch(type) { + case SHAPE_TYPE_NONE: + case SHAPE_TYPE_CAPSULE_X: + case SHAPE_TYPE_CAPSULE_Y: + case SHAPE_TYPE_CAPSULE_Z: + case SHAPE_TYPE_HULL: + case SHAPE_TYPE_PLANE: + case SHAPE_TYPE_SIMPLE_HULL: + case SHAPE_TYPE_SIMPLE_COMPOUND: + case SHAPE_TYPE_STATIC_MESH: + case SHAPE_TYPE_CIRCLE: + // these types are unsupported for ZoneEntity + type = DEFAULT_SHAPE_TYPE; + break; + default: + break; + } + _shapeType = type; + + if (type == SHAPE_TYPE_COMPOUND) { + if (type != oldShapeType) { + fetchCollisionGeometryResource(); + } } else { - return _shapeType == SHAPE_TYPE_NONE ? DEFAULT_SHAPE_TYPE : _shapeType; + _shapeResource.reset(); } } +ShapeType ZoneEntityItem::getShapeType() const { + return _shapeType; +} + void ZoneEntityItem::setCompoundShapeURL(const QString& url) { + QString oldCompoundShapeURL = _compoundShapeURL; withWriteLock([&] { _compoundShapeURL = url; - if (_compoundShapeURL.isEmpty() && _shapeType == SHAPE_TYPE_COMPOUND) { - _shapeType = DEFAULT_SHAPE_TYPE; - } }); + if (oldCompoundShapeURL != url) { + if (_shapeType == SHAPE_TYPE_COMPOUND) { + fetchCollisionGeometryResource(); + } else { + _shapeResource.reset(); + } + } } bool ZoneEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, @@ -307,6 +340,28 @@ bool ZoneEntityItem::findDetailedParabolaIntersection(const glm::vec3& origin, c return _zonesArePickable; } +bool ZoneEntityItem::contains(const glm::vec3& point) const { + GeometryResource::Pointer resource = _shapeResource; + if (_shapeType == SHAPE_TYPE_COMPOUND && resource) { + if (resource->isLoaded()) { + const HFMModel& hfmModel = resource->getHFMModel(); + + glm::vec3 minimum = glm::vec3(hfmModel.offset * glm::vec4(hfmModel.meshExtents.minimum, 1.0f)); + glm::vec3 maximum = glm::vec3(hfmModel.offset * glm::vec4(hfmModel.meshExtents.maximum, 1.0f)); + glm::vec3 modelExtentsDiagonal = maximum - minimum; + glm::vec3 offset = -minimum - (modelExtentsDiagonal * getRegistrationPoint()); + glm::vec3 scale(getScaledDimensions() / modelExtentsDiagonal); + + glm::mat4 hfmToEntityMatrix = glm::scale(scale) * glm::translate(offset); + glm::mat4 entityToWorldMatrix = getTransform().getMatrix(); + glm::mat4 worldToHFMMatrix = glm::inverse(entityToWorldMatrix * hfmToEntityMatrix); + + return hfmModel.convexHullContains(glm::vec3(worldToHFMMatrix * glm::vec4(point, 1.0f))); + } + } + return EntityItem::contains(point); +} + void ZoneEntityItem::setFilterURL(QString url) { withWriteLock([&] { _filterURL = url; @@ -326,10 +381,6 @@ QString ZoneEntityItem::getFilterURL() const { return result; } -bool ZoneEntityItem::hasCompoundShapeURL() const { - return !getCompoundShapeURL().isEmpty(); -} - QString ZoneEntityItem::getCompoundShapeURL() const { QString result; withReadLock([&] { @@ -403,3 +454,15 @@ void ZoneEntityItem::setSkyboxMode(const uint32_t value) { uint32_t ZoneEntityItem::getSkyboxMode() const { return _skyboxMode; } + +void ZoneEntityItem::fetchCollisionGeometryResource() { + QUrl hullURL(getCompoundShapeURL()); + if (hullURL.isEmpty()) { + _shapeResource.reset(); + } else { + QUrlQuery queryArgs(hullURL); + queryArgs.addQueryItem("collision-hull", ""); + hullURL.setQuery(queryArgs); + _shapeResource = DependencyManager::get<ModelCache>()->getCollisionGeometryResource(hullURL); + } +} diff --git a/libraries/entities/src/ZoneEntityItem.h b/libraries/entities/src/ZoneEntityItem.h index c2f4542aa6..813115add9 100644 --- a/libraries/entities/src/ZoneEntityItem.h +++ b/libraries/entities/src/ZoneEntityItem.h @@ -12,6 +12,9 @@ #ifndef hifi_ZoneEntityItem_h #define hifi_ZoneEntityItem_h +#include <ComponentMode.h> +#include <model-networking/ModelCache.h> + #include "KeyLightPropertyGroup.h" #include "AmbientLightPropertyGroup.h" #include "EntityItem.h" @@ -19,7 +22,6 @@ #include "SkyboxPropertyGroup.h" #include "HazePropertyGroup.h" #include "BloomPropertyGroup.h" -#include <ComponentMode.h> class ZoneEntityItem : public EntityItem { public: @@ -58,10 +60,9 @@ public: static void setDrawZoneBoundaries(bool value) { _drawZoneBoundaries = value; } virtual bool isReadyToComputeShape() const override { return false; } - void setShapeType(ShapeType type) override { withWriteLock([&] { _shapeType = type; }); } + virtual void setShapeType(ShapeType type) override; virtual ShapeType getShapeType() const override; - virtual bool hasCompoundShapeURL() const; QString getCompoundShapeURL() const; virtual void setCompoundShapeURL(const QString& url); @@ -115,6 +116,8 @@ public: BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, bool precisionPicking) const override; + bool contains(const glm::vec3& point) const override; + virtual void debugDump() const override; static const ShapeType DEFAULT_SHAPE_TYPE; @@ -156,6 +159,10 @@ protected: static bool _drawZoneBoundaries; static bool _zonesArePickable; + + void fetchCollisionGeometryResource(); + GeometryResource::Pointer _shapeResource; + }; #endif // hifi_ZoneEntityItem_h diff --git a/libraries/physics/CMakeLists.txt b/libraries/physics/CMakeLists.txt index 96a55c8477..5249ed2950 100644 --- a/libraries/physics/CMakeLists.txt +++ b/libraries/physics/CMakeLists.txt @@ -1,11 +1,16 @@ set(TARGET_NAME physics) setup_hifi_library() -link_hifi_libraries(shared task workload fbx entities graphics) +link_hifi_libraries(shared task workload fbx entities graphics shaders) include_hifi_library_headers(networking) include_hifi_library_headers(gpu) include_hifi_library_headers(avatars) include_hifi_library_headers(audio) include_hifi_library_headers(octree) include_hifi_library_headers(animation) +include_hifi_library_headers(model-networking) +include_hifi_library_headers(image) +include_hifi_library_headers(ktx) +include_hifi_library_headers(gpu) +include_hifi_library_headers(hfm) target_bullet() From 7625aebaa8be5aed5c1e2ec0aa3f5bd982f1ad56 Mon Sep 17 00:00:00 2001 From: Andrew Meadows <andrew@highfidelity.io> Date: Wed, 21 Nov 2018 12:09:07 -0800 Subject: [PATCH 06/12] remove reduntant model-networking link dependency --- libraries/entities/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities/CMakeLists.txt b/libraries/entities/CMakeLists.txt index 542f6eb0e2..fcbe563f88 100644 --- a/libraries/entities/CMakeLists.txt +++ b/libraries/entities/CMakeLists.txt @@ -6,4 +6,4 @@ include_hifi_library_headers(fbx) include_hifi_library_headers(gpu) include_hifi_library_headers(image) include_hifi_library_headers(ktx) -link_hifi_libraries(shared shaders networking octree model-networking avatars graphics model-networking) +link_hifi_libraries(shared shaders networking octree avatars graphics model-networking) From 65e920039c04b4224453ffcbe24adeaec3f6c6ee Mon Sep 17 00:00:00 2001 From: Andrew Meadows <andrew@highfidelity.io> Date: Wed, 21 Nov 2018 12:30:30 -0800 Subject: [PATCH 07/12] cleaner return logic for EntityItem::contains() cylinder cases --- libraries/entities/src/EntityItem.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 5000a8c2ea..0b6f4c0cf5 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1712,20 +1712,14 @@ bool EntityItem::contains(const glm::vec3& point) const { return glm::length2(localPoint) <= NORMALIZED_RADIUS_SQUARED; } case SHAPE_TYPE_CYLINDER_X: - if (fabsf(localPoint.x) <= NORMALIZED_HALF_SIDE) { - return (localPoint.y * localPoint.y + localPoint.z * localPoint.z <= NORMALIZED_RADIUS_SQUARED); - } - return false; + return fabsf(localPoint.x) <= NORMALIZED_HALF_SIDE && + localPoint.y * localPoint.y + localPoint.z * localPoint.z <= NORMALIZED_RADIUS_SQUARED; case SHAPE_TYPE_CYLINDER_Y: - if (fabsf(localPoint.x) <= NORMALIZED_HALF_SIDE) { - return (localPoint.z * localPoint.z + localPoint.x * localPoint.x <= NORMALIZED_RADIUS_SQUARED); - } - return false; + return fabsf(localPoint.x) <= NORMALIZED_HALF_SIDE && + localPoint.z * localPoint.z + localPoint.x * localPoint.x <= NORMALIZED_RADIUS_SQUARED; case SHAPE_TYPE_CYLINDER_Z: - if (fabsf(localPoint.x) <= NORMALIZED_HALF_SIDE) { - return (localPoint.x * localPoint.x + localPoint.y * localPoint.y <= NORMALIZED_RADIUS_SQUARED); - } - return false; + return fabsf(localPoint.x) <= NORMALIZED_HALF_SIDE && + localPoint.x * localPoint.x + localPoint.y * localPoint.y <= NORMALIZED_RADIUS_SQUARED; default: return false; } From a656ea723e0fc9c0ecd60038269a5e1379200b28 Mon Sep 17 00:00:00 2001 From: Andrew Meadows <andrew@highfidelity.io> Date: Mon, 26 Nov 2018 09:14:08 -0800 Subject: [PATCH 08/12] special handling of SPHERE case in EntityItem::contains() --- libraries/entities/src/EntityItem.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 0b6f4c0cf5..76dd130f70 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1680,13 +1680,24 @@ void EntityItem::adjustShapeInfoByRegistration(ShapeInfo& info) const { } 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()))); + const float HALF_SQUARED = 0.25f; + return glm::length2(localPoint) < HALF_SQUARED * glm::length2(dimensions); + } + // we transform into the "normalized entity-frame" where the bounding box is centered on the origin // and has dimensions <1,1,1> glm::vec3 localPoint = glm::vec3(glm::inverse(getEntityToWorldMatrix()) * glm::vec4(point, 1.0f)); const float NORMALIZED_HALF_SIDE = 0.5f; const float NORMALIZED_RADIUS_SQUARED = NORMALIZED_HALF_SIDE * NORMALIZED_HALF_SIDE; - ShapeType shapeType = getShapeType(); switch(shapeType) { case SHAPE_TYPE_NONE: return false; @@ -1707,8 +1718,8 @@ bool EntityItem::contains(const glm::vec3& point) const { localPoint.y <= NORMALIZED_HALF_SIDE && localPoint.z <= 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; } case SHAPE_TYPE_CYLINDER_X: From a642af23b79b5deaf229a9baedde36e28435947a Mon Sep 17 00:00:00 2001 From: Andrew Meadows <andrew@highfidelity.io> Date: Tue, 27 Nov 2018 08:44:40 -0800 Subject: [PATCH 09/12] enable shapeType=ellipsoid and expose zone shapeType to UI --- .../entities/src/EntityItemProperties.cpp | 1 + libraries/entities/src/ZoneEntityItem.cpp | 1 - libraries/shared/src/ShapeInfo.cpp | 3 ++- scripts/system/edit.js | 1 + scripts/system/html/js/entityProperties.js | 20 ++++++++++++++++++- 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 1745658cf1..282e86c4d4 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -117,6 +117,7 @@ void buildStringToShapeTypeLookup() { addShapeType(SHAPE_TYPE_SIMPLE_HULL); addShapeType(SHAPE_TYPE_SIMPLE_COMPOUND); addShapeType(SHAPE_TYPE_STATIC_MESH); + addShapeType(SHAPE_TYPE_ELLIPSOID); } QHash<QString, MaterialMappingMode> stringToMaterialMappingModeLookup; diff --git a/libraries/entities/src/ZoneEntityItem.cpp b/libraries/entities/src/ZoneEntityItem.cpp index 4c379f7290..61f07808f6 100644 --- a/libraries/entities/src/ZoneEntityItem.cpp +++ b/libraries/entities/src/ZoneEntityItem.cpp @@ -278,7 +278,6 @@ void ZoneEntityItem::debugDump() const { } void ZoneEntityItem::setShapeType(ShapeType type) { - //ShapeType typeArgument = type; ShapeType oldShapeType = _shapeType; switch(type) { case SHAPE_TYPE_NONE: diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index 3118fce891..3426a79782 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -58,7 +58,8 @@ const char* shapeTypeNames[] = { "compound", "simple-hull", "simple-compound", - "static-mesh" + "static-mesh", + "ellipsoid" }; static const size_t SHAPETYPE_NAME_COUNT = (sizeof(shapeTypeNames) / sizeof((shapeTypeNames)[0])); diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 36f9af0ea7..28309ee98d 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -372,6 +372,7 @@ const DEFAULT_ENTITY_PROPERTIES = { blue: 179 }, }, + shapeType: "box", bloomMode: "inherit" }, Model: { diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index 78ef8ac313..3554b7e5bf 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -1288,6 +1288,24 @@ const GROUPS = [ }, ] }, + { + id: "zone_shape", + label: "ZONE SHAPE", + properties: [ + { + label: "Shape Type", + type: "dropdown", + options: { "box": "Box", "sphere": "Sphere", "ellipsoid": "Ellipsoid", + "cylinder-y": "Cylinder", "compound": "Use Compound Shape URL" }, + propertyID: "shapeType", + }, + { + label: "Compound Shape URL", + type: "string", + propertyID: "compoundShapeURL", + }, + ] + }, { id: "physics", label: "PHYSICS", @@ -1384,7 +1402,7 @@ const GROUPS_PER_TYPE = { None: [ 'base', 'spatial', 'behavior', 'collision', 'physics' ], Shape: [ 'base', 'shape', 'spatial', 'behavior', 'collision', 'physics' ], Text: [ 'base', 'text', 'spatial', 'behavior', 'collision', 'physics' ], - Zone: [ 'base', 'zone', 'spatial', 'behavior', 'collision', 'physics' ], + Zone: [ 'base', 'zone', 'spatial', 'behavior', 'zone_shape', 'physics' ], Model: [ 'base', 'model', 'spatial', 'behavior', 'collision', 'physics' ], Image: [ 'base', 'image', 'spatial', 'behavior', 'collision', 'physics' ], Web: [ 'base', 'web', 'spatial', 'behavior', 'collision', 'physics' ], From 13a3982b5af70df361c607feb2331e3b17ead418 Mon Sep 17 00:00:00 2001 From: Andrew Meadows <andrew@highfidelity.io> Date: Fri, 4 Jan 2019 12:31:29 -0800 Subject: [PATCH 10/12] fix ZoneEntityItem::contains() for model shapes --- .../src/RenderableModelEntityItem.cpp | 21 +++++++++++-------- .../src/RenderableZoneEntityItem.cpp | 19 ----------------- libraries/entities/src/ZoneEntityItem.cpp | 9 ++++---- libraries/hfm/src/hfm/HFM.cpp | 9 +++----- libraries/hfm/src/hfm/HFM.h | 1 + libraries/physics/src/EntityMotionState.cpp | 1 - 6 files changed, 20 insertions(+), 40 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 5693778e3a..aa449b8919 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -367,8 +367,6 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { const uint32_t QUAD_STRIDE = 4; ShapeType type = getShapeType(); - glm::vec3 dimensions = getScaledDimensions(); - auto model = getModel(); if (type == SHAPE_TYPE_COMPOUND) { updateModelBounds(); @@ -450,6 +448,11 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { // to the visual model and apply them to the collision model (without regard for the // collision model's extents). + auto model = getModel(); + // assert we never fall in here when model not fully loaded + assert(model && model->isLoaded()); + + glm::vec3 dimensions = getScaledDimensions(); glm::vec3 scaleToFit = dimensions / model->getHFMModel().getUnscaledMeshExtents().size(); // multiply each point by scale before handing the point-set off to the physics engine. // also determine the extents of the collision model. @@ -461,11 +464,12 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { } } shapeInfo.setParams(type, dimensions, getCompoundShapeURL()); + adjustShapeInfoByRegistration(shapeInfo); } else if (type >= SHAPE_TYPE_SIMPLE_HULL && type <= SHAPE_TYPE_STATIC_MESH) { - // TODO: assert we never fall in here when model not fully loaded - // assert(_model && _model->isLoaded()); - updateModelBounds(); + auto model = getModel(); + // assert we never fall in here when model not fully loaded + assert(model && model->isLoaded()); model->updateGeometry(); // compute meshPart local transforms @@ -473,6 +477,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { const HFMModel& hfmModel = model->getHFMModel(); int numHFMMeshes = hfmModel.meshes.size(); int totalNumVertices = 0; + glm::vec3 dimensions = getScaledDimensions(); glm::mat4 invRegistraionOffset = glm::translate(dimensions * (getRegistrationPoint() - ENTITY_ITEM_DEFAULT_REGISTRATION_POINT)); for (int i = 0; i < numHFMMeshes; i++) { const HFMMesh& mesh = hfmModel.meshes.at(i); @@ -695,12 +700,10 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { } shapeInfo.setParams(type, 0.5f * dimensions, getModelURL()); + adjustShapeInfoByRegistration(shapeInfo); } else { - ModelEntityItem::computeShapeInfo(shapeInfo); - shapeInfo.setParams(type, 0.5f * dimensions); + EntityItem::computeShapeInfo(shapeInfo); } - // finally apply the registration offset to the shapeInfo - adjustShapeInfoByRegistration(shapeInfo); } void RenderableModelEntityItem::setJointMap(std::vector<int> jointMap) { diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 232e6efa67..57ff8ed8c2 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -546,22 +546,3 @@ void ZoneEntityRenderer::setProceduralUserData(const QString& userData) { } } -#if 0 -bool RenderableZoneEntityItem::contains(const glm::vec3& point) const { - if (getShapeType() != SHAPE_TYPE_COMPOUND) { - return EntityItem::contains(point); - } - const_cast<RenderableZoneEntityItem*>(this)->updateGeometry(); - - if (_model && _model->isActive() && EntityItem::contains(point)) { - return _model->convexHullContains(point); - } - - return false; -} - -void RenderableZoneEntityItem::notifyBoundChanged() { - notifyChangedRenderItem(); -} - -#endif diff --git a/libraries/entities/src/ZoneEntityItem.cpp b/libraries/entities/src/ZoneEntityItem.cpp index 61f07808f6..7f7f6170d4 100644 --- a/libraries/entities/src/ZoneEntityItem.cpp +++ b/libraries/entities/src/ZoneEntityItem.cpp @@ -345,11 +345,10 @@ bool ZoneEntityItem::contains(const glm::vec3& point) const { if (resource->isLoaded()) { const HFMModel& hfmModel = resource->getHFMModel(); - glm::vec3 minimum = glm::vec3(hfmModel.offset * glm::vec4(hfmModel.meshExtents.minimum, 1.0f)); - glm::vec3 maximum = glm::vec3(hfmModel.offset * glm::vec4(hfmModel.meshExtents.maximum, 1.0f)); - glm::vec3 modelExtentsDiagonal = maximum - minimum; - glm::vec3 offset = -minimum - (modelExtentsDiagonal * getRegistrationPoint()); - glm::vec3 scale(getScaledDimensions() / modelExtentsDiagonal); + Extents meshExtents = hfmModel.getMeshExtents(); + glm::vec3 meshExtentsDiagonal = meshExtents.maximum - meshExtents.minimum; + glm::vec3 offset = -meshExtents.minimum- (meshExtentsDiagonal * getRegistrationPoint()); + glm::vec3 scale(getScaledDimensions() / meshExtentsDiagonal); glm::mat4 hfmToEntityMatrix = glm::scale(scale) * glm::translate(offset); glm::mat4 entityToWorldMatrix = getTransform().getMatrix(); diff --git a/libraries/hfm/src/hfm/HFM.cpp b/libraries/hfm/src/hfm/HFM.cpp index 8f01956f17..b9e630456d 100644 --- a/libraries/hfm/src/hfm/HFM.cpp +++ b/libraries/hfm/src/hfm/HFM.cpp @@ -189,20 +189,17 @@ bool HFMModel::hasBlendedMeshes() const { } Extents HFMModel::getUnscaledMeshExtents() const { - const Extents& extents = meshExtents; - // even though our caller asked for "unscaled" we need to include any fst scaling, translation, and rotation, which // is captured in the offset matrix - glm::vec3 minimum = glm::vec3(offset * glm::vec4(extents.minimum, 1.0f)); - glm::vec3 maximum = glm::vec3(offset * glm::vec4(extents.maximum, 1.0f)); + glm::vec3 minimum = glm::vec3(offset * glm::vec4(meshExtents.minimum, 1.0f)); + glm::vec3 maximum = glm::vec3(offset * glm::vec4(meshExtents.maximum, 1.0f)); Extents scaledExtents = { minimum, maximum }; - return scaledExtents; } // TODO: Move to graphics::Mesh when Sam's ready bool HFMModel::convexHullContains(const glm::vec3& point) const { - if (!getUnscaledMeshExtents().containsPoint(point)) { + if (!meshExtents.containsPoint(point)) { return false; } diff --git a/libraries/hfm/src/hfm/HFM.h b/libraries/hfm/src/hfm/HFM.h index 9846e7e891..78f608d72e 100644 --- a/libraries/hfm/src/hfm/HFM.h +++ b/libraries/hfm/src/hfm/HFM.h @@ -310,6 +310,7 @@ public: /// Returns the unscaled extents of the model's mesh Extents getUnscaledMeshExtents() const; + const Extents& getMeshExtents() const { return meshExtents; } bool convexHullContains(const glm::vec3& point) const; diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 4b635ef0be..dd906fe5c1 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -91,7 +91,6 @@ EntityMotionState::EntityMotionState(btCollisionShape* shape, EntityItemPointer _serverRotation = localTransform.getRotation(); _serverAcceleration = _entity->getAcceleration(); _serverActionData = _entity->getDynamicData(); - } EntityMotionState::~EntityMotionState() { From 3303bb70170c673f08d8749b4f38d4b72fa1068f Mon Sep 17 00:00:00 2001 From: Andrew Meadows <andrew@highfidelity.io> Date: Fri, 4 Jan 2019 12:36:45 -0800 Subject: [PATCH 11/12] EntityServer now depends on ModelFormatRegistry --- assignment-client/src/entities/EntityServer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 22308071eb..581d854909 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -23,6 +23,7 @@ #include <EntityEditFilters.h> #include <NetworkingConstants.h> #include <AddressManager.h> +#include <hfm/ModelFormatRegistry.h> #include "../AssignmentDynamicFactory.h" #include "AssignmentParentFinder.h" @@ -45,6 +46,7 @@ EntityServer::EntityServer(ReceivedMessage& message) : DependencyManager::registerInheritance<EntityDynamicFactoryInterface, AssignmentDynamicFactory>(); DependencyManager::set<AssignmentDynamicFactory>(); + DependencyManager::set<ModelFormatRegistry>(); // ModelFormatRegistry must be defined before ModelCache. See the ModelCache ctor DependencyManager::set<ModelCache>(); auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver(); From 5c750b40c9ee6049f6f0a18d577f9cbd39dbb353 Mon Sep 17 00:00:00 2001 From: Andrew Meadows <andrew@highfidelity.io> Date: Sat, 5 Jan 2019 08:03:29 -0800 Subject: [PATCH 12/12] fix copy-n-paste errors in EntityItem::contains() for cylinders --- libraries/entities/src/EntityItem.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 76dd130f70..d05f087fdb 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -20,6 +20,7 @@ #include <QtNetwork/QNetworkRequest> #include <glm/gtx/transform.hpp> +#include <glm/gtx/component_wise.hpp> #include <BufferParser.h> #include <ByteCountCoding.h> @@ -1714,9 +1715,7 @@ bool EntityItem::contains(const glm::vec3& point) const { // the above cases not yet supported --> fall through to BOX case case SHAPE_TYPE_BOX: { localPoint = glm::abs(localPoint); - return localPoint.x <= NORMALIZED_HALF_SIDE && - localPoint.y <= NORMALIZED_HALF_SIDE && - localPoint.z <= NORMALIZED_HALF_SIDE; + return glm::any(glm::lessThanEqual(localPoint, glm::vec3(NORMALIZED_HALF_SIDE))); } case SHAPE_TYPE_ELLIPSOID: { // since we've transformed into the normalized space this is just a sphere-point intersection test @@ -1726,10 +1725,10 @@ bool EntityItem::contains(const glm::vec3& point) const { return fabsf(localPoint.x) <= NORMALIZED_HALF_SIDE && localPoint.y * localPoint.y + localPoint.z * localPoint.z <= NORMALIZED_RADIUS_SQUARED; case SHAPE_TYPE_CYLINDER_Y: - return fabsf(localPoint.x) <= NORMALIZED_HALF_SIDE && + return fabsf(localPoint.y) <= NORMALIZED_HALF_SIDE && localPoint.z * localPoint.z + localPoint.x * localPoint.x <= NORMALIZED_RADIUS_SQUARED; case SHAPE_TYPE_CYLINDER_Z: - return fabsf(localPoint.x) <= NORMALIZED_HALF_SIDE && + return fabsf(localPoint.z) <= NORMALIZED_HALF_SIDE && localPoint.x * localPoint.x + localPoint.y * localPoint.y <= NORMALIZED_RADIUS_SQUARED; default: return false;