Cogs.Core
ClipmapUpdate.cpp
1#include "ClipmapUpdate.h"
2#include <algorithm>
3Cogs::ClipmapUpdate::ClipmapUpdate(ClipmapLevel * level, int west, int south, int east, int north)
4 : level(level)
5{
6 extent = Extent{ west, south, east, north };
7}
8
9int Cogs::ClipmapUpdate::getWidth() const
10{
11 return (extent.east - extent.west + 1);
12}
13
14int Cogs::ClipmapUpdate::getHeight() const
15{
16 return (extent.north - extent.south + 1);
17}
18
19Cogs::ClipmapUpdate Cogs::ClipmapUpdate::addBufferWithinLevelNextExtent() const
20{
21 ClipmapUpdate update(
22 level,
23 std::max<int>(extent.west - 1, level->nextExtent.west),
24 std::max<int>(extent.south - 1, level->nextExtent.south),
25 std::min<int>(extent.east + 1, level->nextExtent.east),
26 std::min<int>(extent.north + 1, level->nextExtent.north)
27 );
28
29 return update;
30}
31
32void Cogs::ClipmapUpdate::splitUpdateToAvoidWrapping(const ClipmapUpdate & update, std::vector<ClipmapUpdate> & results)
33{
34 ClipmapLevel * level = update.getLevel();
35 const TextureOrigin & origin = level->origin;
36 const Extent & extent = level->nextExtent;
37
38 const int clipmapSizeX = extent.getWidth();
39 const int clipmapSizeY = extent.getHeight();
40
41 const int west = (origin.x + (update.getWest() - extent.west)) % clipmapSizeX;
42 const int east = (origin.x + (update.getEast() - extent.west)) % clipmapSizeX;
43 const int south = (origin.y + (update.getSouth() - extent.south)) % clipmapSizeY;
44 const int north = (origin.y + (update.getNorth() - extent.south)) % clipmapSizeY;
45
46 if (east < west && north < south) {
47 // Horizontal AND vertical wrap
48 ClipmapUpdate bottomLeftUpdate(
49 level,
50 update.getWest(),
51 update.getSouth(),
52 extent.west + (clipmapSizeX - origin[0] - 1),
53 extent.south + (clipmapSizeY - origin[1] - 1));
54
55 ClipmapUpdate bottomRightUpdate(
56 level,
57 extent.west + clipmapSizeX - origin[0],
58 update.getSouth(),
59 update.getEast(),
60 extent.south + (clipmapSizeY - origin[1] - 1));
61
62 ClipmapUpdate topLeftUpdate(
63 level,
64 update.getWest(),
65 extent.south + clipmapSizeY - origin[1],
66 extent.west + (clipmapSizeX - origin[0] - 1),
67 update.getNorth());
68
69 ClipmapUpdate topRightUpdate(
70 level,
71 extent.west + clipmapSizeX - origin[0],
72 extent.south + clipmapSizeY - origin[1],
73 update.getEast(),
74 update.getNorth());
75
76 results.push_back(bottomLeftUpdate);
77 results.push_back(bottomRightUpdate);
78 results.push_back(topLeftUpdate);
79 results.push_back(topRightUpdate);
80 } else if (east < west) {
81 // Horizontal wrap
82 ClipmapUpdate leftUpdate(
83 level,
84 update.getWest(),
85 update.getSouth(),
86 extent.west + (clipmapSizeX - origin[0] - 1),
87 update.getNorth());
88
89 ClipmapUpdate rightUpdate(
90 level,
91 extent.west + clipmapSizeX - origin[0],
92 update.getSouth(),
93 update.getEast(),
94 update.getNorth());
95
96 results.push_back(leftUpdate);
97 results.push_back(rightUpdate);
98 } else if (north < south) {
99 // Vertical wrap
100 ClipmapUpdate bottomUpdate(
101 level,
102 update.getWest(),
103 update.getSouth(),
104 update.getEast(),
105 extent.south + (clipmapSizeY - origin[1] - 1));
106
107 ClipmapUpdate topUpdate(
108 level,
109 update.getWest(),
110 extent.south + clipmapSizeY - origin[1],
111 update.getEast(),
112 update.getNorth());
113
114 results.push_back(bottomUpdate);
115 results.push_back(topUpdate);
116 } else {
117 // No wrap
118 results.push_back(update);
119 }
120}
121
122Cogs::ClipmapUpdate Cogs::ClipmapUpdate::intersectUpdates(const ClipmapUpdate & first, const ClipmapUpdate & second)
123{
124 const int west = std::max(first.getWest(), second.getWest());
125 const int south = std::max(first.getSouth(), second.getSouth());
126 const int east = std::min(first.getEast(), second.getEast());
127 const int north = std::min(first.getNorth(), second.getNorth());
128
129 return ClipmapUpdate(first.getLevel(), west, south, east, north);
130}