Adding more detailed classes and introducing an upfront setupVIew job

This commit is contained in:
samcake 2018-03-05 18:04:25 -08:00
parent 0ab5fc178f
commit 450786404c
15 changed files with 246 additions and 93 deletions

View file

@ -4261,14 +4261,7 @@ void Application::idle() {
}
{
// TEMP HACK: one view with static radiuses
float r0 = 10.0f;
float r1 = 20.0f;
float r2 = 30.0f;
workload::Space::View view(_viewFrustum.getPosition(), r0, r1, r2);
std::vector<workload::Space::View> views;
views.push_back(view);
getEntities()->getWorkloadSpace()->setViews(views);
_gameWorkload.updateViews(_viewFrustum);
_gameWorkload._engine->run();
}
{

View file

@ -9,6 +9,7 @@
//
#include "GameWorkload.h"
#include "GameWorkloadRenderer.h"
#include <ViewFrustum.h>
GameWorkloadContext::GameWorkloadContext(const workload::SpacePointer& space, const render::ScenePointer& scene) : WorkloadContext(space), _scene(scene) {
}
@ -36,5 +37,14 @@ void GameWorkload::shutdown() {
_engine.reset();
}
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);
}

View file

@ -31,6 +31,8 @@ public:
void startup(const workload::SpacePointer& space, const render::ScenePointer& scene);
void shutdown();
void updateViews(const ViewFrustum& frustum);
workload::EnginePointer _engine;
};

View file

@ -58,7 +58,7 @@ void GameSpaceToRender::run(const workload::WorkloadContextPointer& runContext,
std::vector<workload::Space::Proxy> proxies(space->getNumAllocatedProxies());
space->copyProxyValues(proxies.data(), (uint32_t)proxies.size());
std::vector<workload::Space::View> views(space->getNumViews());
workload::Views views(space->getNumViews());
if (!freezeViews) {
space->copyViews(views);
}
@ -144,9 +144,9 @@ void GameWorkloadRenderItem::setAllProxies(const std::vector<workload::Space::Pr
_numAllProxies = (uint32_t) proxies.size();
}
void GameWorkloadRenderItem::setAllViews(const std::vector<workload::Space::View>& views) {
void GameWorkloadRenderItem::setAllViews(const workload::Views& views) {
_myOwnViews = views;
static const uint32_t sizeOfView = sizeof(workload::Space::View);
static const uint32_t sizeOfView = sizeof(workload::View);
if (!_allViewsBuffer) {
_allViewsBuffer = std::make_shared<gpu::Buffer>(sizeOfView);
}

View file

@ -64,7 +64,7 @@ public:
void showViews(bool show);
void setAllProxies(const std::vector<workload::Space::Proxy>& proxies);
void setAllViews(const std::vector<workload::Space::View>& views);
void setAllViews(const workload::Views& views);
render::ItemKey getKey() const;
@ -75,7 +75,7 @@ protected:
gpu::BufferPointer _allProxiesBuffer;
uint32_t _numAllProxies{ 0 };
std::vector<workload::Space::View> _myOwnViews;
workload::Views _myOwnViews;
gpu::BufferPointer _allViewsBuffer;
uint32_t _numAllViews{ 0 };

View file

@ -76,6 +76,7 @@ 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(); }
@ -139,6 +140,7 @@ 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; }
@ -175,6 +177,7 @@ 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(); }
QConfigPointer& getConfiguration() const { return _concept->getConfiguration(); }

View file

@ -23,10 +23,10 @@ void ClassificationTracker::run(const WorkloadContextPointer& context, Outputs&
if (space) {
Changes changes;
space->categorizeAndGetChanges(changes);
outputs.resize(workload::Space::NUM_TRANSITIONS);
outputs.resize(workload::Region::NUM_TRANSITIONS);
for (uint32_t i = 0; i < changes.size(); ++i) {
int32_t j = Space::computeTransitionIndex(changes[i].prevRegion, changes[i].region);
assert(j >= 0 && j < workload::Space::NUM_TRANSITIONS);
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);
}
}

View file

