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(); DependencyManager::set(); + DependencyManager::set(); auto& packetReceiver = DependencyManager::get()->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 #include +#include #include @@ -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()->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 +#include + #include "KeyLightPropertyGroup.h" #include "AmbientLightPropertyGroup.h" #include "EntityItem.h" @@ -19,7 +22,6 @@ #include "SkyboxPropertyGroup.h" #include "HazePropertyGroup.h" #include "BloomPropertyGroup.h" -#include 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()