载入中...
搜索中...
未找到
UnityNativeVolumeTexture.cpp
浏览该文件的文档.
2
6
7#include <charconv>
8#include <stdexcept>
9#include <string_view>
10
11namespace eve::asset_import {
12namespace {
13std::string_view volumeField(std::string_view text, std::string_view key) {
14 std::string_view found;
15 bool seen = false;
16 while (!text.empty()) {
17 const auto end = text.find('\n');
18 auto line = text.substr(0, end);
19 const auto first = line.find_first_not_of(" \t\r");
20 if (first != std::string_view::npos) line.remove_prefix(first);
21 if (line.starts_with(key) && line.size() > key.size() && line[key.size()] == ':') {
22 if (seen) throw std::runtime_error("duplicate Texture3D field");
23 seen = true;
24 line.remove_prefix(key.size() + 1);
25 const auto begin = line.find_first_not_of(" \t\r");
26 found = begin == std::string_view::npos ? std::string_view{} : line.substr(begin);
27 const auto last = found.find_last_not_of(" \t\r");
28 if (last != std::string_view::npos) found = found.substr(0, last + 1);
29 }
30 if (end == std::string_view::npos) break;
31 text.remove_prefix(end + 1);
32 }
33 if (!seen) throw std::runtime_error("missing Texture3D field");
34 return found;
35}
36uint64_t volumeNumber(std::string_view text, std::string_view key) {
37 const auto value = volumeField(text, key);
38 uint64_t out = 0;
39 const auto parsed = std::from_chars(value.data(), value.data() + value.size(), out);
40 if (parsed.ec != std::errc{} || parsed.ptr != value.data() + value.size())
41 throw std::runtime_error("invalid Texture3D integer");
42 return out;
43}
44} // namespace
45
47 const UnitySourceAsset& source) {
48 const auto& bytes = request.files.at(source.path);
49 const std::string_view text(reinterpret_cast<const char*>(bytes.data()), bytes.size());
50 if (text.find("\nTexture3D:") == std::string_view::npos)
52 DiagnosticCode::Unsupported, "native asset is not a text Texture3D", source.path, {}, "asset.import"));
53 try {
54 const auto width = volumeNumber(text, "m_Width"), height = volumeNumber(text, "m_Height"),
55 depth = volumeNumber(text, "m_Depth"), dataSize = volumeNumber(text, "m_DataSize");
56 if (volumeNumber(text, "m_Format") != 5 || volumeNumber(text, "m_MipCount") != 1 ||
57 volumeNumber(text, "m_ColorSpace") != 0 || volumeNumber(text, "size") != 0 ||
58 !volumeField(text, "path").empty())
60 DiagnosticCode::Unsupported, "requires an embedded linear R8 Texture3D with one mip and no stream data",
61 source.path, {}, "asset.import"));
62 if (!width || !height || !depth || width > UINT32_MAX || height > UINT32_MAX || depth > UINT32_MAX ||
65 throw std::runtime_error("Texture3D dimensions, bytes or budget are invalid");
66 const uint64_t voxels = width * height * depth;
67 const auto hex = volumeField(text, "_typelessdata");
68 if (voxels != dataSize || voxels > request.limits.maximumSourceBytes || voxels > SIZE_MAX / 2 ||
69 hex.size() != size_t(voxels * 2))
70 throw std::runtime_error("Texture3D dimensions, bytes or budget are invalid");
71 std::vector<uint8_t> r8;
72 r8.resize(size_t(voxels));
73 for (size_t i = 0; i < r8.size(); ++i) {
74 unsigned value = 0;
75 const auto parsed = std::from_chars(hex.data() + i * 2, hex.data() + i * 2 + 2, value, 16);
76 if (parsed.ec != std::errc{} || parsed.ptr != hex.data() + i * 2 + 2)
77 throw std::runtime_error("invalid Texture3D hex");
78 r8[i] = uint8_t(value);
79 }
80 auto manifest = detail::baseManifest(request.package, "eve.unity-texture3d/1");
81 if (!manifest) return Result<PreparedAssetImport>::failure(manifest.status());
82 const auto id = request.package.packageId.child("unity:" + source.guid);
83 auto ref = detail::assetRef(id);
84 if (!ref) return Result<PreparedAssetImport>::failure(ref.status());
85 const std::string root = "assets/" + id.format() + "/";
86 Value::Object definition{{"schema", "eve.volume-texture"},
87 {"schemaVersion", int64_t(1)},
88 {"width", int64_t(width)},
89 {"height", int64_t(height)},
90 {"depth", int64_t(depth)},
91 {"encoding", "r8"},
92 {"usage", "noise"},
93 {"blob", root + "source.r8"}};
94 auto encoded = Value(std::move(definition)).toJson();
95 if (!encoded) return Result<PreparedAssetImport>::failure(encoded.status());
97 std::span<const uint8_t>(reinterpret_cast<const uint8_t*>(encoded.value().data()), encoded.value().size()),
99 if (!verified) return Result<PreparedAssetImport>::failure(verified.status());
101 out.manifest = std::move(manifest).takeValue();
102 const std::string definitionPath = root + "asset.json";
103 out.manifest.assets.push_back(
104 {ref.value(),
105 "eve.volume-texture",
106 SchemaVersion(1),
107 definitionPath,
108 detail::sha256(std::span<const uint8_t>(reinterpret_cast<const uint8_t*>(encoded.value().data()),
109 encoded.value().size())),
110 {"volume-texture", "usage:noise", "source:unity"}});
111 out.manifest.entrypoints.emplace("default", ref.value());
112 out.manifest.provenance["sourceName"] = Value(source.path);
113 out.manifest.provenance["sourceHash"] = Value(detail::sha256(bytes));
114 out.entries.push_back({definitionPath, {encoded.value().begin(), encoded.value().end()}});
115 out.entries.push_back({root + "source.r8", std::move(r8)});
116 out.sourceMappings.push_back({"11700000", ref.value()});
117 out.findings.push_back({source.path, "Texture3D.R8", ImportDisposition::Translated,
118 "embedded linear R8 volume retained with X-fastest voxel order"});
119 auto report = detail::finalizeImportReport(out, request.package, "unity", "Texture3D-v3",
120 {{"sourceFormat", Value("R8")}});
121 if (!report) return Result<PreparedAssetImport>::failure(report.status());
122 return Result<PreparedAssetImport>::success(std::move(out));
123 } catch (const std::exception& error) {
126 }
127}
128
129} // namespace eve::asset_import
double value
int root
Definition AnimSmr.cpp:119
Bounded R8 volume conversion to runtime EVVOL.
const GltfImportRequest & request
std::uint32_t key
std::int32_t first
std::uint32_t height
std::uint32_t width
std::string text
std::uint64_t bytes
std::string error
Definition Package.cpp:60
float begin
bool found
Direct Unity text-serialization adapter for TerrainData and Prefab assets.
const UnitySourceAsset & source
std::uint32_t depth
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
std::map< std::string, Value > Object
Definition Value.h:34
Id128 child(std::string_view role) const noexcept
Derives a deterministic child UUID for a hierarchical identity.
Definition Identity.h:192
std::string sha256(std::span< const std::uint8_t > bytes)
Sha 256.
EVENGINE_API_PLATFORM Result< void > finalizeImportReport(PreparedAssetImport &prepared, const ImportPackageIdentity &package, std::string_view sourceEngine, std::string_view sourceVersion, Value::Object options={})
Append the deterministic mandatory import report and bind it from provenance.
Result< asset::EvaManifest > baseManifest(const ImportPackageIdentity &package, std::string_view importer)
Base manifest.
Result< AssetRef > assetRef(PersistentId id)
Asset ref.
Result< PreparedAssetImport > prepareUnityNativeVolumeTexture(const UnityProjectImportRequest &request, const UnitySourceAsset &source)
Convert embedded linear R8 Unity Texture3D to an owning canonical volume candidate.
Result< CookedCanonicalVolumeTexture > cookCanonicalVolumeTextureRgba8(std::span< const uint8_t > definition, std::span< const uint8_t > sourceR8, uint64_t maximumDecodedBytes)
detail::StrongUint64< detail::SchemaVersionTag > SchemaVersion
Persistent data-format version; not a runtime replacement generation.
std::vector< EvaAssetEntry > assets
Definition EvaManifest.h:69
Value::Object provenance
Definition EvaManifest.h:72
std::map< std::string, AssetRef > entrypoints
Definition EvaManifest.h:71
Owning, validated source archive candidate not yet published to disk/database.
std::vector< ImportFinding > findings
std::vector< asset::EvaArchiveEntry > entries
std::vector< ImportSourceMapping > sourceMappings
In-memory Unity project slice; keys are normalized project-relative paths.
Immutable-by-convention owning source index entry; no borrowed source addresses.
Definition UnitySource.h:38