@ -16,23 +16,24 @@
#include <iostream>
#include "ViewTask.h"
#include "ClassificationTracker.h"
namespace workload {
WorkloadContext::WorkloadContext(const SpacePointer& space) : task::JobContext(trace_workload()), _space(space) {}
using EngineModel = Task::Model<class EngineBuilder>;
class EngineBuilder {
public:
using JobModel = Task::Model<EngineModel>;
void build(EngineModel& model, const Varying& in, Varying& out) {
using Input = Views;
using JobModel = Task::ModelI<EngineBuilder, Input>;
void build(JobModel& model, const Varying& in, Varying& out) {
model.addJob<SetupViews>("setupViews", in);
auto classifications = model.addJob<ClassificationTracker>("classificationTracker");
}
};
Engine::Engine(const WorkloadContextPointer& context) : Task("Engine", EngineModel::create()),
Engine::Engine(const WorkloadContextPointer& context) : Task("Engine", EngineBuilder::JobModel::create()),
_context(context) {
}
} // namespace workload

View file

@ -0,0 +1,72 @@
//
// Region.h
// libraries/workload/src/workload
//
// Created by Sam Gateau 2018.03.05
// Copyright 2018 High Fidelity, Inc.
//
// 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_Region_h
#define hifi_workload_Region_h
namespace workload {
class Region {
public:
using Type = uint8_t;
enum Name : uint8_t {
R1 = 0,
R2,
R3,
UNKNOWN,
INVALID,
};
static const uint8_t NUM_CLASSIFICATIONS = 4;
static const uint8_t NUM_TRANSITIONS = NUM_CLASSIFICATIONS * (NUM_CLASSIFICATIONS - 1);
static uint8_t computeTransitionIndex(uint8_t prevIndex, uint8_t newIndex);
};
inline uint8_t Region::computeTransitionIndex(uint8_t prevIndex, uint8_t newIndex) {
// given prevIndex and newIndex compute an index into the transition list,
// where the lists between unchanged indices don't exist (signaled by index = -1).
//
// Given an NxN array
// let p = i + N * j
//
// then k = -1 when i == j
// = p - (1 + p/(N+1)) when i != j
//
// i 0 1 2 3
// j +-------+-------+-------+-------+
// |p = 0 | 1 | 2 | 3 |
// 0 | | | | |
// |k = -1 | 0 | 1 | 2 |
// +-------+-------+-------+-------+
// | 4 | 5 | 6 | 7 |
// 1 | | | | |
// | 3 | -1 | 4 | 5 |
// +-------+-------+-------+-------+
// | 8 | 9 | 10 | 11 |
// 2 | | | | |
// | 6 | 7 | -1 | 8 |
// +-------+-------+-------+-------+
// | 12 | 13 | 14 | 15 |
// 3 | | | | |
// | 9 | 10 | 11 | -1 |
// +-------+-------+-------+-------+
uint8_t p = prevIndex + Region::NUM_CLASSIFICATIONS * newIndex;
if (0 == (p % (Region::NUM_CLASSIFICATIONS + 1))) {
return -1;
}
return p - (1 + p / (Region::NUM_CLASSIFICATIONS + 1));
}
} // namespace workload
#endif // hifi_workload_Region_h

View file

@ -33,8 +33,8 @@ int32_t Space::createProxy(const Space::Sphere& newSphere) {
int32_t index = _freeIndices.back();
_freeIndices.pop_back();
_proxies[index].sphere = newSphere;
_proxies[index].region = Space::REGION_UNKNOWN;
_proxies[index].prevRegion = Space::REGION_UNKNOWN;
_proxies[index].region = Region::UNKNOWN;
_proxies[index].prevRegion = Region::UNKNOWN;
return index;
}
}
@ -54,7 +54,7 @@ void Space::updateProxies(const std::vector<ProxyUpdate>& changedProxies) {
}
}
void Space::setViews(const std::vector<Space::View>& views) {
void Space::setViews(const Views& views) {
_views = views;
}
@ -68,12 +68,14 @@ void Space::categorizeAndGetChanges(std::vector<Space::Change>& changes) {
uint32_t numViews = (uint32_t)_views.size();
for (uint32_t i = 0; i < numProxies; ++i) {
Proxy& proxy = _proxies[i];
if (proxy.region < Space::REGION_INVALID) {
uint8_t region = Space::REGION_UNKNOWN;
if (proxy.region < Region::INVALID) {
uint8_t region = Region::UNKNOWN;
for (uint32_t j = 0; j < numViews; ++j) {
float distance2 = glm::distance2(_views[j].center, glm::vec3(_proxies[i].sphere));
auto& view = _views[j];
float distance2 = glm::distance2(view.origin, glm::vec3(proxy.sphere));
for (uint8_t c = 0; c < region; ++c) {
float touchDistance = _views[j].radiuses[c] + _proxies[i].sphere.w;
float touchDistance = view.regions[c].w + proxy.sphere.w;
if (distance2 < touchDistance * touchDistance) {
region = c;
break;
@ -104,7 +106,7 @@ void Space::deleteProxy(int32_t proxyId) {
}
}
} else {
_proxies[proxyId].region = Space::REGION_INVALID;
_proxies[proxyId].region = Region::INVALID;
_freeIndices.push_back(proxyId);
}
}

View file

@ -19,22 +19,13 @@
#include <vector>
#include <glm/glm.hpp>
#include "View.h"
namespace workload {
class Space {
public:
static const int32_t NUM_CLASSIFICATIONS = 4;
static const int32_t NUM_TRANSITIONS = NUM_CLASSIFICATIONS * (NUM_CLASSIFICATIONS - 1);
static int32_t computeTransitionIndex(int32_t prevIndex, int32_t newIndex);
static const uint8_t REGION_NEAR = 0;
static const uint8_t REGION_MIDDLE = 1;
static const uint8_t REGION_FAR = 2;
static const uint8_t REGION_UNKNOWN = 3;
static const uint8_t REGION_INVALID = 4;
using Sphere = glm::vec4; // <x,y,z> = center, w = radius
using ProxyUpdate = std::pair<int32_t, Sphere>;
@ -43,26 +34,12 @@ public:
Proxy() : sphere(0.0f) {}
Proxy(const Sphere& s) : sphere(s) {}
Sphere sphere;
uint8_t region { REGION_UNKNOWN };
uint8_t prevRegion { REGION_UNKNOWN };
uint8_t region { Region::UNKNOWN };
uint8_t prevRegion { Region::UNKNOWN };
uint16_t _padding;
uint32_t _paddings[3];
};
class View {
public:
View() = default;
View(const glm::vec3& pos, float nearRadius, float midRadius, float farRadius) : center(pos) {
radiuses[REGION_NEAR] = nearRadius;
radiuses[REGION_MIDDLE] = midRadius;
radiuses[REGION_FAR] = farRadius;
}
glm::vec3 center;
float _padding0;
float radiuses[NUM_CLASSIFICATIONS - 1];
float _padding1;
};
class Change {
public:
Change(int32_t i, uint32_t c, uint32_t p) : proxyId(i), region(c), prevRegion(p) {}
@ -94,45 +71,10 @@ private:
void updateProxy(int32_t proxyId, const Sphere& sphere);
std::vector<Proxy> _proxies;
std::vector<View> _views;
Views _views;
std::vector<int32_t> _freeIndices;
};
inline int32_t Space::computeTransitionIndex(int32_t prevIndex, int32_t newIndex) {
// given prevIndex and newIndex compute an index into the transition list,
// where the lists between unchanged indices don't exist (signaled by index = -1).
//
// Given an NxN array
// let p = i + N * j
//
// then k = -1 when i == j
// = p - (1 + p/(N+1)) when i != j
//
// i 0 1 2 3
// j +-------+-------+-------+-------+
// |p = 0 | 1 | 2 | 3 |
// 0 | | | | |
// |k = -1 | 0 | 1 | 2 |
// +-------+-------+-------+-------+
// | 4 | 5 | 6 | 7 |
// 1 | | | | |
// | 3 | -1 | 4 | 5 |
// +-------+-------+-------+-------+
// | 8 | 9 | 10 | 11 |
// 2 | | | | |
// | 6 | 7 | -1 | 8 |
// +-------+-------+-------+-------+
// | 12 | 13 | 14 | 15 |
// 3 | | | | |
// | 9 | 10 | 11 | -1 |
// +-------+-------+-------+-------+
int32_t p = prevIndex + Space::NUM_CLASSIFICATIONS * newIndex;
if (0 == (p % (Space::NUM_CLASSIFICATIONS + 1))) {
return -1;
}
return p - (1 + p / (Space::NUM_CLASSIFICATIONS + 1));
}
using SpacePointer = std::shared_ptr<Space>;
using Changes = std::vector<Space::Change>;
using SortedChanges = std::vector<std::vector<int32_t>>;

View file

@ -0,0 +1,19 @@
//
// View.cpp
// libraries/workload/src/workload
//
// Created by Sam Gateau 2018.03.05
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "View.h"
#include <ViewFrustum.h>
using namespace workload;
View evalFromFrustum(const ViewFrustum& frustum, float farDistance) {
return View();
}

View file

@ -0,0 +1,50 @@
//
// View.h
// libraries/workload/src/workload
//
// Created by Sam Gateau 2018.03.05
// Copyright 2018 High Fidelity, Inc.
//
// 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_View_h
#define hifi_workload_View_h
#include <memory>
#include <vector>
#include <glm/glm.hpp>
#include "Region.h"
class ViewFrustum;
namespace workload {
using Sphere = glm::vec4;
class View {
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);
}
glm::vec3 origin;
float _padding { 1.0f };
Sphere regions[(Region::NUM_CLASSIFICATIONS - 1)];
static View evalFromFrustum(const ViewFrustum& frustum, float farDistance);
};
using Views = std::vector<View>;
} // namespace workload
#endif // hifi_workload_View_h

View file

@ -0,0 +1,24 @@
//
// ViewTask.cpp
// libraries/workload/src/workload
//
// Created by Sam Gateau 2018.03.05
// Copyright 2018 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "ViewTask.h"
using namespace workload;
void SetupViews::configure(const Config& config) {
}
void SetupViews::run(const WorkloadContextPointer& renderContext, const Input& inputs) {
inputs;
}

View file

@ -0,0 +1,35 @@
//
// ViewTask.h
// libraries/workload/src/workload
//
// Created by Sam Gateau 2018.03.05
// Copyright 2018 High Fidelity, Inc.
//
// 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_ViewTask_h
#define hifi_workload_ViewTask_h
#include "Engine.h"
namespace workload {
class SetupViewsConfig : public Job::Config{
Q_OBJECT
public:
SetupViewsConfig() : Job::Config(true) {}
};
class SetupViews {
public:
using Config = SetupViewsConfig;
using Input = Views;
using JobModel = Job::ModelI<SetupViews, Input, Config>;
void configure(const Config& config);
void run(const workload::WorkloadContextPointer& renderContext, const Input& inputs);
};
} // namespace workload
#endif // hifi_workload_ViewTask_h