-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathProxyCommand.h
More file actions
219 lines (195 loc) · 6.73 KB
/
Copy pathProxyCommand.h
File metadata and controls
219 lines (195 loc) · 6.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#pragma once
#include "PrimitiveRenderProxy.h"
#include "LightRenderProxy.h"
#include "UIRenderProxy.h"
#include <mathematics/bounds.hpp>
#include <mathematics/matrix4x4.hpp>
#include <mathematics/vector3.hpp>
#include <type_traits>
#include <variant>
class FoliageComponent;
class TerrainComponent;
class SpriteRenderer;
class ImageComponent;
class TextComponent;
class MeshRenderer;
class DecalComponent;
class SpriteSheetComponent;
class LightComponent;
class RenderScene;
// 게임 스레드가 캡처하고 렌더 스레드가 적용하는 RenderScene delta.
//
// std::function 안에 프록시 shared_ptr/weak_ptr를 숨겨 운반하지 않는다.
// payload는 컴포넌트에서 읽은 값만 소유하고, 대상 프록시는 소비 시점에
// RenderScene이 GUID로 해석한다. 따라서 생산자는 RenderScene 맵/락을
// 건드리지 않고, 소비자는 이미 파괴된 대상을 안전하게 drop할 수 있다.
class ProxyCommand
{
public:
enum class ApplyResult : uint8_t
{
Applied,
StaleEpoch,
MissingTarget,
};
struct PrimitiveCreate
{
std::shared_ptr<PrimitiveRenderProxy> proxy{};
};
struct LightCreate
{
std::shared_ptr<LightRenderProxy> proxy{};
};
struct UICreate
{
std::shared_ptr<UIRenderProxy> proxy{};
};
struct PrimitiveDestroy {};
struct LightDestroy {};
struct UIDestroy {};
struct MeshUpdate
{
math::matrix4x4 worldMatrix{ math::matrix4x4::identity() };
math::vector3 worldPosition{};
math::aabb worldBounds{};
std::shared_ptr<Material> material{};
std::shared_ptr<math::matrix4x4[]> bonePalette{};
HashedGuid animatorGuid{};
HashedGuid materialGuid{};
LightMapping lightMapping{};
uint32 bitflag{ 0 };
bool hasWorldBounds{ false };
bool isStatic{ false };
bool isEnabled{ false };
bool isShadowCast{ true };
bool isShadowReceive{ true };
bool enableLOD{ false };
bool updateLightMapping{ false };
bool hasAnimator{ false };
};
struct TerrainUpdate
{
math::matrix4x4 worldMatrix{ math::matrix4x4::identity() };
math::vector3 worldPosition{};
std::shared_ptr<TerrainMesh> terrainMesh{};
std::shared_ptr<TerrainMaterial> terrainMaterial{};
};
struct FoliageUpdate
{
math::matrix4x4 worldMatrix{ math::matrix4x4::identity() };
math::vector3 worldPosition{};
std::vector<FoliageType> foliageTypes{};
std::vector<FoliageInstance> foliageInstances{};
};
struct DecalUpdate
{
math::matrix4x4 worldMatrix{ math::matrix4x4::identity() };
std::shared_ptr<Texture> diffuse{};
std::shared_ptr<Texture> normal{};
std::shared_ptr<Texture> orm{};
uint32 sliceX{ 1 };
uint32 sliceY{ 1 };
int sliceNumber{ 0 };
};
struct SpriteUpdate
{
math::matrix4x4 worldMatrix{ math::matrix4x4::identity() };
math::vector3 worldPosition{};
std::shared_ptr<Texture> texture{};
math::vector3 billboardAxis{ 0.f, 1.f, 0.f };
BillboardType billboardType{ BillboardType::None };
bool isStatic{ false };
bool isEnabled{ false };
bool enableDepth{ false };
int orderInLayer{ 0 };
};
struct LightUpdate
{
LightRenderProxy::Values values{};
};
struct ImageUpdate
{
UIRenderProxy::ImageData data{};
bool isEnabled{ false };
};
struct TextUpdate
{
UIRenderProxy::TextData data{};
bool isEnabled{ false };
};
struct SpriteSheetUpdate
{
UIRenderProxy::SpriteSheetData data{};
bool isEnabled{ false };
bool isLoop{ false };
};
using Payload = std::variant<std::monostate,
PrimitiveCreate, LightCreate, UICreate,
PrimitiveDestroy, LightDestroy, UIDestroy,
MeshUpdate, TerrainUpdate, FoliageUpdate, DecalUpdate, SpriteUpdate,
LightUpdate, ImageUpdate, TextUpdate, SpriteSheetUpdate>;
ProxyCommand() = default;
~ProxyCommand() = default;
ProxyCommand(MeshRenderer* pComponent, uint64_t sceneEpoch);
ProxyCommand(LightComponent* pComponent, uint64_t sceneEpoch);
ProxyCommand(TerrainComponent* pComponent, uint64_t sceneEpoch);
ProxyCommand(FoliageComponent* pComponent, uint64_t sceneEpoch);
ProxyCommand(ImageComponent* pComponent, uint64_t sceneEpoch);
ProxyCommand(TextComponent* pComponent, uint64_t sceneEpoch);
ProxyCommand(DecalComponent* pComponent, uint64_t sceneEpoch);
ProxyCommand(SpriteSheetComponent* pComponent, uint64_t sceneEpoch);
ProxyCommand(SpriteRenderer* pComponent, uint64_t sceneEpoch);
ProxyCommand(const ProxyCommand&) = default;
ProxyCommand(ProxyCommand&&) noexcept = default;
ProxyCommand& operator=(const ProxyCommand&) = default;
ProxyCommand& operator=(ProxyCommand&&) noexcept = default;
public:
static ProxyCommand CreatePrimitive(
std::shared_ptr<PrimitiveRenderProxy> proxy, uint64_t sceneEpoch);
static ProxyCommand CreateLight(
std::shared_ptr<LightRenderProxy> proxy, uint64_t sceneEpoch);
static ProxyCommand CreateUI(
std::shared_ptr<UIRenderProxy> proxy, uint64_t sceneEpoch);
static ProxyCommand DestroyPrimitive(HashedGuid guid, uint64_t sceneEpoch);
static ProxyCommand DestroyLight(HashedGuid guid, uint64_t sceneEpoch);
static ProxyCommand DestroyUI(HashedGuid guid, uint64_t sceneEpoch);
bool IsValid() const noexcept
{
return !std::holds_alternative<std::monostate>(m_payload);
}
// 단 한 번 소비한다. 대상이 이미 해제되었거나 타입이 다르면 false로
// drop하고 payload를 비운다.
ApplyResult Apply(RenderScene& renderScene, uint64_t sceneEpoch);
uint64_t GetSceneEpoch() const noexcept { return m_sceneEpoch; }
// bounded RenderThread queue가 같은 프록시의 연속 update를 latest-wins로
// 접을 때 쓰는 값 정체성이다. create/destroy는 절대 접지 않는다.
bool IsUpdate() const noexcept
{
// variant 선언 순서에서 update payload의 첫 슬롯은 MeshUpdate(7)다.
return m_payload.index() >= 7u;
}
size_t GetProxyGuidValue() const noexcept { return m_proxyGUID.m_ID_Data; }
size_t GetPayloadKind() const noexcept { return m_payload.index(); }
private:
HashedGuid m_proxyGUID{};
uint64_t m_sceneEpoch{ 0 };
Payload m_payload{};
};
static_assert(std::is_same_v<decltype(ProxyCommand::MeshUpdate::worldMatrix),
math::matrix4x4>);
static_assert(std::is_same_v<decltype(ProxyCommand::MeshUpdate::worldPosition),
math::vector3>);
static_assert(std::is_same_v<decltype(ProxyCommand::MeshUpdate::worldBounds),
math::aabb>);
static_assert(std::is_same_v<decltype(ProxyCommand::MeshUpdate::bonePalette),
std::shared_ptr<math::matrix4x4[]>>);
static_assert(std::is_same_v<decltype(ProxyCommand::TerrainUpdate::worldMatrix),
math::matrix4x4>);
static_assert(std::is_same_v<decltype(ProxyCommand::FoliageUpdate::worldMatrix),
math::matrix4x4>);
static_assert(std::is_same_v<decltype(ProxyCommand::DecalUpdate::worldMatrix),
math::matrix4x4>);
static_assert(std::is_same_v<decltype(ProxyCommand::SpriteUpdate::worldMatrix),
math::matrix4x4>);
static_assert(std::is_same_v<decltype(ProxyCommand::SpriteUpdate::billboardAxis),
math::vector3>);