diff --git a/interface/src/workload/GameWorkload.cpp b/interface/src/workload/GameWorkload.cpp index d68889408a..63fe440fcd 100644 --- a/interface/src/workload/GameWorkload.cpp +++ b/interface/src/workload/GameWorkload.cpp @@ -38,13 +38,8 @@ void GameWorkload::shutdown() { } void GameWorkload::updateViews(const ViewFrustum& frustum) { - // TEMP HACK: one view with static radiuses - float r0 = 10.0f; - float r1 = 20.0f; - float r2 = 30.0f; - workload::View view(frustum.getPosition(), r0, r1, r2); workload::Views views; - views.push_back(view); - _engine->setInput(views); + views.emplace_back(workload::View::evalFromFrustum(frustum)); + _engine->feedInput(views); } diff --git a/libraries/render-utils/src/drawWorkloadView.slv b/libraries/render-utils/src/drawWorkloadView.slv index c5e3d0bb5b..09dc41e471 100644 --- a/libraries/render-utils/src/drawWorkloadView.slv +++ b/libraries/render-utils/src/drawWorkloadView.slv @@ -22,8 +22,10 @@ uniform vec4 inColor; struct WorkloadView { + vec4 direction_far; + vec4 fov; vec4 origin; - vec4 radiuses; + vec4 regions[3]; }; #if defined(GPU_GL410) @@ -83,7 +85,10 @@ void main(void) { vec4 spriteVert = UNIT_SPRITE[UNIT_SPRITE_INDICES[vertexID]]; WorkloadView view = getWorkloadView(viewID); - vec4 proxyPosWorld = vec4(view.origin.xyz, 1.0); + + vec4 region = view.regions[regionID]; + + vec4 proxyPosWorld = vec4(region.xyz, 1.0); // standard transform, bring proxy in view space TransformCamera cam = getTransformCamera(); @@ -103,7 +108,7 @@ void main(void) { vec3 dirX = normalize(cross(vec3(0.0, 1.0, 0.0), dirZ)); vec3 dirY = normalize(cross(dirZ, dirX)); */ - float regionRadius = view.radiuses[regionID]; + float regionRadius = region.w; vec3 originSpaceVert = dirY * (-0.02) + regionRadius * ( dirX * spriteVert.x + dirY * spriteVert.y + dirZ * spriteVert.z); diff --git a/libraries/task/src/task/Task.h b/libraries/task/src/task/Task.h index 74af60b231..7c66cf9810 100644 --- a/libraries/task/src/task/Task.h +++ b/libraries/task/src/task/Task.h @@ -76,9 +76,9 @@ public: JobConcept(QConfigPointer config) : _config(config) {} virtual ~JobConcept() = default; - virtual void setInput(const Varying& input) {} virtual const Varying getInput() const { return Varying(); } virtual const Varying getOutput() const { return Varying(); } + virtual Varying& editInput() = 0; virtual QConfigPointer& getConfiguration() { return _config; } virtual void applyConfiguration() = 0; @@ -140,9 +140,9 @@ public: Varying _input; Varying _output; - void setInput(const Varying& input) override { _input = input; } const Varying getInput() const override { return _input; } const Varying getOutput() const override { return _output; } + Varying& editInput() override { return _input; } template Model(const Varying& input, QConfigPointer config, A&&... args) : @@ -177,9 +177,12 @@ public: Job(std::string name, ConceptPointer concept) : _concept(concept), _name(name) {} - void setInput(const Varying& in) { _concept->setInput(in); } const Varying getInput() const { return _concept->getInput(); } const Varying getOutput() const { return _concept->getOutput(); } + + template void feedInput(const I& in) { _concept->editInput().edit() = in; } + + QConfigPointer& getConfiguration() const { return _concept->getConfiguration(); } void applyConfiguration() { return _concept->applyConfiguration(); } @@ -243,6 +246,8 @@ public: const Varying getInput() const override { return _input; } const Varying getOutput() const override { return _output; } + Varying& editInput() override { return _input; } + typename Jobs::iterator editJob(std::string name) { typename Jobs::iterator jobIt; for (jobIt = _jobs.begin(); jobIt != _jobs.end(); ++jobIt) { diff --git a/libraries/workload/src/workload/Region.h b/libraries/workload/src/workload/Region.h index 691900f2b1..43aed9aef4 100644 --- a/libraries/workload/src/workload/Region.h +++ b/libraries/workload/src/workload/Region.h @@ -28,6 +28,8 @@ public: static const uint8_t NUM_CLASSIFICATIONS = 4; static const uint8_t NUM_TRANSITIONS = NUM_CLASSIFICATIONS * (NUM_CLASSIFICATIONS - 1); + static const uint8_t NUM_VIEW_REGIONS = (NUM_CLASSIFICATIONS - 1); + static uint8_t computeTransitionIndex(uint8_t prevIndex, uint8_t newIndex); }; diff --git a/libraries/workload/src/workload/View.cpp b/libraries/workload/src/workload/View.cpp index c34983e08c..dba4ffed7c 100644 --- a/libraries/workload/src/workload/View.cpp +++ b/libraries/workload/src/workload/View.cpp @@ -13,7 +13,36 @@ using namespace workload; -View evalFromFrustum(const ViewFrustum& frustum, float farDistance) { - - return View(); +void View::setFov(float angleRad) { + float halfAngle = angleRad * 0.5f; + + fov_halfAngle_tan_cos_sin.x = halfAngle; + fov_halfAngle_tan_cos_sin.y = tanf(halfAngle); + fov_halfAngle_tan_cos_sin.z = cosf(halfAngle); + fov_halfAngle_tan_cos_sin.w = sinf(halfAngle); } + +View View::evalFromFrustum(const ViewFrustum& frustum) { + View view; + view.origin = frustum.getPosition(); + view.direction = frustum.getDirection(); + view.setFov(frustum.getFieldOfView()); + + return view; +} + +Sphere View::evalRegionSphere(const View& view, float originRadius, float maxDistance) { + float radius = (maxDistance + originRadius) / 2.0; + float center = radius - originRadius; + return Sphere(view.origin + view.direction * center, radius); +} + +void View::updateRegions(View& view) { + float refFar = 10.0f; + float refClose = 2.0f; + for (int i = 0; i < Region::NUM_VIEW_REGIONS; i++) { + float weight = i + 1.0f; + 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 5c2c5bbbd2..7484c46398 100644 --- a/libraries/workload/src/workload/View.h +++ b/libraries/workload/src/workload/View.h @@ -29,18 +29,34 @@ public: View() = default; View(const View& view) = default; - View(const glm::vec3& pos, float nearRadius, float midRadius, float farRadius) : - origin(pos) { - regions[Region::R1] = Sphere(pos, nearRadius); - regions[Region::R2] = Sphere(pos, midRadius); - regions[Region::R3] = Sphere(pos, farRadius); - } + // View attributes: - glm::vec3 origin; - float _padding { 1.0f }; - Sphere regions[(Region::NUM_CLASSIFICATIONS - 1)]; + // direction + glm::vec3 direction{ 0.0f, 0.0f, -1.0f }; - static View evalFromFrustum(const ViewFrustum& frustum, float farDistance); + // Max radius + float maxRadius{ FLT_MAX }; + + // Fov stores the half field of view angle, and tan/cos/sin ready to go, default is fov of 90deg + glm::vec4 fov_halfAngle_tan_cos_sin { M_PI_4, 1.0f, M_SQRT2 * 0.5f, M_SQRT2 * 0.5f }; + + // Origin position + glm::vec3 origin{ 0.0f }; + + // Origin radius + float originRadius{ 0.5f }; + + // N regions spheres + Sphere regions[Region::NUM_VIEW_REGIONS]; + + // Set fov properties from angle + void setFov(float angleRad); + + + static View evalFromFrustum(const ViewFrustum& frustum); + static Sphere evalRegionSphere(const View& view, float originRadius, float maxDistance); + + static void updateRegions(View& view); }; using Views = std::vector; diff --git a/libraries/workload/src/workload/ViewTask.cpp b/libraries/workload/src/workload/ViewTask.cpp index 70f7406e82..451f3c820f 100644 --- a/libraries/workload/src/workload/ViewTask.cpp +++ b/libraries/workload/src/workload/ViewTask.cpp @@ -18,7 +18,11 @@ void SetupViews::configure(const Config& config) { void SetupViews::run(const WorkloadContextPointer& renderContext, const Input& inputs) { - inputs; + Views views = inputs; + for (auto& v : views) { + View::updateRegions(v); + } + renderContext->_space->setViews(views); }