Drafting the Octree and a debugging job

This commit is contained in:
samcake 2016-01-25 18:14:05 -08:00
parent c1626f1bf7
commit b96bbab22f
4 changed files with 138 additions and 82 deletions

View file

@ -25,6 +25,7 @@
#include "render/DrawTask.h" #include "render/DrawTask.h"
#include "render/DrawStatus.h" #include "render/DrawStatus.h"
#include "render/DrawSceneOctree.h"
#include "AmbientOcclusionEffect.h" #include "AmbientOcclusionEffect.h"
#include "AntialiasingEffect.h" #include "AntialiasingEffect.h"
@ -135,6 +136,13 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) : Task() {
_drawDebugDeferredBufferIndex = (int)_jobs.size() - 1; _drawDebugDeferredBufferIndex = (int)_jobs.size() - 1;
enableJob(_drawDebugDeferredBufferIndex, false); enableJob(_drawDebugDeferredBufferIndex, false);
// Scene Octree Debuging job
{
addJob<DrawSceneOctree>("DrawSceneOctree");
// _drawStatusJobIndex = (int)_jobs.size() - 1;
// enableJob(_drawStatusJobIndex, false);
}
// Status icon rendering job // Status icon rendering job
{ {
// Grab a texture map representing the different status icons and assign that to the drawStatsuJob // Grab a texture map representing the different status icons and assign that to the drawStatsuJob

View file

@ -1,29 +1,57 @@
//
// Octree.h
// render/src/render
//
// Created by Sam Gateau on 1/25/16.
// Copyright 2014 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_render_Octree_h
#define hifi_render_Octree_h
#include <vector>
#include <memory>
#include <cassert>
#include <array>
#include <glm/glm.hpp>
#include <glm/gtx/bit.hpp>
namespace render { namespace render {
class Octree { class Octree {
public: public:
enum Octant {
L_B_N = 0, using LinkStorage = int8_t;
R_B_N = 1, enum Link : LinkStorage {
L_T_N = 2,
R_T_N = 3, Octant_L_B_N = 0,
L_B_F = 4, Octant_R_B_N = 1,
R_B_F = 5, Octant_L_T_N = 2,
L_T_F = 6, Octant_R_T_N = 3,
R_T_F = 7, Octant_L_B_F = 4,
Octant_R_B_F = 5,
Octant_L_T_F = 6,
Octant_R_T_F = 7,
NUM_OCTANTS, NUM_OCTANTS,
};
Parent = NUM_OCTANTS,
enum OctantBits {
NUM_LINKS = NUM_OCTANTS + 1,
XAxis = 0x01, XAxis = 0x01,
YAxis = 0x02, YAxis = 0x02,
ZAXis = 0x04, ZAxis = 0x04,
NoLink = 0x0F,
}; };
using Octant = Link;
// Depth, Width, Volume // Depth, Width, Volume
// {0, 1, 1} // {0, 1, 1}
// {1, 2, 8} // {1, 2, 8}
@ -44,96 +72,106 @@ namespace render {
// {16, 65536, 281474976710656} // {16, 65536, 281474976710656}
using Depth = int8_t; // Max depth is 15 => 32Km root down to 1m cells using Depth = int8_t; // Max depth is 15 => 32Km root down to 1m cells
using Coord = int16_t// Need 16bits integer coordinates on each axes: 32768 cell positions using Coord = int16_t;// Need 16bits integer coordinates on each axes: 32768 cell positions
using Pos = glm::vec3<Coord>; using Coord3 = glm::i16vec3;
using Coord4 = glm::i16vec4;
class CellCoord { class CellPoint {
void assertValid() {
assert((pos.x >= 0) && (pos.y >= 0) && (pos.z >= 0));
assert((pos.x < (2 << depth)) && (pos.y < (2 << depth)) && (pos.z < (2 << depth)));
}
public: public:
CellCoord() {} CellPoint() {}
CellCoord(const Pos& xyz, Depth d) : pos(xyz), depth(d) {} CellPoint(const Coord3& xyz, Depth d) : pos(xyz), depth(d) { assertValid(); }
CellCoord(Depth d) : pos(0), depth(d) {} CellPoint(Depth d) : pos(0), depth(d) { assertValid(); }
union { Coord3 pos{ 0 };
glm::vec4<Coord> raw; uint8_t spare{ 0 };
struct { Depth depth{ 0 };
Pos pos { 0 };
int8_t spare { 0 };
Depth depth { 0 }; // Eval the octant of this cell relative to its parent
}; Octant octant() const { return Octant((pos.x & XAxis) | (pos.y & YAxis) | (pos.z & ZAxis)); }
};
// Get the Parent cell pos of this cell
CellCoord parent() const { return CellCoord{ pos >> 1, (d <= 0? 0 : d-1) }; } CellPoint parent() const {
CellCoord child(Octant octant) const { return CellCoord{ Pos((pos.x << 1) | (octant & XAxis), return CellPoint{ pos >> Coord3(1), Depth(depth <= 0 ? 0 : depth - 1) };
(pos.y << 1) | (octant & YAxis), }
(pos.z << 1) | (octant & ZAxis)), d+1 }; } CellPoint child(Link octant) const {
return CellPoint{ pos << Coord3(1) | Coord3((Coord)bool(octant & XAxis), (Coord)bool(octant & YAxis), (Coord)bool(octant & ZAxis)), Depth(depth + 1) };
}
using vector = std::vector< CellPoint >;
static vector rootTo(const CellPoint& dest) {
CellPoint current{ dest };
vector path(dest.depth + 1);
path[dest.depth] = dest;
while (current.depth > 0) {
current = current.parent();
path[current.depth] = current;
}
return path;
}
}; };
using CellPath = CellPoint::vector;
class Range { class Range {
public: public:
Pos _min; Coord3 _min;
Pos _max; Coord3 _max;
} };
// Cell or Brick Indexing
using Index = int32_t;
static const Index INVALID = -1;
using Indices = std::vector<Index>;
// the cell description // the cell description
class Cell { class Cell {
public: public:
using Index = int32_t;
static const Index INVALID = -1;
CellPoint cellpos;
Index children[NUM_OCTANTS] = { INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID };
Index parent{ INVALID }; std::array<Index, NUM_LINKS> links;
Index parent() const { return links[Parent]; }
bool asParent() const { return parent() != INVALID; }
Index child(Link octant) const { return links[octant]; }
bool asChild(Link octant) const { return child(octant) != INVALID; }
Index brick{ INVALID }; Index brick{ INVALID };
CellPos cellpos; Cell() :
links({ { INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID } })
{}
}; };
using Cells = std::vector< Cell >; using Cells = std::vector< Cell >;
class CellPath {
public:
using PosArray = std::vector< CellPos >;
PosArray cellCoords;
};
class Brick { class Brick {
public: public:
} };
using Bricks = std::vector< Block >; using Bricks = std::vector< Brick >;
// Octree members // Octree members
Cells _cells; Cells _cells = Cells(1, Cell()); // start with only the Cell root
Bricks _bricks; Bricks _bricks;
Octree() {};
CellPath rootTo(const CellPos& dest) {
CellPos current{ dest }; // allocatePath
CellPath path(dest.depth + 1) Indices allocateCellPath(const CellPath& path);
path[dest.depth] = dest;
while (current.depth > 0) {
current = current.parent();
path[current.depth] = current);
}
return path;
}
CellPath rootTo(const CellPos& dest) {
CellPos current{ dest };
CellPath path(dest.depth + 1)
path[dest.depth] = dest;
while (current.depth > 0) {
current = current.parent();
path[current.depth] = current);
}
return path;
}
}; };
} }
#endif // hifi_render_Octree_h

View file

@ -139,6 +139,12 @@ void PendingChanges::merge(PendingChanges& changes) {
Scene::Scene() { Scene::Scene() {
_items.push_back(Item()); // add the itemID #0 to nothing _items.push_back(Item()); // add the itemID #0 to nothing
_masterBucketMap.allocateStandardOpaqueTranparentBuckets(); _masterBucketMap.allocateStandardOpaqueTranparentBuckets();
_spatialTree;
Octree::CellPoint point{ Octree::Coord3{ 2, 4, 3 }, 3 };
auto path = Octree::CellPoint::rootTo(point);
} }
ItemID Scene::allocateID() { ItemID Scene::allocateID() {

View file

@ -27,6 +27,8 @@
#include "model/Material.h" #include "model/Material.h"
#include "ShapePipeline.h" #include "ShapePipeline.h"
#include "Octree.h"
namespace render { namespace render {
class Context; class Context;
@ -527,6 +529,8 @@ protected:
void removeItems(const ItemIDs& ids); void removeItems(const ItemIDs& ids);
void updateItems(const ItemIDs& ids, UpdateFunctors& functors); void updateItems(const ItemIDs& ids, UpdateFunctors& functors);
Octree _spatialTree;
friend class Engine; friend class Engine;
}; };