PixelBullet  0.0.1
A C++ game engine
Loading...
Searching...
No Matches
material_serialization.h
1#pragma once
2
3#include "pixelbullet/graphics/material_types.h"
4#include "pixelbullet/serialization/node.h"
5#include "pixelbullet/serialization/node_reader.h"
6
7#include <string>
8#include <utility>
9
10namespace pixelbullet
11{
12inline Node& operator<<(Node& node, const MaterialAlphaMode& value)
13{
14 node << std::string(ToString(value));
15 return node;
16}
17
18inline const Node& operator>>(const Node& node, MaterialAlphaMode& value)
19{
20 std::string serialized;
21 node >> serialized;
22 if (serialized == "Mask")
23 {
24 value = MaterialAlphaMode::Mask;
25 }
26 else if (serialized == "Blend")
27 {
28 value = MaterialAlphaMode::Blend;
29 }
30 else
31 {
32 value = MaterialAlphaMode::Opaque;
33 }
34 return node;
35}
36
37[[nodiscard]] inline bool TryReadNode(const Node& node, MaterialAlphaMode& value, serialization::NodeReader& reader)
38{
39 std::string serialized;
40 if (!serialization::TryReadNode(node, serialized, reader))
41 {
42 return false;
43 }
44 if (serialized == "Opaque")
45 {
46 value = MaterialAlphaMode::Opaque;
47 }
48 else if (serialized == "Mask")
49 {
50 value = MaterialAlphaMode::Mask;
51 }
52 else if (serialized == "Blend")
53 {
54 value = MaterialAlphaMode::Blend;
55 }
56 else
57 {
58 return reader.Fail("Unknown MaterialAlphaMode token '" + serialized + "'.");
59 }
60 return true;
61}
62
63inline Node& operator<<(Node& node, const MaterialTextureWrapMode& value)
64{
65 node << std::string(ToString(value));
66 return node;
67}
68
69inline const Node& operator>>(const Node& node, MaterialTextureWrapMode& value)
70{
71 std::string serialized;
72 node >> serialized;
73 if (serialized == "ClampToEdge")
74 {
75 value = MaterialTextureWrapMode::ClampToEdge;
76 }
77 else if (serialized == "MirroredRepeat")
78 {
79 value = MaterialTextureWrapMode::MirroredRepeat;
80 }
81 else
82 {
83 value = MaterialTextureWrapMode::Repeat;
84 }
85 return node;
86}
87
88[[nodiscard]] inline bool TryReadNode(const Node& node, MaterialTextureWrapMode& value, serialization::NodeReader& reader)
89{
90 std::string serialized;
91 if (!serialization::TryReadNode(node, serialized, reader))
92 {
93 return false;
94 }
95 if (serialized == "Repeat")
96 {
97 value = MaterialTextureWrapMode::Repeat;
98 }
99 else if (serialized == "ClampToEdge")
100 {
101 value = MaterialTextureWrapMode::ClampToEdge;
102 }
103 else if (serialized == "MirroredRepeat")
104 {
105 value = MaterialTextureWrapMode::MirroredRepeat;
106 }
107 else
108 {
109 return reader.Fail("Unknown MaterialTextureWrapMode token '" + serialized + "'.");
110 }
111 return true;
112}
113
114inline Node& operator<<(Node& node, const MaterialTextureMagFilter& value)
115{
116 node << std::string(ToString(value));
117 return node;
118}
119
120inline const Node& operator>>(const Node& node, MaterialTextureMagFilter& value)
121{
122 std::string serialized;
123 node >> serialized;
124 value = serialized == "Nearest" ? MaterialTextureMagFilter::Nearest : MaterialTextureMagFilter::Linear;
125 return node;
126}
127
128[[nodiscard]] inline bool TryReadNode(const Node& node, MaterialTextureMagFilter& value, serialization::NodeReader& reader)
129{
130 std::string serialized;
131 if (!serialization::TryReadNode(node, serialized, reader))
132 {
133 return false;
134 }
135 if (serialized == "Linear")
136 {
137 value = MaterialTextureMagFilter::Linear;
138 }
139 else if (serialized == "Nearest")
140 {
141 value = MaterialTextureMagFilter::Nearest;
142 }
143 else
144 {
145 return reader.Fail("Unknown MaterialTextureMagFilter token '" + serialized + "'.");
146 }
147 return true;
148}
149
150inline Node& operator<<(Node& node, const MaterialTextureMinFilter& value)
151{
152 node << std::string(ToString(value));
153 return node;
154}
155
156inline Node& operator<<(Node& node, const MaterialTextureUvSet& value)
157{
158 node << std::string(ToString(value));
159 return node;
160}
161
162inline const Node& operator>>(const Node& node, MaterialTextureMinFilter& value)
163{
164 std::string serialized;
165 node >> serialized;
166 if (serialized == "Linear")
167 {
168 value = MaterialTextureMinFilter::Linear;
169 }
170 else if (serialized == "Nearest")
171 {
172 value = MaterialTextureMinFilter::Nearest;
173 }
174 else if (serialized == "NearestMipmapNearest")
175 {
176 value = MaterialTextureMinFilter::NearestMipmapNearest;
177 }
178 else if (serialized == "LinearMipmapNearest")
179 {
180 value = MaterialTextureMinFilter::LinearMipmapNearest;
181 }
182 else if (serialized == "NearestMipmapLinear")
183 {
184 value = MaterialTextureMinFilter::NearestMipmapLinear;
185 }
186 else
187 {
188 value = MaterialTextureMinFilter::LinearMipmapLinear;
189 }
190 return node;
191}
192
193[[nodiscard]] inline bool TryReadNode(const Node& node, MaterialTextureMinFilter& value, serialization::NodeReader& reader)
194{
195 std::string serialized;
196 if (!serialization::TryReadNode(node, serialized, reader))
197 {
198 return false;
199 }
200 if (serialized == "Linear")
201 {
202 value = MaterialTextureMinFilter::Linear;
203 }
204 else if (serialized == "Nearest")
205 {
206 value = MaterialTextureMinFilter::Nearest;
207 }
208 else if (serialized == "NearestMipmapNearest")
209 {
210 value = MaterialTextureMinFilter::NearestMipmapNearest;
211 }
212 else if (serialized == "LinearMipmapNearest")
213 {
214 value = MaterialTextureMinFilter::LinearMipmapNearest;
215 }
216 else if (serialized == "NearestMipmapLinear")
217 {
218 value = MaterialTextureMinFilter::NearestMipmapLinear;
219 }
220 else if (serialized == "LinearMipmapLinear")
221 {
222 value = MaterialTextureMinFilter::LinearMipmapLinear;
223 }
224 else
225 {
226 return reader.Fail("Unknown MaterialTextureMinFilter token '" + serialized + "'.");
227 }
228 return true;
229}
230
231inline const Node& operator>>(const Node& node, MaterialTextureUvSet& value)
232{
233 std::string serialized;
234 node >> serialized;
235 value = serialized == "Uv1" ? MaterialTextureUvSet::Uv1 : MaterialTextureUvSet::Uv0;
236 return node;
237}
238
239[[nodiscard]] inline bool TryReadNode(const Node& node, MaterialTextureUvSet& value, serialization::NodeReader& reader)
240{
241 std::string serialized;
242 if (!serialization::TryReadNode(node, serialized, reader))
243 {
244 return false;
245 }
246 if (serialized == "Uv0")
247 {
248 value = MaterialTextureUvSet::Uv0;
249 }
250 else if (serialized == "Uv1")
251 {
252 value = MaterialTextureUvSet::Uv1;
253 }
254 else
255 {
256 return reader.Fail("Unknown MaterialTextureUvSet token '" + serialized + "'.");
257 }
258 return true;
259}
260
261inline Node& operator<<(Node& node, const MaterialShadingModel& value)
262{
263 node << std::string(ToString(value));
264 return node;
265}
266
267inline const Node& operator>>(const Node& node, MaterialShadingModel& value)
268{
269 std::string serialized;
270 node >> serialized;
271 value = serialized == "Unlit" ? MaterialShadingModel::Unlit : MaterialShadingModel::Lit;
272 return node;
273}
274
275[[nodiscard]] inline bool TryReadNode(const Node& node, MaterialShadingModel& value, serialization::NodeReader& reader)
276{
277 std::string serialized;
278 if (!serialization::TryReadNode(node, serialized, reader))
279 {
280 return false;
281 }
282 if (serialized == "Lit")
283 {
284 value = MaterialShadingModel::Lit;
285 }
286 else if (serialized == "Unlit")
287 {
288 value = MaterialShadingModel::Unlit;
289 }
290 else
291 {
292 return reader.Fail("Unknown MaterialShadingModel token '" + serialized + "'.");
293 }
294 return true;
295}
296
297inline Node& operator<<(Node& node, const MaterialTextureSamplerSettings& sampler)
298{
299 node["wrapU"] << sampler.wrap_u;
300 node["wrapV"] << sampler.wrap_v;
301 node["magFilter"] << sampler.mag_filter;
302 node["minFilter"] << sampler.min_filter;
303 return node;
304}
305
306inline const Node& operator>>(const Node& node, MaterialTextureSamplerSettings& sampler)
307{
308 if (node.has_property("wrapU"))
309 {
310 node["wrapU"] >> sampler.wrap_u;
311 }
312 if (node.has_property("wrapV"))
313 {
314 node["wrapV"] >> sampler.wrap_v;
315 }
316 if (node.has_property("magFilter"))
317 {
318 node["magFilter"] >> sampler.mag_filter;
319 }
320 if (node.has_property("minFilter"))
321 {
322 node["minFilter"] >> sampler.min_filter;
323 }
324 return node;
325}
326
327[[nodiscard]] inline bool TryReadNode(const Node& node, MaterialTextureSamplerSettings& sampler, serialization::NodeReader& reader)
328{
329 bool ok = true;
330 ok &= serialization::TryReadOptionalProperty(node, "wrapU", sampler.wrap_u, reader);
331 ok &= serialization::TryReadOptionalProperty(node, "wrapV", sampler.wrap_v, reader);
332 ok &= serialization::TryReadOptionalProperty(node, "magFilter", sampler.mag_filter, reader);
333 ok &= serialization::TryReadOptionalProperty(node, "minFilter", sampler.min_filter, reader);
334 return ok;
335}
336
337inline Node& operator<<(Node& node, const MaterialTextureTransform& transform)
338{
339 Node offset_node;
340 offset_node.set_type(NodeType::Array);
341 auto& offset_properties = offset_node.properties();
342 offset_properties.clear();
343 for (int index = 0; index < 2; ++index)
344 {
345 Node component_node;
346 component_node << transform.offset[index];
347 offset_properties.emplace_back("", std::move(component_node));
348 }
349 node["offset"] = std::move(offset_node);
350
351 Node scale_node;
352 scale_node.set_type(NodeType::Array);
353 auto& scale_properties = scale_node.properties();
354 scale_properties.clear();
355 for (int index = 0; index < 2; ++index)
356 {
357 Node component_node;
358 component_node << transform.scale[index];
359 scale_properties.emplace_back("", std::move(component_node));
360 }
361 node["scale"] = std::move(scale_node);
362 node["rotationDegrees"] << transform.rotation_degrees;
363 return node;
364}
365
366inline const Node& operator>>(const Node& node, MaterialTextureTransform& transform)
367{
368 if (node.has_property("offset"))
369 {
370 const Node& offset_node = node["offset"];
371 ASSERT(offset_node.type() == NodeType::Array, "material texture transform offset must be an array");
372 const auto& offset_properties = offset_node.properties();
373 ASSERT(offset_properties.size() >= 2, "material texture transform offset requires two components");
374 for (int index = 0; index < 2; ++index)
375 {
376 offset_properties[index].second >> transform.offset[index];
377 }
378 }
379
380 if (node.has_property("scale"))
381 {
382 const Node& scale_node = node["scale"];
383 ASSERT(scale_node.type() == NodeType::Array, "material texture transform scale must be an array");
384 const auto& scale_properties = scale_node.properties();
385 ASSERT(scale_properties.size() >= 2, "material texture transform scale requires two components");
386 for (int index = 0; index < 2; ++index)
387 {
388 scale_properties[index].second >> transform.scale[index];
389 }
390 }
391
392 if (node.has_property("rotationDegrees"))
393 {
394 node["rotationDegrees"] >> transform.rotation_degrees;
395 }
396
397 return node;
398}
399
400[[nodiscard]] inline bool TryReadNode(const Node& node, MaterialTextureTransform& transform, serialization::NodeReader& reader)
401{
402 bool ok = true;
403 ok &= serialization::TryReadOptionalProperty(node, "offset", transform.offset, reader);
404 ok &= serialization::TryReadOptionalProperty(node, "scale", transform.scale, reader);
405 ok &= serialization::TryReadOptionalProperty(node, "rotationDegrees", transform.rotation_degrees, reader);
406 return ok;
407}
408} // namespace pixelbullet
#define ASSERT(condition,...)
Asserts that a condition is true.
Definition assert.h:142
Represents a hierarchical node capable of storing various data types and supporting YAML serializatio...
Definition node.h:49
Definition node_reader.h:48
Definition material_types.h:136
Definition material_types.h:146