From 03a5a6f4e09876b6e95563d1542de093c73976c6 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 7 Mar 2018 08:41:01 -0800 Subject: [PATCH 1/3] more correct proxy classification for multiple views --- libraries/workload/src/workload/Space.cpp | 27 ++++++----------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/libraries/workload/src/workload/Space.cpp b/libraries/workload/src/workload/Space.cpp index de3da5991e..7a9f90c5b8 100644 --- a/libraries/workload/src/workload/Space.cpp +++ b/libraries/workload/src/workload/Space.cpp @@ -62,10 +62,9 @@ void Space::copyViews(std::vector& copy) const { copy = _views; } -// TODO?: move this to an algorithm/job? void Space::categorizeAndGetChanges(std::vector& changes) { - uint32_t numProxies = (uint32_t)_proxies.size(); - uint32_t numViews = (uint32_t)_views.size(); + uint32_t numProxies = _proxies.size(); + uint32_t numViews = _views.size(); for (uint32_t i = 0; i < numProxies; ++i) { Proxy& proxy = _proxies[i]; if (proxy.region < Region::INVALID) { @@ -74,21 +73,11 @@ void Space::categorizeAndGetChanges(std::vector& changes) { uint8_t region = Region::UNKNOWN; for (uint32_t j = 0; j < numViews; ++j) { auto& view = _views[j]; - - glm::vec3 distance2(glm::distance2(proxyCenter, glm::vec3(view.regions[0])), glm::distance2(proxyCenter, glm::vec3(view.regions[1])), glm::distance2(proxyCenter, glm::vec3(view.regions[2]))); - glm::vec3 regionRadii2(view.regions[0].w + proxyRadius, view.regions[1].w + proxyRadius, view.regions[2].w + proxyRadius); - regionRadii2 *= regionRadii2; - auto touchTests = glm::lessThanEqual(distance2, regionRadii2); - - if (glm::any(touchTests)) { - if (touchTests.x) { - region = Region::R1; - break; - } else if (touchTests.y) { - region = Region::R2; - break; - } else { - region = Region::R3; + // for each 'view' we need only increment 'k' below the current value of 'region' + for (uint8_t k = 0; k < region; ++k) { + float touchDistance = proxyRadius + view.regions[k].w; + if (distance2(proxyCenter, glm::vec3(view.regions[k])) < touchDistance * touchDistance) { + region = k; break; } } @@ -124,10 +113,8 @@ void Space::deleteProxy(int32_t proxyId) { } uint32_t Space::copyProxyValues(Proxy* proxies, uint32_t numDestProxies) const { - auto numCopied = std::min(numDestProxies, (uint32_t)_proxies.size()); memcpy(proxies, _proxies.data(), numCopied * sizeof(Proxy)); - return numCopied; } From 0d9b1a7368561cd3fc5518041f87583285dfdeea Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 7 Mar 2018 11:19:47 -0800 Subject: [PATCH 2/3] jobflow: RegionTracker --> RegionState --- .../src/workload/ClassificationTracker.cpp | 34 --------- libraries/workload/src/workload/Engine.cpp | 27 ++------ .../workload/src/workload/RegionState.cpp | 69 +++++++++++++++++++ libraries/workload/src/workload/RegionState.h | 38 ++++++++++ .../workload/src/workload/RegionTracker.cpp | 43 ++++++++++++ ...lassificationTracker.h => RegionTracker.h} | 22 +++--- libraries/workload/src/workload/Space.h | 8 ++- libraries/workload/src/workload/View.cpp | 2 +- libraries/workload/src/workload/View.h | 2 +- 9 files changed, 172 insertions(+), 73 deletions(-) delete mode 100644 libraries/workload/src/workload/ClassificationTracker.cpp create mode 100644 libraries/workload/src/workload/RegionState.cpp create mode 100644 libraries/workload/src/workload/RegionState.h create mode 100644 libraries/workload/src/workload/RegionTracker.cpp rename libraries/workload/src/workload/{ClassificationTracker.h => RegionTracker.h} (56%) diff --git a/libraries/workload/src/workload/ClassificationTracker.cpp b/libraries/workload/src/workload/ClassificationTracker.cpp deleted file mode 100644 index 635fb56527..0000000000 --- a/libraries/workload/src/workload/ClassificationTracker.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// -// ClassificationTracker.cpp -// libraries/workload/src/workload -// -// Created by Andrew Meadows 2018.02.21 -// Copyright 2018 High Fidelity, Inc. -// -// Originally from lighthouse3d. Modified to utilize glm::vec3 and clean up to our coding standards -// Simple plane class. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// -#include "ClassificationTracker.h" - -using namespace workload; - -void ClassificationTracker::configure(const Config& config) { -} - -void ClassificationTracker::run(const WorkloadContextPointer& context, Outputs& outputs) { - auto space = context->_space; - if (space) { - Changes changes; - space->categorizeAndGetChanges(changes); - outputs.resize(workload::Region::NUM_TRANSITIONS); - for (uint32_t i = 0; i < changes.size(); ++i) { - int32_t j = Region::computeTransitionIndex(changes[i].prevRegion, changes[i].region); - assert(j >= 0 && j < workload::Region::NUM_TRANSITIONS); - outputs[j].push_back(changes[i].proxyId); - } - } -} - diff --git a/libraries/workload/src/workload/Engine.cpp b/libraries/workload/src/workload/Engine.cpp index ce5ab6cca0..525872f190 100644 --- a/libraries/workload/src/workload/Engine.cpp +++ b/libraries/workload/src/workload/Engine.cpp @@ -17,29 +17,10 @@ #include #include "ViewTask.h" -#include "ClassificationTracker.h" +#include "RegionTracker.h" +#include "RegionState.h" namespace workload { - class DebugCout { - public: - using Inputs = SortedChanges; - using JobModel = workload::Job::ModelI; - - DebugCout() {} - - void run(const workload::WorkloadContextPointer& renderContext, const Inputs& inputs) { - qDebug() << "Some message from " << inputs.size(); - int i = 0; - for (auto& b: inputs) { - qDebug() << " Bucket Number" << i << " size is " << b.size(); - i++; - } - } - - protected: - }; - - WorkloadContext::WorkloadContext(const SpacePointer& space) : task::JobContext(trace_workload()), _space(space) {} class EngineBuilder { @@ -48,8 +29,8 @@ namespace workload { using JobModel = Task::ModelI; void build(JobModel& model, const Varying& in, Varying& out) { model.addJob("setupViews", in); - const auto classifications = model.addJob("classificationTracker"); - // model.addJob("debug", classifications); + const auto regionChanges = model.addJob("regionTracker"); + model.addJob("regionState", regionChanges); } }; diff --git a/libraries/workload/src/workload/RegionState.cpp b/libraries/workload/src/workload/RegionState.cpp new file mode 100644 index 0000000000..f779c8d2fc --- /dev/null +++ b/libraries/workload/src/workload/RegionState.cpp @@ -0,0 +1,69 @@ +// +// RegionState.cpp +// libraries/workload/src/workload +// +// Created by Andrew Meadows 2018.03.07 +// Copyright 2018 High Fidelity, Inc. +// +// Originally from lighthouse3d. Modified to utilize glm::vec3 and clean up to our coding standards +// Simple plane class. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "RegionState.h" + +using namespace workload; + +void RegionState::run(const workload::WorkloadContextPointer& renderContext, const Inputs& inputs) { + // inputs is a vector of vectors of proxyId's: + // + // inputs[0] = vector of ids exiting region 0 + // inputs[1] = vector of ids entering region 0 + // ... + // inputs[2N] = vector of ids exiting region N + // inputs[2N + 1] = vector of ids entering region N + assert(inputs.size() == 2 * Region::UNKNOWN); + + // The id's in each vector are sorted in ascending order + // because the source vectors are scanned in ascending order. + + for (uint32_t i = 0; i < _state.size(); ++i) { + const IndexVector& going = inputs[2 * i]; + const IndexVector& coming = inputs[2 * i - 1]; + if (coming.size() == 0 && going.size() == 0) { + continue; + } + if (_state[i].empty()) { + assert(going.empty()); + _state[i] = coming; + } else { + // NOTE: all vectors are sorted by proxyId! + // which means we can build the new vector by walking three vectors (going, current, coming) in one pass + IndexVector& oldState = _state[i]; + IndexVector newState; + newState.reserve(oldState.size() - going.size() + coming.size()); + uint32_t goingIndex = 0; + uint32_t comingIndex = 0; + for (uint32_t j = 0; j < oldState.size(); ++j) { + int32_t proxyId = oldState[j]; + while (comingIndex < coming.size() && coming[comingIndex] < proxyId) { + newState.push_back(coming[comingIndex]); + ++comingIndex; + } + if (goingIndex < going.size() && going[goingIndex] == proxyId) { + ++goingIndex; + } else { + newState.push_back(proxyId); + } + } + assert(goingIndex == going.size()); + while (comingIndex < coming.size()) { + newState.push_back(coming[comingIndex]); + ++comingIndex; + } + oldState.swap(newState); + } + } +} diff --git a/libraries/workload/src/workload/RegionState.h b/libraries/workload/src/workload/RegionState.h new file mode 100644 index 0000000000..366d6192d2 --- /dev/null +++ b/libraries/workload/src/workload/RegionState.h @@ -0,0 +1,38 @@ +// +// RegionState.h +// libraries/workload/src/workload +// +// Created by Andrew Meadows 2018.03.07 +// Copyright 2018 High Fidelity, Inc. +// +// Originally from lighthouse3d. Modified to utilize glm::vec3 and clean up to our coding standards +// Simple plane class. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_workload_RegionState_h +#define hifi_workload_RegionState_h + +#include "Space.h" +#include "Engine.h" + +namespace workload { + + class RegionState { + public: + using Inputs = IndexVectors; + using JobModel = workload::Job::ModelI; + + RegionState() { + _state.resize(Region::UNKNOWN); + } + + void run(const workload::WorkloadContextPointer& renderContext, const Inputs& inputs); + + protected: + IndexVectors _state; + }; +} +#endif // hifi_workload_RegionState_h diff --git a/libraries/workload/src/workload/RegionTracker.cpp b/libraries/workload/src/workload/RegionTracker.cpp new file mode 100644 index 0000000000..c2b14937ad --- /dev/null +++ b/libraries/workload/src/workload/RegionTracker.cpp @@ -0,0 +1,43 @@ +// +// RegionTracker.cpp +// libraries/workload/src/workload +// +// Created by Andrew Meadows 2018.02.21 +// Copyright 2018 High Fidelity, Inc. +// +// Originally from lighthouse3d. Modified to utilize glm::vec3 and clean up to our coding standards +// Simple plane class. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#include "RegionTracker.h" + +#include "Region.h" + +using namespace workload; + +void RegionTracker::configure(const Config& config) { +} + +void RegionTracker::run(const WorkloadContextPointer& context, Outputs& outputs) { + outputs.clear(); + auto space = context->_space; + if (space) { + Changes changes; + space->categorizeAndGetChanges(changes); + // use exit/enter lists for each region less than Region::UNKNOWN + outputs.resize(2 * (workload::Region::NUM_CLASSIFICATIONS - 1)); + for (uint32_t i = 0; i < changes.size(); ++i) { + Space::Change& change = changes[i]; + if (change.prevRegion < Region::UNKNOWN) { + // EXIT list index = 2 * regionIndex + outputs[2 * change.prevRegion].push_back(change.proxyId); + } + if (change.region < Region::UNKNOWN) { + // ENTER list index = 2 * regionIndex + 1 + outputs[2 * change.region + 1].push_back(change.proxyId); + } + } + } +} diff --git a/libraries/workload/src/workload/ClassificationTracker.h b/libraries/workload/src/workload/RegionTracker.h similarity index 56% rename from libraries/workload/src/workload/ClassificationTracker.h rename to libraries/workload/src/workload/RegionTracker.h index e3364950da..e80723a7da 100644 --- a/libraries/workload/src/workload/ClassificationTracker.h +++ b/libraries/workload/src/workload/RegionTracker.h @@ -1,5 +1,5 @@ // -// ClassificationTracker.h +// RegionTracker.h // libraries/workload/src/workload // // Created by Andrew Meadows 2018.02.21 @@ -12,27 +12,27 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef hifi_workload_ClassificationTracker_h -#define hifi_workload_ClassificationTracker_h +#ifndef hifi_workload_RegionTracker_h +#define hifi_workload_RegionTracker_h #include "Space.h" #include "Engine.h" namespace workload { - class ClassificationTrackerConfig : public Job::Config { + class RegionTrackerConfig : public Job::Config { Q_OBJECT public: - ClassificationTrackerConfig() : Job::Config(true) {} + RegionTrackerConfig() : Job::Config(true) {} }; - class ClassificationTracker { + class RegionTracker { public: - using Config = ClassificationTrackerConfig; - using Outputs = SortedChanges; - using JobModel = workload::Job::ModelO; + using Config = RegionTrackerConfig; + using Outputs = IndexVectors; + using JobModel = workload::Job::ModelO; - ClassificationTracker() {} + RegionTracker() {} void configure(const Config& config); void run(const workload::WorkloadContextPointer& renderContext, Outputs& outputs); @@ -42,4 +42,4 @@ namespace workload { } // namespace workload -#endif // hifi_workload_ClassificationTracker_h +#endif // hifi_workload_RegionTracker_h diff --git a/libraries/workload/src/workload/Space.h b/libraries/workload/src/workload/Space.h index d331647cf0..0acd69194b 100644 --- a/libraries/workload/src/workload/Space.h +++ b/libraries/workload/src/workload/Space.h @@ -24,6 +24,8 @@ namespace workload { +using IndexVector = std::vector; + class Space { public: using Sphere = glm::vec4; // = center, w = radius @@ -52,7 +54,7 @@ public: void clear(); int32_t createProxy(const Sphere& sphere); - void deleteProxies(const std::vector& deadIndices); + void deleteProxies(const IndexVector& deadIndices); void updateProxies(const std::vector& changedProxies); void setViews(const std::vector& views); @@ -72,12 +74,12 @@ private: std::vector _proxies; Views _views; - std::vector _freeIndices; + IndexVector _freeIndices; }; using SpacePointer = std::shared_ptr; using Changes = std::vector; -using SortedChanges = std::vector>; +using IndexVectors = std::vector; } // namespace workload diff --git a/libraries/workload/src/workload/View.cpp b/libraries/workload/src/workload/View.cpp index f68e7a8436..cba1168669 100644 --- a/libraries/workload/src/workload/View.cpp +++ b/libraries/workload/src/workload/View.cpp @@ -45,4 +45,4 @@ void View::updateRegions(View& view) { view.regions[i] = evalRegionSphere(view, refClose * weight, refFar * weight); refFar *= 2.0f; } -} \ No newline at end of file +} diff --git a/libraries/workload/src/workload/View.h b/libraries/workload/src/workload/View.h index a237615a7a..ea815c919a 100644 --- a/libraries/workload/src/workload/View.h +++ b/libraries/workload/src/workload/View.h @@ -63,4 +63,4 @@ using Views = std::vector; } // namespace workload -#endif // hifi_workload_View_h \ No newline at end of file +#endif // hifi_workload_View_h From 77d0c211df34cee579ac595902614774c48e5cb3 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 7 Mar 2018 15:46:42 -0800 Subject: [PATCH 3/3] fix warnings on windows --- libraries/workload/src/workload/Space.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/workload/src/workload/Space.cpp b/libraries/workload/src/workload/Space.cpp index 7a9f90c5b8..c2323fc0a1 100644 --- a/libraries/workload/src/workload/Space.cpp +++ b/libraries/workload/src/workload/Space.cpp @@ -63,8 +63,8 @@ void Space::copyViews(std::vector& copy) const { } void Space::categorizeAndGetChanges(std::vector& changes) { - uint32_t numProxies = _proxies.size(); - uint32_t numViews = _views.size(); + uint32_t numProxies = (uint32_t)_proxies.size(); + uint32_t numViews = (uint32_t)_views.size(); for (uint32_t i = 0; i < numProxies; ++i) { Proxy& proxy = _proxies[i]; if (proxy.region < Region::INVALID) {