3#include "Foundation/Logging/Logger.h"
5#include "Systems/Core/CameraSystem.h"
6#include "Systems/Core/TransformSystem.h"
10#include "TexAtlasSystem.h"
14 using namespace Cogs::Core::TexAtlas;
18 bool mightBeVisible(
const glm::mat4& M,
const glm::mat4& V,
const glm::vec4* corners,
bool restrictBetweenNearAndFar)
20 if (restrictBetweenNearAndFar) {
21 uint32_t anyInside = 0;
22 for (
size_t i = 0; i < 8; i++) {
23 const glm::vec4 p = M * corners[i];
24 if (-p.w < p.x) anyInside |= 1;
25 if (p.x < p.w) anyInside |= 2;
26 if (-p.w < p.y) anyInside |= 4;
27 if (p.y < p.w) anyInside |= 8;
28 if (-p.w < p.z) anyInside |= 16;
29 if (p.z < p.w) anyInside |= 32;
31 return anyInside == 0b111111u;
34 uint32_t anyInside = 0;
35 for (
size_t i = 0; i < 8; i++) {
36 const glm::vec4 p = M * corners[i];
37 if (-p.w < p.x) anyInside |= 1;
38 if (p.x < p.w) anyInside |= 2;
39 if (-p.w < p.y) anyInside |= 4;
40 if (p.y < p.w) anyInside |= 8;
42 const glm::vec4 q = V * corners[i];
43 if (q.z < 0.f) anyInside |= 16;
45 return anyInside == 0b011111u;
49 float getScaledError(
const glm::mat4& ,
const glm::mat4& V, glm::vec4* corners,
float texelSizeView,
float tolerance, uint32_t level)
51 float near = std::numeric_limits<float>::max();
52 for (
size_t i = 0; i < 8; i++) {
53 near = std::min(near, -(V * corners[i]).z);
55 return texelSizeView / (2.f * tolerance * (1 << level) * std::max(1.0f, near));
61 const uint32_t mask = (1u << tile.level) - 1u;
62 return cache.getOrAllocCacheSlot(context, fetcher, glm::uvec3(uint32_t(tile.x) & mask,
63 uint32_t(tile.y) & mask,
69void Cogs::Core::TexAtlas::Geometry::calcTileCorners(glm::vec4* corners,
const LodTree::Tile& tile)
const
71 const float w = 1.f / float(1 << tile.level);
72 glm::vec2 u0 = w * glm::vec2(tile.x, tile.y);
73 glm::vec2 u1 = w * glm::vec2(tile.x + 1, tile.y + 1);
75 glm::vec2 d0 = glm::clamp(invDomainMapScale * (u0 + invDomainMapShift), glm::vec2(0.0), glm::vec2(1.0));
76 glm::vec2 d1 = glm::clamp(invDomainMapScale * (u1 + invDomainMapShift), glm::vec2(0.0), glm::vec2(1.0));
79 glm::vec2(d0.x, d0.y),
80 glm::vec2(d1.x, d0.y),
81 glm::vec2(d1.x, d1.y),
85 for (
size_t i = 0; i < 4; i++) {
86 const glm::vec2& u = U[i];
87 glm::vec2 p = (
coefficients[0] * (1.f - u.x) * (1.f - u.y) +
92 corners[i + 0] = glm::vec4(p, elevationMin, 1.f);
93 corners[i + 4] = glm::vec4(p, elevationMax, 1.f);
101 return a.error < b.error;
106void Cogs::Core::TexAtlas::LodTree::update(
Context* context,
const Geometry& geo,
Cache& cache,
Fetcher& fetcher,
const Layout& layout,
float tolerance,
bool restrictBetweenNearAndFar,
bool lodFreeze)
109 constexpr uint16_t TileHasData = 0x0000u;
110 constexpr uint16_t TileIsRefined = 0x4000u;
111 constexpr uint16_t TileHadDataAndIsDebugFlagged = 0x8000u;
112 constexpr uint16_t TileNotYetLoaded = 0xc000u;
114 (void)TileHadDataAndIsDebugFlagged;
118 const CameraData& camData = context->cameraSystem->getMainCameraData();
120 const glm::mat4 V = camData.viewMatrix;
122 const glm::mat4 PV = camData.rawViewProjection;
124 float baseLevelPixels = std::max(1u, fetcher.tileWidth) * glm::length(glm::vec2(geo.domain[1] - geo.domain[0]));
127 float texelSizeWorld = baseLevelExtent / baseLevelPixels;
128 float texelSizeView = glm::determinant(glm::mat3(V)) * texelSizeWorld;
131 glm::vec3 x_w = glm::normalize(glm::vec3(camData.inverseViewMatrix * glm::vec4(1.f, 0.f, 0.f, 0.f)));
144 encoded.resize(std::max(1u, layout.
size.x * layout.
size.y));
146 glm::vec4 corners[8];
149 for (uint32_t j = 0; j < layout.
size.y; j++) {
150 for (uint32_t i = 0; i < layout.
size.x; i++) {
154 .x = layout.
offset.x + int32_t(i),
155 .y = layout.
offset.y + int32_t(j),
156 .level =
static_cast<uint8_t
>(layout.
level),
157 .encodedIx =
static_cast<uint16_t
>(j * layout.
size.x + i),
163 tile.slotIx = getOrAllocCacheSlotWrap(context, cache, fetcher, tile);
164 if (tile.slotIx != NoSlotIx) {
165 encoded[tile.encodedIx] = tile.slotIx;
166 geo.calcTileCorners(corners, tile);
167 if (mightBeVisible(PV, V, corners, restrictBetweenNearAndFar)) {
168 tile.error = getScaledError(P, V, corners, texelSizeView, tolerance, tile.level);
169 if (1.f < tile.error) {
170 candidates.push_back(tile);
176 encoded[tile.encodedIx] = TileNotYetLoaded;
182 std::make_heap(candidates.begin(), candidates.end(), compareTile);
188 while (!candidates.empty()) {
191 std::pop_heap(candidates.begin(), candidates.end(), compareTile);
192 tiles.push_back(candidates.back());
193 candidates.pop_back();
196 const Tile& parentTile = tiles.back();
197 if (parentTile.level < layout.
maxLevel) {
199 bool anyValid =
false;
200 uint32_t firstSlot =
static_cast<uint32_t
>(encoded.size());
202 for (int32_t j = 0; j < 2; j++) {
203 for (int32_t i = 0; i < 2; i++) {
207 .x = 2 * parentTile.x + i,
208 .y = 2 * parentTile.y + j,
209 .level =
static_cast<uint8_t
>(parentTile.level + 1),
210 .encodedIx =
static_cast<uint16_t
>(encoded.size()),
214 geo.calcTileCorners(corners, childTile);
215 if (mightBeVisible(PV, V, corners, restrictBetweenNearAndFar)) {
216 childTile.error = getScaledError(P, V, corners, texelSizeView, tolerance, childTile.level);
217 if (1.f < childTile.error) {
218 childTile.slotIx = getOrAllocCacheSlotWrap(context, cache, fetcher, childTile);
219 if (childTile.slotIx != NoSlotIx) {
221 candidates.push_back(childTile);
222 std::push_heap(candidates.begin(), candidates.end(), compareTile);
229 if (childTile.slotIx != NoSlotIx) {
230 encoded.push_back(childTile.slotIx + TileHasData);
234 encoded.push_back(TileNotYetLoaded + parentTile.slotIx);
242 encoded[parentTile.encodedIx] = TileIsRefined +
static_cast<uint16_t
>(firstSlot);
246 encoded.resize(firstSlot);
254 if (encoded.empty()) {
255 encoded.push_back(0xc000u);
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Log implementation class.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Contains data describing a Camera instance and its derived data structured such as matrix data and vi...
glm::mat4 rawProjectionMatrix
Projection matrix that has not been adjusted by the renderer, and is thus appropriate for direct scre...
glm::vec2 coefficients[4]
Coefficients wrt engine origin.
uint32_t level
Base level.
uint32_t maxLevel
Maximum level.
glm::uvec2 size
Size of grid.
glm::ivec2 offset
Indices of the grid cell with smallest indices.