载入中...
搜索中...
未找到
CanonicalVolumeTextureCook.cpp
浏览该文件的文档.
2
3#include "common/Value.h"
4
5#include <limits>
6
7namespace eve::asset {
8namespace {
9const Value* field(const Value::Object& object, const char* name) {
10 const auto found = object.find(name);
11 return found == object.end() ? nullptr : &found->second;
12}
13bool exactString(const Value::Object& object, const char* name, const char* expected) {
14 const auto* value = field(object, name);
15 return value && value->isString() && value->asString() == expected;
16}
17bool positive32(const Value::Object& object, const char* name, uint32_t& output) {
18 const auto* value = field(object, name);
19 if (!value || !value->isInt64() || value->asInt() <= 0 || uint64_t(value->asInt()) > UINT32_MAX) return false;
20 output = uint32_t(value->asInt());
21 return true;
22}
23void put32(std::vector<uint8_t>& bytes, uint32_t value) {
24 for (unsigned shift = 0; shift < 32; shift += 8) bytes.push_back(uint8_t(value >> shift));
25}
26} // namespace
27
29 std::span<const uint8_t> sourceR8,
30 uint64_t maximumDecodedBytes) {
31 auto decoded =
32 Value::fromJson(std::string_view(reinterpret_cast<const char*>(definition.data()), definition.size()));
33 if (!decoded) return Result<CookedCanonicalVolumeTexture>::failure(decoded.status());
34 const auto* object = decoded.value().getIf<Value::Object>();
35 uint32_t width = 0, height = 0, depth = 0;
36 const auto* blob = object ? field(*object, "blob") : nullptr;
37 if (!object || object->size() != 8 || !exactString(*object, "schema", "eve.volume-texture") ||
38 !exactString(*object, "encoding", "r8") || !exactString(*object, "usage", "noise") || !blob ||
39 !blob->isString() || !blob->asString().ends_with("/source.r8") || !positive32(*object, "width", width) ||
40 !positive32(*object, "height", height) || !positive32(*object, "depth", depth))
42 Diagnostic::error(DiagnosticCode::ParseError, "volume definition shape or members are invalid", {}, {},
43 "asset.cook.volume-texture"));
44 const auto* version = field(*object, "schemaVersion");
45 if (!version || !version->isInt64() || version->asInt() != 1 ||
46 uint64_t(width) > std::numeric_limits<uint64_t>::max() / height ||
47 uint64_t(width) * height > std::numeric_limits<uint64_t>::max() / depth)
49 DiagnosticCode::InvalidArgument, "volume dimensions, version, source bytes or budget are invalid", {}, {},
50 "asset.cook.volume-texture"));
51 const uint64_t voxels = uint64_t(width) * height * depth;
52 if (voxels > SIZE_MAX || voxels != sourceR8.size() || maximumDecodedBytes < 24 ||
53 voxels > (maximumDecodedBytes - 24) / 4)
55 DiagnosticCode::InvalidArgument, "volume dimensions, version, source bytes or budget are invalid", {}, {},
56 "asset.cook.volume-texture"));
57
58 auto runtime = *object;
59 runtime["encoding"] = Value("rgba8");
60 runtime["blob"] = Value("chunk:1");
61 auto encoded = Value(std::move(runtime)).toJson();
62 if (!encoded) return Result<CookedCanonicalVolumeTexture>::failure(encoded.status());
64 result.definition.assign(encoded.value().begin(), encoded.value().end());
65 result.bulk.insert(result.bulk.end(), {'E', 'V', 'V', 'O', 'L', 0, 1, 0});
66 put32(result.bulk, width);
67 put32(result.bulk, height);
68 put32(result.bulk, depth);
69 put32(result.bulk, 0);
70 result.bulk.reserve(24 + size_t(voxels) * 4);
71 for (uint8_t value : sourceR8) result.bulk.insert(result.bulk.end(), {value, value, value, 255});
72 return Result<CookedCanonicalVolumeTexture>::success(std::move(result));
73}
74
75} // namespace eve::asset
double value
std::string output
Bounded R8 volume conversion to runtime EVVOL.
std::vector< std::uint8_t > blob
std::uint32_t height
std::uint32_t width
std::uint64_t bytes
std::string name
bool found
Json object
std::uint32_t depth
Owning, renderer-independent dynamic values.
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Move-only operation result carrying either a value or Status.
Definition Result.h:155
static Result success(T value)
Construct a successful result owning value.
Definition Result.h:164
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
The canonical owning dynamic value used by data-facing protocols.
Definition Value.h:31
Result< std::string > toJson() const
Serialize this value as deterministic compact JSON.
Definition Value.cpp:67
static Result< Value > fromJson(std::string_view json)
Parse one strict JSON value into an owning Value.
Definition Value.cpp:57
std::map< std::string, Value > Object
Definition Value.h:34
Result< CookedCanonicalVolumeTexture > cookCanonicalVolumeTextureRgba8(std::span< const uint8_t > definition, std::span< const uint8_t > sourceR8, uint64_t maximumDecodedBytes)
void put32(std::vector< char > &b, uint32_t v)
Put 32.
Definition zip_writer.h:56
std::variant< std::monostate, std::int64_t, double, std::string, bool > Value
Definition Database.h:26
const EditorValue * field(const EditorValue &value, const char *name)
Runtime definition and RGBA8 bulk generated from one canonical volume.