181 lines
5.5 KiB
C++
Executable File
181 lines
5.5 KiB
C++
Executable File
// ----------------------------------------------------------------------------
|
|
// - Open3D: www.open3d.org -
|
|
// ----------------------------------------------------------------------------
|
|
// Copyright (c) 2018-2023 www.open3d.org
|
|
// SPDX-License-Identifier: MIT
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#pragma once
|
|
|
|
#include <fmt/format.h>
|
|
|
|
#include <array>
|
|
#include <cstdint>
|
|
#include <functional>
|
|
#include <type_traits>
|
|
|
|
namespace open3d {
|
|
|
|
namespace visualization {
|
|
namespace rendering {
|
|
|
|
// If you add entry here, don't forget to update TypeToString!
|
|
enum class EntityType : std::uint16_t {
|
|
None = 0,
|
|
|
|
View,
|
|
Scene,
|
|
|
|
Geometry,
|
|
Light,
|
|
IndirectLight,
|
|
Skybox,
|
|
Camera,
|
|
Material,
|
|
MaterialInstance,
|
|
Texture,
|
|
RenderTarget,
|
|
|
|
VertexBuffer,
|
|
IndexBuffer,
|
|
|
|
Count
|
|
};
|
|
|
|
// RenderEntityHandle - handle type for entities inside Renderer
|
|
// Can be used in STL containers as key
|
|
struct REHandle_abstract {
|
|
static const char* TypeToString(EntityType type);
|
|
|
|
static const std::uint16_t kBadId = 0;
|
|
const EntityType type = EntityType::None;
|
|
|
|
inline size_t Hash() const {
|
|
return static_cast<std::uint16_t>(type) << 16 | id;
|
|
}
|
|
|
|
bool operator==(const REHandle_abstract& other) const {
|
|
return id == other.id && type == other.type;
|
|
}
|
|
|
|
bool operator!=(const REHandle_abstract& other) const {
|
|
return !operator==(other);
|
|
}
|
|
|
|
bool operator<(const REHandle_abstract& other) const {
|
|
return Hash() < other.Hash();
|
|
}
|
|
|
|
explicit operator bool() const { return id != kBadId; }
|
|
|
|
REHandle_abstract() : type(EntityType::None), id(kBadId) {}
|
|
|
|
std::uint16_t GetId() const { return id; }
|
|
|
|
protected:
|
|
REHandle_abstract(const EntityType aType, const std::uint16_t aId)
|
|
: type(aType), id(aId) {}
|
|
|
|
static std::array<std::uint16_t, static_cast<size_t>(EntityType::Count)>
|
|
uid_table;
|
|
|
|
std::uint16_t id = kBadId;
|
|
};
|
|
|
|
std::ostream& operator<<(std::ostream& os, const REHandle_abstract& uid);
|
|
|
|
// REHandle is used for specification of handle types to prevent
|
|
// errors with passing, assigning or comparison of different kinds of handles
|
|
template <EntityType entityType>
|
|
struct REHandle : public REHandle_abstract {
|
|
static const REHandle kBad;
|
|
|
|
static REHandle Next() {
|
|
const auto index = static_cast<std::uint16_t>(entityType);
|
|
auto id = ++uid_table[index];
|
|
if (id == REHandle_abstract::kBadId) {
|
|
uid_table[index] = REHandle_abstract::kBadId + 1;
|
|
id = REHandle_abstract::kBadId + 1;
|
|
}
|
|
|
|
return std::move(REHandle(id));
|
|
}
|
|
|
|
static REHandle Concretize(const REHandle_abstract& abstract) {
|
|
if (abstract.type != entityType) {
|
|
// assert("Incompatible render uid types!\n");
|
|
return REHandle();
|
|
}
|
|
|
|
return REHandle(abstract.GetId());
|
|
}
|
|
|
|
REHandle() : REHandle_abstract(entityType, REHandle_abstract::kBadId) {}
|
|
REHandle(const REHandle& other) : REHandle_abstract(entityType, other.id) {}
|
|
// Don't use this constructor unless you know what you are doing
|
|
explicit REHandle(std::uint16_t id) : REHandle_abstract(entityType, id) {}
|
|
|
|
REHandle& operator=(const REHandle& other) {
|
|
id = other.id;
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
template <EntityType entityType>
|
|
const REHandle<entityType> REHandle<entityType>::kBad;
|
|
|
|
typedef REHandle<EntityType::View> ViewHandle;
|
|
typedef REHandle<EntityType::Scene> SceneHandle;
|
|
typedef REHandle<EntityType::Geometry> GeometryHandle;
|
|
typedef REHandle<EntityType::Light> LightHandle;
|
|
typedef REHandle<EntityType::IndirectLight> IndirectLightHandle;
|
|
typedef REHandle<EntityType::Skybox> SkyboxHandle;
|
|
typedef REHandle<EntityType::Camera> CameraHandle;
|
|
typedef REHandle<EntityType::Material> MaterialHandle;
|
|
typedef REHandle<EntityType::MaterialInstance> MaterialInstanceHandle;
|
|
typedef REHandle<EntityType::Texture> TextureHandle;
|
|
typedef REHandle<EntityType::RenderTarget> RenderTargetHandle;
|
|
typedef REHandle<EntityType::VertexBuffer> VertexBufferHandle;
|
|
typedef REHandle<EntityType::IndexBuffer> IndexBufferHandle;
|
|
|
|
} // namespace rendering
|
|
} // namespace visualization
|
|
} // namespace open3d
|
|
|
|
/// @cond
|
|
namespace std {
|
|
template <>
|
|
class hash<open3d::visualization::rendering::REHandle_abstract> {
|
|
public:
|
|
size_t operator()(const open3d::visualization::rendering::REHandle_abstract&
|
|
uid) const {
|
|
return uid.Hash();
|
|
}
|
|
};
|
|
} // namespace std
|
|
|
|
namespace fmt {
|
|
template <typename T>
|
|
struct formatter<
|
|
T,
|
|
std::enable_if_t<std::is_base_of<open3d::visualization::rendering::
|
|
REHandle_abstract,
|
|
T>::value,
|
|
char>> {
|
|
template <typename FormatContext>
|
|
auto format(const open3d::visualization::rendering::REHandle_abstract& uid,
|
|
FormatContext& ctx) -> decltype(ctx.out()) {
|
|
return format_to(ctx.out(), "[{}, {}, hash: {}]",
|
|
open3d::visualization::rendering::REHandle_abstract::
|
|
TypeToString(uid.type),
|
|
uid.GetId(), uid.Hash());
|
|
}
|
|
|
|
template <typename ParseContext>
|
|
constexpr auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
|
return ctx.begin();
|
|
}
|
|
};
|
|
} // namespace fmt
|
|
/// @endcond
|