Skip to content

Commit

Permalink
Merge pull request #15 from sensat/fix-multiple-lods-with-replace-til…
Browse files Browse the repository at this point in the history
…eset
  • Loading branch information
Kaapp authored Sep 5, 2024
2 parents d7e1179 + cb4097d commit f38f5d6
Showing 1 changed file with 58 additions and 58 deletions.
116 changes: 58 additions & 58 deletions modules/tiles/src/tileset/grouped-tiles.array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,73 +23,73 @@ export class GroupedTilesArray {
* the operation.
*/
addTilesOrGroups(other: GroupedTilesArray, maxSize: number = 0) {
const totalItems = this.array.length + other.array.length;

if (maxSize <= 0 || totalItems <= maxSize) {
// unlimited, or enough space to append all elements
this.array = this.array.concat(other.array);
} else {
// add as many items as possible by display priority, up to the maximum size
const replacedTileIds = new Set<string>();
let itemsToAdd = maxSize - this.array.length;

// shallow copy of other array to not modify other group
const otherArray = other.array.slice();

// ensure array is sorted DESCENDING by priority
otherArray.sort((a, b) => b._displayPriority - a._displayPriority);

while (itemsToAdd > 0 && otherArray.length > 0) {
// popping off end means iterating the list ASCENDING in priority
const nextItem = otherArray.pop()!; // safe assertion as we just checked the length

const nextItemReplacedIds =
nextItem instanceof Tile3D
? [nextItem._replacedTileId]
: nextItem.tiles.map((tile) => tile._replacedTileId);

const tilesInItem = nextItem instanceof Tile3D ? 1 : nextItem.tiles.length;
if (tilesInItem > itemsToAdd) {
// can't add the next item as it'd make the list too long
break;
}
if (maxSize <= 0) {
// unlimited, so we can ignore this condition. however, it's
// not safe to just append the two lists as they may have REPLACE
// strategies, so we could end up selecting both a parent and child.
maxSize = Number.MAX_SAFE_INTEGER;
}

// add the item
this.array.push(nextItem);
itemsToAdd -= tilesInItem;
// add as many items as possible by display priority, up to the maximum size
const replacedTileIds = new Set<string>();
let itemsToAdd = maxSize - this.array.length;

// update replaced tile Ids (and increase the count if needed)
for (let i = 0; i < nextItemReplacedIds.length; i++) {
const replacedTileId = nextItemReplacedIds[i];
// shallow copy of other array to not modify other group
const otherArray = other.array.slice();

if (replacedTileId !== undefined && !replacedTileIds.has(replacedTileId)) {
// we're replacing a new item, so we need to add an extra item
itemsToAdd++;
replacedTileIds.add(replacedTileId);
}
// ensure array is sorted DESCENDING by priority
otherArray.sort((a, b) => b._displayPriority - a._displayPriority);

while (itemsToAdd > 0 && otherArray.length > 0) {
// popping off end means iterating the list ASCENDING in priority
const nextItem = otherArray.pop()!; // safe assertion as we just checked the length

const nextItemReplacedIds =
nextItem instanceof Tile3D
? [nextItem._replacedTileId]
: nextItem.tiles.map((tile) => tile._replacedTileId);

const tilesInItem = nextItem instanceof Tile3D ? 1 : nextItem.tiles.length;
if (tilesInItem > itemsToAdd) {
// can't add the next item as it'd make the list too long
break;
}

// add the item
this.array.push(nextItem);
itemsToAdd -= tilesInItem;

// update replaced tile Ids (and increase the count if needed)
for (let i = 0; i < nextItemReplacedIds.length; i++) {
const replacedTileId = nextItemReplacedIds[i];

if (replacedTileId !== undefined && !replacedTileIds.has(replacedTileId)) {
// we're replacing a new item, so we need to add an extra item
itemsToAdd++;
replacedTileIds.add(replacedTileId);
}
}
}

// splice out any replaced tiles
this.array = this.array
.map((tileOrGroup) => {
if (tileOrGroup instanceof TileGroup3D) {
const filteredGroup = new TileGroup3D();

for (let i = 0; i < tileOrGroup.tiles.length; i++) {
const tile = tileOrGroup.tiles[i];
if (!replacedTileIds.has(tile.id)) {
filteredGroup.addTile(tile);
}
}
// splice out any replaced tiles
this.array = this.array
.map((tileOrGroup) => {
if (tileOrGroup instanceof TileGroup3D) {
const filteredGroup = new TileGroup3D();

return filteredGroup.tiles.length > 0 ? filteredGroup : null;
for (let i = 0; i < tileOrGroup.tiles.length; i++) {
const tile = tileOrGroup.tiles[i];
if (!replacedTileIds.has(tile.id)) {
filteredGroup.addTile(tile);
}
}

return !replacedTileIds.has(tileOrGroup.id) ? tileOrGroup : null;
})
.filter((item): item is Tile3D | TileGroup3D => item !== null);
}
return filteredGroup.tiles.length > 0 ? filteredGroup : null;
}

return !replacedTileIds.has(tileOrGroup.id) ? tileOrGroup : null;
})
.filter((item): item is Tile3D | TileGroup3D => item !== null);
}

numTiles() {
Expand Down

0 comments on commit f38f5d6

Please sign in to comment.