载入中...
搜索中...
未找到
EvpackMeshVfx.cpp
浏览该文件的文档.
2#include <cmath>
3#include <map>
6#include "asset/ShaderAsset.h"
10
12namespace {} // namespace
15 std::unique_ptr<stylize::MeshVfxAssetInstance> playback;
16 std::vector<std::unique_ptr<asset_graphics::EvpackShader>> shaders;
17};
18EvpackMeshVfx::EvpackMeshVfx(std::unique_ptr<Impl> impl) : impl_(std::move(impl)) {}
21 const AssetRef& asset,
22 const asset::EvpackCapabilities& capabilities,
23 graphics::Graphics& graphics) {
24 auto payload = reader.read(asset, "eve.stylize.mesh-vfx/1", capabilities, 1024 * 1024);
25 if (!payload) return Result<std::unique_ptr<EvpackMeshVfx>>::failure(payload.status());
26 if (payload.value().chunks.size() != 1 || payload.value().chunks[0].kind != asset::EvpackChunkKind::Definition)
28 DiagnosticCode::InvalidArgument, "Effect requires one definition", {}, {}, "asset.mesh-vfx"));
29 auto value = asset::decodeRuntimeDefinition(payload.value().chunks[0].bytes);
30 if (!value) return Result<std::unique_ptr<EvpackMeshVfx>>::failure(value.status());
31 auto json = value.value().toJson();
32 if (!json) return Result<std::unique_ptr<EvpackMeshVfx>>::failure(json.status());
33 auto definition = stylize::MeshVfxAsset::fromJson(json.value());
34 if (!definition) return Result<std::unique_ptr<EvpackMeshVfx>>::failure(definition.status());
35 if (definition.value().layers.size() > 32 || definition.value().trail || definition.value().trailBinding ||
36 !definition.value().animationTriggers.play.empty() || !definition.value().animationTriggers.stop.empty() ||
37 !definition.value().animationTriggers.trailBreak.empty())
40 "Package renderer supports up to 32 mesh layers; trail/animation attachments require a gameplay adapter",
41 {}, {}, "asset.mesh-vfx"));
42 std::map<std::string, std::map<std::string, float>> defaults;
43 std::vector<AssetRef> references;
44 for (const auto& layer : definition.value().layers) {
45 const float cycle = layer.playback.fadeIn + layer.playback.duration + layer.playback.fadeOut;
46 if (!std::isfinite(cycle) || (layer.playback.loop && cycle <= 0))
48 Diagnostic::error(DiagnosticCode::InvalidArgument, "Invalid playback cycle", {}, {}, "asset.mesh-vfx"));
49 auto reference = AssetRef::parse(layer.style);
50 if (!reference) return Result<std::unique_ptr<EvpackMeshVfx>>::failure(reference.status());
51 auto shader = asset::loadShaderAsset(reader, reference.value(), capabilities);
52 if (!shader) return Result<std::unique_ptr<EvpackMeshVfx>>::failure(shader.status());
53 if (shader.value().interface != asset::ShaderAssetInterface::Mesh3D)
55 DiagnosticCode::InvalidArgument, "Mesh effect requires mesh shader", {}, {}, "asset.mesh-vfx"));
57 if (!layout) return Result<std::unique_ptr<EvpackMeshVfx>>::failure(layout.status());
58 auto& parameters = defaults[layer.style];
59 for (const auto& parameter : shader.value().parameters) {
60 if (parameter.defaults.size() != 1)
61 return Result<std::unique_ptr<EvpackMeshVfx>>::failure(
62 Diagnostic::error(DiagnosticCode::Unsupported, "Mesh VFX curves require scalar shader parameters",
63 {}, {}, "asset.mesh-vfx"));
64 parameters[parameter.name] = parameter.defaults.front();
65 }
66 references.push_back(std::move(reference).takeValue());
67 }
68 auto playback = stylize::MeshVfxAssetInstance::create(definition.value(), defaults);
69 if (!playback) return Result<std::unique_ptr<EvpackMeshVfx>>::failure(playback.status());
70 auto impl = std::make_unique<Impl>(Impl{graphics, std::move(playback).takeValue(), {}});
71 for (const auto& reference : references) {
72 auto shader = asset_graphics::EvpackShader::load(reader, reference, capabilities, graphics);
73 if (!shader) return Result<std::unique_ptr<EvpackMeshVfx>>::failure(shader.status());
74 impl->shaders.push_back(std::move(shader).takeValue());
75 }
76 auto result = std::unique_ptr<EvpackMeshVfx>(new EvpackMeshVfx(std::move(impl)));
77 result->play();
78 return Result<std::unique_ptr<EvpackMeshVfx>>::success(std::move(result));
79}
80void EvpackMeshVfx::play() noexcept { impl_->playback->play(); }
82 if (!std::isfinite(dt) || dt < 0)
84 Diagnostic::error(DiagnosticCode::InvalidArgument, "Invalid dt", {}, {}, "asset.mesh-vfx"));
85 // Bound accumulated time before changing any layer.
86 for (std::size_t i = 0; i < impl_->playback->layerCount(); ++i)
87 if (!std::isfinite(impl_->playback->layer(i).elapsed() + dt))
89 Diagnostic::error(DiagnosticCode::InvalidArgument, "Playback time overflow", {}, {}, "asset.mesh-vfx"));
90 impl_->playback->update(dt);
91 return Result<void>::success();
92}
93Result<void> EvpackMeshVfx::stop(float fadeOutSeconds) {
94 if (!std::isfinite(fadeOutSeconds) || fadeOutSeconds < 0)
96 Diagnostic::error(DiagnosticCode::InvalidArgument, "Invalid fade", {}, {}, "asset.mesh-vfx"));
97 impl_->playback->stop(fadeOutSeconds);
98 return Result<void>::success();
99}
100Result<void> EvpackMeshVfx::setFloat(std::size_t layer, std::string_view name, float value) {
101 if (layer >= impl_->playback->layerCount() || !std::isfinite(value))
103 Diagnostic::error(DiagnosticCode::InvalidArgument, "Invalid layer/value", {}, {}, "asset.mesh-vfx"));
104 auto& style = impl_->playback->layer(layer).style();
105 if (!style.hasParam(std::string(name)))
107 Diagnostic::error(DiagnosticCode::NotFound, "Parameter not found", {}, {}, "asset.mesh-vfx"));
108 style.setFloat(std::string(name), value);
109 return Result<void>::success();
110}
111Result<void> EvpackMeshVfx::draw(graphics::Mesh& mesh, const std::array<float, 16>& transform,
112 OptionalRef<graphics::Texture> texture, const std::array<float, 4>& tint) {
113 for (std::size_t i = 0; i < impl_->shaders.size(); ++i) {
114 auto& layer = impl_->playback->layer(i);
115 if (layer.intensity() <= 0) continue;
116 auto& shader = *impl_->shaders[i];
117 for (const auto& parameter : shader.definition().parameters) {
118 const float value = layer.style().getFloat(parameter.name);
119 auto applied = shader.setParameter(parameter.name, std::span<const float>(&value, 1));
120 if (!applied) return applied;
121 }
122 auto color = tint;
123 color[3] *= layer.intensity();
124 auto drawn = shader.drawMesh(mesh, transform, texture, color);
125 if (!drawn) return drawn;
126 }
127 return Result<void>::success();
128}
130 const asset::EvpackCapabilities& capabilities) {
131 auto candidate = load(reader, asset, capabilities, impl_->graphics);
132 if (!candidate) return Result<void>::failure(candidate.status());
133 impl_.swap(candidate.value()->impl_);
134 return Result<void>::success();
135}
136std::vector<std::string> EvpackMeshVfx::drainEvents() { return impl_->playback->drainEvents(); }
137} // namespace eve::asset_stylize
double value
Value::Object payload
AuthorityStoreHandleRef reference
Definition Authority.cpp:24
void * impl
Typed capability-aware runtime access to admitted packs.
std::string layout
glm::vec4 tint
std::string name
TileLayer * layer
Mesh * mesh
Shader * shader
JSON-free versioned runtime metadata codec.
Stable asset identity backed by PersistentId.
Definition ResourceRef.h:53
static Result< AssetRef > parse(std::string_view text)
Parse an asset://<canonical UUID> reference.
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
Immutable reader retaining an admitted pack by shared ownership.
Result< RuntimeAssetPayload > read(const AssetRef &asset, std::string_view expectedType, const EvpackCapabilities &capabilities, std::uint64_t maximumDecodedBytes) const
Resolve, type-check, variant-select and decode a canonical runtime asset.
static Result< std::unique_ptr< EvpackShader > > load(const asset::EvpackResourceReader &reader, const AssetRef &asset, const asset::EvpackCapabilities &capabilities, graphics::Graphics &graphics)
Validate then upload; failures preserve all existing instances. Reader is not retained.
Owning package-backed mesh effect, using the canonical MeshVfxAsset playback and curves....
Result< void > setFloat(std::size_t layer, std::string_view name, float value)
Set one scalar override for one layer; authored curves still own animated parameters on advance.
Result< void > reload(const asset::EvpackResourceReader &reader, const AssetRef &asset, const asset::EvpackCapabilities &capabilities)
Atomically replace only after successful full load. Reapply defaults and restart; failure preserves o...
~EvpackMeshVfx()
Releases EvpackMeshVfx resources.
Result< void > draw(graphics::Mesh &mesh, const std::array< float, 16 > &transform, OptionalRef< graphics::Texture > texture, const std::array< float, 4 > &tint={1, 1, 1, 1})
Draw active layers during an open 3D frame with caller-owned mesh/texture and instance transform....
std::vector< std::string > drainEvents()
Drain canonical timeline events; no caller callback is invoked while advancing.
static Result< std::unique_ptr< EvpackMeshVfx > > load(const asset::EvpackResourceReader &reader, const AssetRef &asset, const asset::EvpackCapabilities &capabilities, graphics::Graphics &graphics)
Resolve every layer and validate all candidates before GPU upload; no partial instance is published.
void play() noexcept
Restart the authored playback and reset its curves on the next advance.
Result< void > stop(float fadeOutSeconds=0.f)
Stop with an optional finite nonnegative fade.
Result< void > advance(float dt)
Advance using finite nonnegative seconds; invalid input leaves playback unchanged.
EvpackMeshVfx(const EvpackMeshVfx &)=delete
GPU mesh handle (+ optional CPU morph targets).
Definition Mesh.h:25
static eve::Result< std::unique_ptr< MeshVfxAssetInstance > > create(const MeshVfxAsset &asset)
Build independent runtime state for every asset layer.
Result< void > validateShaderAssetGpu(const asset::ShaderAsset &shader)
Validate complete SPIR-V semantics and the supported engine pipeline interface before upload.
Result< Value > decodeRuntimeDefinition(std::span< const std::uint8_t > bytes, const RuntimeDefinitionLimits &limits)
Decode a bounded EVDEF\0\1 metadata tree without a JSON parser.
EVENGINE_API_FOUNDATION Result< ShaderAsset > loadShaderAsset(const EvpackResourceReader &reader, const AssetRef &asset, const EvpackCapabilities &capabilities)
Read and decode one capability-selected eve.shader/1 from an admitted runtime package.
std::optional< std::reference_wrapper< T > > OptionalRef
Optional borrowed reference; it does not extend T's lifetime.
Definition BorrowedRef.h:24
Actual runtime device capabilities used for variant selection.
Definition Evpack.h:92
std::unique_ptr< stylize::MeshVfxAssetInstance > playback
std::vector< std::unique_ptr< asset_graphics::EvpackShader > > shaders
static eve::Result< MeshVfxAsset > fromJson(std::string_view json)
Parse, migrate, and validate a JSON asset without mutating live state.
glm::vec4 color