diff --git a/interface/src/avatar/OtherAvatar.cpp b/interface/src/avatar/OtherAvatar.cpp index a6e2d6a998..3776d54d9a 100755 --- a/interface/src/avatar/OtherAvatar.cpp +++ b/interface/src/avatar/OtherAvatar.cpp @@ -201,6 +201,7 @@ void OtherAvatar::computeShapeLOD() { break; case workload::Region::UNKNOWN: case workload::Region::INVALID: + case workload::Region::R4: case workload::Region::R3: default: newLOD = BodyLOD::Sphere; diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index 75e512232b..01ef9ed69e 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -122,9 +122,6 @@ void SafeLanding::updateTracking() { if (isEntityPhysicsReady(entity) && isVisuallyReady) { entityMapIter = _trackedEntities.erase(entityMapIter); } else { - if (!isVisuallyReady) { - entity->requestRenderUpdate(); - } entityMapIter++; } } @@ -203,8 +200,11 @@ bool SafeLanding::isEntityPhysicsReady(const EntityItemPointer& entity) { if (hasAABox && downloadedCollisionTypes.count(modelEntity->getShapeType()) != 0) { auto space = _entityTreeRenderer->getWorkloadSpace(); uint8_t region = space ? space->getRegion(entity->getSpaceIndex()) : (uint8_t)workload::Region::INVALID; - bool shouldBePhysical = region < workload::Region::R3 && entity->shouldBePhysical(); - return (!shouldBePhysical || entity->isInPhysicsSimulation() || modelEntity->computeShapeFailedToLoad()); + bool definitelyNotPhysical = (region > workload::Region::R2 && region < workload::Region::UNKNOWN) || + !entity->shouldBePhysical() || + modelEntity->unableToLoadCollisionShape(); + bool definitelyPhysical = entity->isInPhysicsSimulation(); + return definitelyNotPhysical || definitelyPhysical; } } } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index cfc94ad92c..7ef491312f 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -282,27 +282,26 @@ bool RenderableModelEntityItem::findDetailedParabolaIntersection(const glm::vec3 } void RenderableModelEntityItem::fetchCollisionGeometryResource() { - _compoundShapeResource = DependencyManager::get()->getCollisionGeometryResource(getCollisionShapeURL()); + _collisionGeometryResource = DependencyManager::get()->getCollisionGeometryResource(getCollisionShapeURL()); } -bool RenderableModelEntityItem::computeShapeFailedToLoad() { - if (!_compoundShapeResource) { +bool RenderableModelEntityItem::unableToLoadCollisionShape() { + if (!_collisionGeometryResource) { fetchCollisionGeometryResource(); } - - return (_compoundShapeResource && _compoundShapeResource->isFailed()); + return (_collisionGeometryResource && _collisionGeometryResource->isFailed()); } void RenderableModelEntityItem::setShapeType(ShapeType type) { ModelEntityItem::setShapeType(type); auto shapeType = getShapeType(); if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) { - if (!_compoundShapeResource && !getCollisionShapeURL().isEmpty()) { + if (!_collisionGeometryResource && !getCollisionShapeURL().isEmpty()) { fetchCollisionGeometryResource(); } - } else if (_compoundShapeResource && !getCompoundShapeURL().isEmpty()) { + } else if (_collisionGeometryResource && !getCompoundShapeURL().isEmpty()) { // the compoundURL has been set but the shapeType does not agree - _compoundShapeResource.reset(); + _collisionGeometryResource.reset(); } } @@ -333,11 +332,11 @@ bool RenderableModelEntityItem::isReadyToComputeShape() const { } if (model->isLoaded()) { - if (!shapeURL.isEmpty() && !_compoundShapeResource) { + if (!shapeURL.isEmpty() && !_collisionGeometryResource) { const_cast(this)->fetchCollisionGeometryResource(); } - if (_compoundShapeResource && _compoundShapeResource->isLoaded()) { + if (_collisionGeometryResource && _collisionGeometryResource->isLoaded()) { // we have both URLs AND both geometries AND they are both fully loaded. if (_needsInitialSimulation) { // the _model's offset will be wrong until _needsInitialSimulation is false @@ -368,7 +367,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { } if (type == SHAPE_TYPE_COMPOUND) { - if (!_compoundShapeResource || !_compoundShapeResource->isLoaded()) { + if (!_collisionGeometryResource || !_collisionGeometryResource->isLoaded()) { return; } @@ -376,8 +375,8 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { // should never fall in here when collision model not fully loaded // TODO: assert that all geometries exist and are loaded - //assert(_model && _model->isLoaded() && _compoundShapeResource && _compoundShapeResource->isLoaded()); - const HFMModel& collisionGeometry = _compoundShapeResource->getHFMModel(); + //assert(_model && _model->isLoaded() && _collisionGeometryResource && _collisionGeometryResource->isLoaded()); + const HFMModel& collisionGeometry = _collisionGeometryResource->getHFMModel(); ShapeInfo::PointCollection& pointCollection = shapeInfo.getPointCollection(); pointCollection.clear(); @@ -499,7 +498,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { std::vector> meshes; if (type == SHAPE_TYPE_SIMPLE_COMPOUND) { - auto& hfmMeshes = _compoundShapeResource->getHFMModel().meshes; + auto& hfmMeshes = _collisionGeometryResource->getHFMModel().meshes; meshes.reserve(hfmMeshes.size()); for (auto& hfmMesh : hfmMeshes) { meshes.push_back(hfmMesh._mesh); @@ -727,10 +726,10 @@ int RenderableModelEntityItem::avatarJointIndex(int modelJointIndex) { bool RenderableModelEntityItem::contains(const glm::vec3& point) const { auto model = getModel(); - if (EntityItem::contains(point) && model && _compoundShapeResource && _compoundShapeResource->isLoaded()) { + if (EntityItem::contains(point) && model && _collisionGeometryResource && _collisionGeometryResource->isLoaded()) { glm::mat4 worldToHFMMatrix = model->getWorldToHFMMatrix(); glm::vec3 hfmPoint = worldToHFMMatrix * glm::vec4(point, 1.0f); - return _compoundShapeResource->getHFMModel().convexHullContains(hfmPoint); + return _collisionGeometryResource->getHFMModel().convexHullContains(hfmPoint); } return false; @@ -960,6 +959,10 @@ QStringList RenderableModelEntityItem::getJointNames() const { return result; } +QString RenderableModelEntityItem::getCollisionShapeURL() const { + return getShapeType() == SHAPE_TYPE_COMPOUND ? getCompoundShapeURL() : getModelURL(); +} + scriptable::ScriptableModelBase render::entities::ModelEntityRenderer::getScriptableModel() { auto model = resultWithReadLock([this]{ return _model; }); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 7f84b3ae62..3c6f1d956c 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -79,7 +79,7 @@ public: virtual bool isReadyToComputeShape() const override; virtual void computeShapeInfo(ShapeInfo& shapeInfo) override; - bool computeShapeFailedToLoad(); + bool unableToLoadCollisionShape(); virtual bool contains(const glm::vec3& point) const override; void stopModelOverrideIfNoParent(); @@ -113,6 +113,9 @@ public: virtual int getJointIndex(const QString& name) const override; virtual QStringList getJointNames() const override; + // Returns the URL used for the collision shape + QString getCollisionShapeURL() const; + private: bool needsUpdateModelBounds() const; void autoResizeJointArrays(); @@ -120,7 +123,7 @@ private: bool readyToAnimate() const; void fetchCollisionGeometryResource(); - GeometryResource::Pointer _compoundShapeResource; + GeometryResource::Pointer _collisionGeometryResource; std::vector _jointMap; QVariantMap _originalTextures; bool _jointMapCompleted { false }; diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index f276bea05d..346a05a1bf 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -590,10 +590,6 @@ QString ModelEntityItem::getCompoundShapeURL() const { return _compoundShapeURL.get(); } -QString ModelEntityItem::getCollisionShapeURL() const { - return getShapeType() == SHAPE_TYPE_COMPOUND ? getCompoundShapeURL() : getModelURL(); -} - void ModelEntityItem::setColor(const glm::u8vec3& value) { withWriteLock([&] { _color = value; diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 75a695f1c0..d9a7e5a743 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -75,9 +75,6 @@ public: static const QString DEFAULT_COMPOUND_SHAPE_URL; QString getCompoundShapeURL() const; - // Returns the URL used for the collision shape - QString getCollisionShapeURL() const; - // model related properties virtual void setModelURL(const QString& url); virtual void setCompoundShapeURL(const QString& url); diff --git a/libraries/physics/src/PhysicalEntitySimulation.cpp b/libraries/physics/src/PhysicalEntitySimulation.cpp index 0a08aaa28d..85c53af10a 100644 --- a/libraries/physics/src/PhysicalEntitySimulation.cpp +++ b/libraries/physics/src/PhysicalEntitySimulation.cpp @@ -49,9 +49,9 @@ void PhysicalEntitySimulation::addEntityInternal(EntityItemPointer entity) { assert(entity); assert(!entity->isDead()); uint8_t region = _space->getRegion(entity->getSpaceIndex()); - bool shouldBePhysical = region < workload::Region::R3 && entity->shouldBePhysical(); + bool maybeShouldBePhysical = (region < workload::Region::R3 || region == workload::Region::UNKNOWN) && entity->shouldBePhysical(); bool canBeKinematic = region <= workload::Region::R3; - if (shouldBePhysical) { + if (maybeShouldBePhysical) { EntityMotionState* motionState = static_cast(entity->getPhysicsInfo()); if (motionState) { motionState->setRegion(region); @@ -330,6 +330,18 @@ void PhysicalEntitySimulation::buildMotionStatesForEntitiesThatNeedThem() { continue; } + uint8_t region = _space->getRegion(entity->getSpaceIndex()); + if (region == workload::Region::UNKNOWN) { + // the workload hasn't categorized it yet --> skip for later + ++entityItr; + continue; + } + if (region > workload::Region::R2) { + // not in physical zone --> remove from list + entityItr = _entitiesToAddToPhysics.erase(entityItr); + continue; + } + if (entity->isReadyToComputeShape()) { ShapeRequest shapeRequest(entity); ShapeRequests::iterator requestItr = _shapeRequests.find(shapeRequest); diff --git a/libraries/workload/src/workload/Region.h b/libraries/workload/src/workload/Region.h index 43aed9aef4..0262899d01 100644 --- a/libraries/workload/src/workload/Region.h +++ b/libraries/workload/src/workload/Region.h @@ -21,6 +21,7 @@ public: R1 = 0, R2, R3, + R4, UNKNOWN, INVALID, }; @@ -71,4 +72,4 @@ inline uint8_t Region::computeTransitionIndex(uint8_t prevIndex, uint8_t newInde } // namespace workload -#endif // hifi_workload_Region_h \ No newline at end of file +#endif // hifi_workload_Region_h diff --git a/libraries/workload/src/workload/RegionState.cpp b/libraries/workload/src/workload/RegionState.cpp index 47179ad6f7..ade7e47e4d 100644 --- a/libraries/workload/src/workload/RegionState.cpp +++ b/libraries/workload/src/workload/RegionState.cpp @@ -28,7 +28,9 @@ void RegionState::run(const workload::WorkloadContextPointer& renderContext, con // ... // inputs[2N] = vector of ids exiting region N // inputs[2N + 1] = vector of ids entering region N - assert(inputs.size() == 2 * Region::UNKNOWN); + // + // But we only pass inputs for R1 through R3 + assert(inputs.size() == 2 * (int32_t)(Region::R3 + 1)); // The id's in each vector are sorted in ascending order // because the source vectors are scanned in ascending order. diff --git a/libraries/workload/src/workload/RegionState.h b/libraries/workload/src/workload/RegionState.h index 40db9d4982..9552709d8e 100644 --- a/libraries/workload/src/workload/RegionState.h +++ b/libraries/workload/src/workload/RegionState.h @@ -54,7 +54,7 @@ namespace workload { using JobModel = workload::Job::ModelI; RegionState() { - _state.resize(Region::UNKNOWN); + _state.resize(Region::R3 + 1); } void configure(const Config& config); diff --git a/libraries/workload/src/workload/RegionTracker.cpp b/libraries/workload/src/workload/RegionTracker.cpp index 381b92c414..0866c91709 100644 --- a/libraries/workload/src/workload/RegionTracker.cpp +++ b/libraries/workload/src/workload/RegionTracker.cpp @@ -33,15 +33,15 @@ void RegionTracker::run(const WorkloadContextPointer& context, Outputs& outputs) //Changes changes; space->categorizeAndGetChanges(outChanges); - // use exit/enter lists for each region less than Region::UNKNOWN + // use exit/enter lists for each region less than Region::R4 outRegionChanges.resize(2 * (workload::Region::NUM_CLASSIFICATIONS - 1)); for (uint32_t i = 0; i < outChanges.size(); ++i) { Space::Change& change = outChanges[i]; - if (change.prevRegion < Region::UNKNOWN) { + if (change.prevRegion < Region::R4) { // EXIT list index = 2 * regionIndex outRegionChanges[2 * change.prevRegion].push_back(change.proxyId); } - if (change.region < Region::UNKNOWN) { + if (change.region < Region::R4) { // ENTER list index = 2 * regionIndex + 1 outRegionChanges[2 * change.region + 1].push_back(change.proxyId); } diff --git a/libraries/workload/src/workload/Space.cpp b/libraries/workload/src/workload/Space.cpp index 747df5f6c4..f045c8311f 100644 --- a/libraries/workload/src/workload/Space.cpp +++ b/libraries/workload/src/workload/Space.cpp @@ -99,7 +99,7 @@ void Space::categorizeAndGetChanges(std::vector& changes) { if (proxy.region < Region::INVALID) { glm::vec3 proxyCenter = glm::vec3(proxy.sphere); float proxyRadius = proxy.sphere.w; - uint8_t region = Region::UNKNOWN; + uint8_t region = Region::R4; for (uint32_t j = 0; j < numViews; ++j) { auto& view = _views[j]; // for each 'view' we need only increment 'k' below the current value of 'region'