169 lines
4.6 KiB
C
169 lines
4.6 KiB
C
|
|
#pragma once
|
||
|
|
|
||
|
|
#include "Library.h"
|
||
|
|
|
||
|
|
#include <cstdint>
|
||
|
|
|
||
|
|
namespace Cesium3DTilesSelection {
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief A description of the state of a {@link Tile} during the rendering
|
||
|
|
* process
|
||
|
|
*
|
||
|
|
* Instances of this class combine a frame number and a
|
||
|
|
* {@link TileSelectionState::Result} that describes the actual state of the
|
||
|
|
* tile.
|
||
|
|
* Instances of this class are stored in a {@link Tile}, and are used to track
|
||
|
|
* the state of the tile during the rendering process. The {@link Tileset}
|
||
|
|
* updates this state while traversing the tile hierarchy, tracking whether a
|
||
|
|
* tile was rendered, culled, or refined in the last frame.
|
||
|
|
*/
|
||
|
|
class TileSelectionState final {
|
||
|
|
public:
|
||
|
|
/**
|
||
|
|
* @brief Enumeration of possible results of a {@link TileSelectionState}
|
||
|
|
*/
|
||
|
|
enum class CESIUM3DTILESSELECTION_API Result {
|
||
|
|
/**
|
||
|
|
* @brief There was no selection result.
|
||
|
|
*
|
||
|
|
* This may be the case when the tile wasn't visited last frame.
|
||
|
|
*/
|
||
|
|
None = 0,
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief This tile was deemed not visible and culled.
|
||
|
|
*/
|
||
|
|
Culled = 1,
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief The tile was selected for rendering.
|
||
|
|
*/
|
||
|
|
Rendered = 2,
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief This tile did not meet the required screen-space error and was
|
||
|
|
* refined.
|
||
|
|
*/
|
||
|
|
Refined = 3,
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief This tile was rendered but then removed from the render list
|
||
|
|
*
|
||
|
|
* This tile was originally rendered, but it got kicked out of the render
|
||
|
|
* list in favor of an ancestor because it is not yet renderable.
|
||
|
|
*/
|
||
|
|
RenderedAndKicked = 4,
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief This tile was refined but then removed from the render list
|
||
|
|
*
|
||
|
|
* This tile was originally refined, but its rendered descendants got kicked
|
||
|
|
* out of the render list in favor of an ancestor because it is not yet
|
||
|
|
* renderable.
|
||
|
|
*/
|
||
|
|
RefinedAndKicked = 5
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief Initializes a new instance with
|
||
|
|
* {@link TileSelectionState::Result::None}
|
||
|
|
*/
|
||
|
|
constexpr TileSelectionState() noexcept
|
||
|
|
: _frameNumber(0), _result(Result::None) {}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief Initializes a new instance with a given
|
||
|
|
* {@link TileSelectionState::Result}.
|
||
|
|
*
|
||
|
|
* @param frameNumber The frame number in which the selection took place.
|
||
|
|
* @param result The result of the selection.
|
||
|
|
*/
|
||
|
|
constexpr TileSelectionState(int32_t frameNumber, Result result) noexcept
|
||
|
|
: _frameNumber(frameNumber), _result(result) {}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief Gets the frame number in which selection took place.
|
||
|
|
*/
|
||
|
|
constexpr int32_t getFrameNumber() const noexcept {
|
||
|
|
return this->_frameNumber;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief Gets the result of selection.
|
||
|
|
*
|
||
|
|
* The given frame number must match the frame number in which selection last
|
||
|
|
* took place. Otherwise, {@link TileSelectionState::Result::None} is
|
||
|
|
* returned.
|
||
|
|
*
|
||
|
|
* @param frameNumber The previous frame number.
|
||
|
|
* @return The {@link TileSelectionState::Result}
|
||
|
|
*/
|
||
|
|
constexpr Result getResult(int32_t frameNumber) const noexcept {
|
||
|
|
if (this->_frameNumber != frameNumber) {
|
||
|
|
return Result::None;
|
||
|
|
}
|
||
|
|
return this->_result;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief Determines if this tile or its descendents were kicked from the
|
||
|
|
* render list.
|
||
|
|
*
|
||
|
|
* In other words, if its last selection result was
|
||
|
|
* {@link TileSelectionState::Result::RenderedAndKicked} or
|
||
|
|
* {@link TileSelectionState::Result::RefinedAndKicked}.
|
||
|
|
*
|
||
|
|
* @param frameNumber The previous frame number.
|
||
|
|
* @return `true` if the tile was kicked, and `false` otherwise
|
||
|
|
*/
|
||
|
|
constexpr bool wasKicked(int32_t frameNumber) const noexcept {
|
||
|
|
const Result result = this->getResult(frameNumber);
|
||
|
|
return result == Result::RenderedAndKicked ||
|
||
|
|
result == Result::RefinedAndKicked;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief Gets the original selection result prior to being kicked.
|
||
|
|
*
|
||
|
|
* If the tile wasn't kicked, the original value is returned.
|
||
|
|
*
|
||
|
|
* @param frameNumber The previous frame number.
|
||
|
|
* @return The {@link TileSelectionState::Result} prior to being kicked.
|
||
|
|
*/
|
||
|
|
constexpr Result getOriginalResult(int32_t frameNumber) const noexcept {
|
||
|
|
const Result result = this->getResult(frameNumber);
|
||
|
|
|
||
|
|
switch (result) {
|
||
|
|
case Result::RefinedAndKicked:
|
||
|
|
return Result::Refined;
|
||
|
|
case Result::RenderedAndKicked:
|
||
|
|
return Result::Rendered;
|
||
|
|
default:
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief Marks this tile as "kicked".
|
||
|
|
*/
|
||
|
|
constexpr void kick() noexcept {
|
||
|
|
switch (this->_result) {
|
||
|
|
case Result::Rendered:
|
||
|
|
this->_result = Result::RenderedAndKicked;
|
||
|
|
break;
|
||
|
|
case Result::Refined:
|
||
|
|
this->_result = Result::RefinedAndKicked;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private:
|
||
|
|
int32_t _frameNumber;
|
||
|
|
Result _result;
|
||
|
|
};
|
||
|
|
|
||
|
|
} // namespace Cesium3DTilesSelection
|