载入中...
搜索中...
未找到
MontagePlayer.cpp
浏览该文件的文档.
54Result<void> MontagePlayer::prepare(action::ActionTimeline timeline, IMontageClipProvider& provider) {
68Result<void> MontagePlayer::prepare(action::ActionTimeline timeline, std::vector<MontageClipAsset>&& clips) {
78 if (!std::isfinite(clips[index].clip->getDuration()) || clips[index].clip->getDuration() <= 0.0f)
98 const double sourceEnd = section.sourceEnd.isZero() ? clip->getDuration() : section.sourceEnd.seconds();
124 Diagnostic::error(DiagnosticCode::InvalidArgument, "montage has not been prepared", "montage"));
144 activate(*section, Duration::fromNanoseconds(time_.nanoseconds() - section->start.nanoseconds()));
152 Diagnostic::error(DiagnosticCode::InvalidArgument, "montage has not been prepared", "montage"));
165 Diagnostic::error(DiagnosticCode::InvalidArgument, "montage has not been prepared", "montage"));
177 Diagnostic::error(DiagnosticCode::InvalidArgument, "montage has not been prepared", "montage"));
180 Diagnostic::error(DiagnosticCode::InvalidArgument, "replacement montage clip is incomplete", "clip"));
183 DiagnosticCode::InvalidArgument, "replacement montage clip duration must be positive", "clip.duration"));
184 const auto asset = std::find_if(clips_.begin(), clips_.end(), [&](const auto& value) { return value.uri == uri; });
192 const double sourceEnd = section.sourceEnd.isZero() ? clip->getDuration() : section.sourceEnd.seconds();
193 if (sourceStart >= clip->getDuration() || sourceEnd > clip->getDuration() || sourceEnd <= sourceStart)
204 if (section) activate(*section, Duration::fromNanoseconds(time_.nanoseconds() - section->start.nanoseconds()));
212 Diagnostic::error(DiagnosticCode::InvalidArgument, "montage has not been prepared", "montage"));
215 Diagnostic::error(DiagnosticCode::InvalidArgument, "action execution id must not be zero", "executionId"));
231 DiagnosticCode::InvalidArgument, "montage must be prepared and playing before rebinding", "montage"));
234 Diagnostic::error(DiagnosticCode::InvalidArgument, "action execution id must not be zero", "executionId"));
252 const auto found = std::find_if(clips_.begin(), clips_.end(), [&](const auto& asset) { return asset.uri == uri; });
263void MontagePlayer::activate(const action::ActionAnimationSection& section, Duration localTime) {
269 section.sourceEnd.isZero() ? clip->getDuration() : static_cast<float>(section.sourceEnd.seconds());
271 player_->setBlendCurve(section.blendCurve == action::ActionBlendCurve::Linear ? AnimBlendCurve::Linear
332Result<MontageAdvance> MontagePlayer::present(const action::ActionAdvance& advance, SimulationTick tick) {
335 Diagnostic::error(DiagnosticCode::InvalidArgument, "montage has not been prepared", "montage"));
344 Diagnostic::error(DiagnosticCode::InvalidArgument, "action advance time is outside the presentation cursor",
348 Diagnostic::error(DiagnosticCode::Conflict, "montage tick must advance monotonically", "tick"));
362 auto next = std::find_if(timeline_->animationSections.begin(), timeline_->animationSections.end(),
365 next == timeline_->animationSections.end() ? result.current : std::min(next->start, result.current);
371 activate(*section, Duration::fromNanoseconds(cursor.nanoseconds() - section->start.nanoseconds()));
373 const Duration slice = Duration::fromNanoseconds(sliceEnd.nanoseconds() - cursor.nanoseconds());
382 result.sectionId = activeSection_ ? std::optional<LogicalId>(activeSection_->id) : std::nullopt;
386 const double t = std::clamp(currentSeconds / timeline_->montage.defaultBlendIn.seconds(), 0.0, 1.0);
392 const double start = timeline_->duration.seconds() - timeline_->montage.defaultBlendOut.seconds() +
410 std::move(result), Status::success(result.completed ? StatusCode::Applied : StatusCode::Pending));
413std::vector<action::ActionTimelineEvent> MontagePlayer::realignStateEvents(Duration target) const {
422 {isActive ? action::ActionTimelineEventKind::StateEnter : action::ActionTimelineEventKind::StateExit,
433Result<MontageAdvance> MontagePlayer::jumpToTime(action::ActionExecutionId executionId, Duration target,
437 Diagnostic::error(DiagnosticCode::InvalidArgument, "montage has not been prepared", "montage"));
443 Diagnostic::error(DiagnosticCode::InvalidArgument, "jump belongs to another execution", "executionId"));
446 Diagnostic::error(DiagnosticCode::InvalidArgument, "montage jump is outside the timeline", "target"));
449 Diagnostic::error(DiagnosticCode::Conflict, "montage tick must advance monotonically", "tick"));
461 activate(*section, Duration::fromNanoseconds(target.nanoseconds() - section->start.nanoseconds()));
468 return Result<MontageAdvance>::success(std::move(result), Status::success(StatusCode::Applied));
471Result<MontageAdvance> MontagePlayer::jumpToSection(action::ActionExecutionId executionId, std::size_t sectionIndex,
475 Diagnostic::error(DiagnosticCode::InvalidArgument, "montage has not been prepared", "montage"));
481Result<MontageAdvance> MontagePlayer::evaluateSectionProgress(action::ActionExecutionId executionId,
489 Diagnostic::error(DiagnosticCode::InvalidArgument, "montage has not been prepared", "montage"));
501 Diagnostic::error(DiagnosticCode::InvalidArgument, "montage has not been prepared", "montage"));
502 const auto found = std::upper_bound(timeline_->splitTimestamps.begin(), timeline_->splitTimestamps.end(), time_);
510 Diagnostic::error(DiagnosticCode::InvalidArgument, "montage has not been prepared", "montage"));
513 const double span = static_cast<double>(range.value().second.nanoseconds() - range.value().first.nanoseconds());
514 const double elapsed = static_cast<double>(time_.nanoseconds() - range.value().first.nanoseconds());
521 Diagnostic::error(DiagnosticCode::InvalidArgument, "montage has not been prepared", "montage"));
522 if (!playing_) return Result<MontageAdvance>::success(MontageAdvance{}, Status::success(StatusCode::NoOp));
525 Diagnostic::error(DiagnosticCode::Conflict, "montage tick must advance monotonically", "tick"));
535 {action::ActionTimelineEventKind::StateExit, track.id, state.id, state.type, time_, state.payload});
546 return Result<MontageAdvance>::success(std::move(result), Status::success(StatusCode::Applied));
552 DiagnosticCode::InvalidArgument, "montage blend-out duration must be non-negative", "duration"));
555 Diagnostic::error(DiagnosticCode::InvalidArgument, "montage has not been prepared", "montage"));
561 Diagnostic::error(DiagnosticCode::Conflict, "montage tick must advance monotonically", "tick"));
575 return Result<MontageAdvance>::success(std::move(result), Status::success(StatusCode::Applied));
582 {action::ActionTimelineEventKind::StateExit, track.id, state.id, state.type, time_, state.payload});
590 return Result<MontageAdvance>::success(std::move(result), Status::success(StatusCode::Pending));
602 Diagnostic::error(DiagnosticCode::Conflict, "montage tick must advance monotonically", "tick"));
606 const double t = std::clamp(blendOutElapsed_.seconds() / blendOutDuration_.seconds(), 0.0, 1.0);
620 std::move(result), Status::success(result.completed ? StatusCode::Applied : StatusCode::Pending));
Deterministic presentation-only action montage playback.
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
constexpr std::int64_t nanoseconds() const noexcept
Return the exact signed nanosecond representation.
Definition Time.h:69
Result< Duration > tryAdd(Duration other) const
Add two durations with overflow validation.
Definition Time.cpp:30
static constexpr Duration fromNanoseconds(std::int64_t nanoseconds) noexcept
Construct an exact duration from nanoseconds.
Definition Time.h:55
double seconds() const noexcept
Return this duration as seconds for legacy/presentation APIs.
Definition Time.cpp:28
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
static Status success(StatusCode code=StatusCode::Ok)
Construct a successful status with an explicit non-error outcome.
Definition Status.h:81
Keyframed skeletal animation clip (local TRS tracks per bone). Script type: AnimClip.
Definition AnimClip.h:145
Single-clip (or cross-fading) 3D animation player. Script type: AnimPlayer.
Definition AnimPlayer.h:30
Evaluated local (and optional world) pose for an AnimSkeleton. Script type: AnimPose.
Definition AnimPose.h:17
3D bone hierarchy + bind-pose local TRS for skeletal animation. Independent of ik::Skeleton3D (FABRIK...
Definition AnimSkeleton.h:16
Synchronous ownership-transfer port used to resolve montage clip URIs.
Definition MontagePlayer.h:40
virtual Result< std::unique_ptr< AnimClip > > load(std::string_view uri, const AnimSkeleton &skeleton)=0
Resolve one URI into a clip compatible with the borrowed skeleton.
virtual void applyMontageRootMotion(const TransformTRS &delta) noexcept=0
Consume one borrowed filtered root-motion delta.
Presentation-only montage player over an ActionTimeline.
Definition MontagePlayer.h:107
Result< void > setSettings(action::ActionMontageSettings settings)
Apply validated montage-wide settings without rebuilding clip topology or playback time.
Definition MontagePlayer.cpp:149
Result< void > replaceClip(std::string_view uri, std::unique_ptr< AnimClip > clip)
Transactionally replace one URI-backed clip and preserve the current cursor and slot weight.
Definition MontagePlayer.cpp:174
Result< double > physicalSectionProgress(std::size_t sectionIndex) const
Return current normalized progress within an objective physical section.
Definition MontagePlayer.cpp:507
Result< void > reloadClips(IMontageClipProvider &provider)
Transactionally reload every referenced clip while preserving playback state.
Definition MontagePlayer.cpp:121
MontagePlayer(AnimSkeleton &skeleton)
Borrow a skeleton that must outlive this player.
Definition MontagePlayer.cpp:47
Result< void > setSectionSplits(std::vector< Duration > splitTimestamps)
Atomically replace objective physical-section split timestamps without rebuilding clip topology.
Definition MontagePlayer.cpp:162
Result< MontageAdvance > advanceBlendOut(Duration delta, SimulationTick tick)
Advance an active blend-out without advancing gameplay or montage time.
Definition MontagePlayer.cpp:593
Result< MontageAdvance > jumpToTime(action::ActionExecutionId executionId, Duration target, SimulationTick tick)
Atomically realign presentation and active state blocks to an externally authoritative timestamp.
Definition MontagePlayer.cpp:433
Result< MontageAdvance > jumpToSection(action::ActionExecutionId executionId, std::size_t sectionIndex, SimulationTick tick)
Jump presentation to the start of one objective physical section.
Definition MontagePlayer.cpp:471
Result< void > setRootMotionPolicy(const RootMotionPolicy &policy)
Replace the canonical root-motion policy used by presentation and the owned AnimPlayer.
Definition MontagePlayer.cpp:315
Result< MontageAdvance > evaluateSectionProgress(action::ActionExecutionId executionId, std::size_t sectionIndex, double progress, SimulationTick tick)
Evaluate a normalized physical-section progress and atomically realign presentation.
Definition MontagePlayer.cpp:481
Result< MontageAdvance > interrupt(SimulationTick tick)
Interrupt playback and emit paired exits for every active state block.
Definition MontagePlayer.cpp:518
Result< void > prepare(action::ActionTimeline timeline, std::vector< MontageClipAsset > &&clips)
Validate and atomically replace the complete montage presentation.
Definition MontagePlayer.cpp:68
Result< void > play(action::ActionExecutionId executionId)
Bind presentation playback to one authoritative ActionRuntime execution.
Definition MontagePlayer.cpp:209
Result< MontageAdvance > beginBlendOut(Duration duration, SimulationTick tick)
Enter continuous blend-out and emit exits for every active state block.
Definition MontagePlayer.cpp:549
Result< MontageAdvance > present(const action::ActionAdvance &advance, SimulationTick tick)
Present one ActionRuntime-owned advance without advancing gameplay time locally.
Definition MontagePlayer.cpp:332
void setRootMotionMask(MontageRootMotionMask mask) noexcept
Compatibility setter for axis enable bits.
Definition MontagePlayer.cpp:308
Result< std::size_t > physicalSectionIndex() const
Resolve the objective physical section containing the current cursor.
Definition MontagePlayer.cpp:498
Result< void > rebindExecution(action::ActionExecutionId executionId)
Rebind an already playing presentation after its external gameplay authority is recreated.
Definition MontagePlayer.cpp:228
Result< void > setRootMotionCharacterYaw(float yawRadians)
Update CharacterFacing yaw without replacing bake/lock/apply-space.
Definition MontagePlayer.cpp:325
constexpr std::uint64_t value() const noexcept
Returns the underlying value at an explicit protocol boundary.
Definition StrongUint64.h:26
static constexpr StrongUint64 zero() noexcept
Returns the zero value for this strong type.
Definition StrongUint64.h:24
constexpr bool isZero() const noexcept
Returns whether this value is zero.
Definition StrongUint64.h:28
@ Completed
@ StateEnter
Definition Animation.cpp:58
RootMotionLockAxes
Per-axis translation locks for extracted root-motion deltas.
Definition RootMotionPolicy.h:21
@ BindPose
Restore the skeleton bind pose on entering a gap.
eve::Result< void > validateRootMotionPolicy(const RootMotionPolicy &policy)
Validate policy fields.
Definition RootMotionPolicy.cpp:48
AnimBlendCurve
Deterministic built-in curve used by cross-fade pose interpolation.
Definition AnimPlayer.h:18
@ EaseInOut
constexpr bool hasLock(RootMotionLockAxes mask, RootMotionLockAxes axis) noexcept
True when mask contains the given axis bit.
Definition RootMotionPolicy.h:42
@ InvalidArgument
@ Conflict
@ Pending
@ NoOp
@ Applied
Definition Container.h:602
std::vector< ActionTimelineEvent > timelineEvents
Owning timeline boundaries crossed by this advance.
Definition Action.h:187
std::vector< ActionActiveBlock > activeBlocks
Owning samples of timeline states active after this advance.
Definition Action.h:189
Objective animation segment placed on the montage presentation lane.
Definition ActionTimeline.h:58
std::string animationUri
Definition ActionTimeline.h:60
Montage-wide presentation settings persisted with the action timeline.
Definition ActionTimeline.h:36
Canonical action timeline asset shared by runtime and editor.
Definition ActionTimeline.h:178
Result< void > validate() const
Validate ids, ranges, uniqueness and deterministic ordering.
Definition ActionTimeline.cpp:219
std::vector< ActionAnimationSection > animationSections
Definition ActionTimeline.h:184
Owning observation returned by one montage presentation step.
Definition MontagePlayer.h:88
std::vector< action::ActionTimelineEvent > events
Definition MontagePlayer.h:92
std::optional< LogicalId > sectionId
Definition MontagePlayer.h:91
std::vector< MontageActiveBlock > activeBlocks
Definition MontagePlayer.h:93
Compatibility-only axis enable mask for montage root motion.
Definition MontagePlayer.h:55
Policy applied after raw root-bone delta extraction. @ownership Value type; owned by AnimPlayer or th...
Definition RootMotionPolicy.h:62
RootMotionLockAxes lockAxes
Definition RootMotionPolicy.h:63
float characterYaw
Yaw in radians for CharacterFacing; ignored for BoneLocal.
Definition RootMotionPolicy.h:69