2021-11-11 21:22:24 +01:00
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
// //
|
|
|
|
// ozz-animation is hosted at http://github.com/guillaumeblanc/ozz-animation //
|
|
|
|
// and distributed under the MIT License (MIT). //
|
|
|
|
// //
|
|
|
|
// Copyright (c) Guillaume Blanc //
|
|
|
|
// //
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a //
|
|
|
|
// copy of this software and associated documentation files (the "Software"), //
|
|
|
|
// to deal in the Software without restriction, including without limitation //
|
|
|
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense, //
|
|
|
|
// and/or sell copies of the Software, and to permit persons to whom the //
|
|
|
|
// Software is furnished to do so, subject to the following conditions: //
|
|
|
|
// //
|
|
|
|
// The above copyright notice and this permission notice shall be included in //
|
|
|
|
// all copies or substantial portions of the Software. //
|
|
|
|
// //
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR //
|
|
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL //
|
|
|
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER //
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING //
|
|
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER //
|
|
|
|
// DEALINGS IN THE SOFTWARE. //
|
|
|
|
// //
|
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
|
|
|
#ifndef OZZ_OZZ_ANIMATION_RUNTIME_TRACK_TRIGGERING_JOB_H_
|
|
|
|
#define OZZ_OZZ_ANIMATION_RUNTIME_TRACK_TRIGGERING_JOB_H_
|
|
|
|
|
2023-03-26 11:44:29 +02:00
|
|
|
#include "ozz/animation/runtime/export.h"
|
2021-11-11 21:22:24 +01:00
|
|
|
#include "ozz/base/platform.h"
|
|
|
|
|
|
|
|
namespace ozz {
|
|
|
|
namespace animation {
|
|
|
|
|
|
|
|
class FloatTrack;
|
|
|
|
|
|
|
|
// Track edge triggering job implementation. Edge triggering wording refers to
|
|
|
|
// signal processing, where a signal edge is a transition from low to high or
|
|
|
|
// from high to low. It is called an "edge" because of the square wave which
|
|
|
|
// represents a signal has edges at those points. A rising edge is the
|
|
|
|
// transition from low to high, a falling edge is from high to low.
|
|
|
|
// TrackTriggeringJob detects when track curve crosses a threshold value,
|
|
|
|
// triggering dated events that can be processed as state changes.
|
|
|
|
// Only FloatTrack is supported, because comparing to a threshold for other
|
|
|
|
// track types isn't possible.
|
|
|
|
// The job execution actually performs a lazy evaluation of edges. It builds an
|
|
|
|
// iterator that will process the next edge on each call to ++ operator.
|
2023-03-26 11:44:29 +02:00
|
|
|
struct OZZ_ANIMATION_DLL TrackTriggeringJob {
|
2021-11-11 21:22:24 +01:00
|
|
|
TrackTriggeringJob();
|
|
|
|
|
|
|
|
// Validates job parameters.
|
|
|
|
bool Validate() const;
|
|
|
|
|
|
|
|
// Validates and executes job. Execution is lazy. Iterator operator ++ is
|
|
|
|
// actually doing the processing work.
|
|
|
|
bool Run() const;
|
|
|
|
|
|
|
|
// Input range. 0 is the beginning of the track, 1 is the end.
|
|
|
|
// from and to can be of any sign, any order, and any range. The job will
|
|
|
|
// perform accordingly:
|
|
|
|
// - if difference between from and to is greater than 1, the iterator will
|
|
|
|
// loop multiple times on the track.
|
|
|
|
// - if from is greater than to, then the track is processed backward (rising
|
|
|
|
// edges in forward become falling ones).
|
|
|
|
float from;
|
|
|
|
float to;
|
|
|
|
|
|
|
|
// Edge detection threshold value.
|
|
|
|
// A rising edge is detected as soon as the track value becomes greater than
|
|
|
|
// the threshold.
|
|
|
|
// A falling edge is detected as soon as the track value becomes smaller or
|
|
|
|
// equal than the threshold.
|
|
|
|
float threshold;
|
|
|
|
|
|
|
|
// Track to sample.
|
|
|
|
const FloatTrack* track;
|
|
|
|
|
|
|
|
// Job output iterator.
|
|
|
|
class Iterator;
|
|
|
|
Iterator* iterator;
|
|
|
|
|
|
|
|
// Returns an iterator referring to the past-the-end element. It should only
|
|
|
|
// be used to test if iterator loop reached the end (using operator !=), and
|
|
|
|
// shall not be dereferenced.
|
|
|
|
Iterator end() const;
|
|
|
|
|
|
|
|
// Structure of an edge as detected by the job.
|
|
|
|
struct Edge {
|
|
|
|
float ratio; // Ratio at which track value crossed threshold.
|
|
|
|
bool rising; // true is edge is rising (getting higher than threshold).
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
// Iterator implementation. Calls to ++ operator will compute the next edge. It
|
|
|
|
// should be compared (using operator !=) to job's end iterator to test if the
|
|
|
|
// last edge has been reached.
|
2023-03-26 11:44:29 +02:00
|
|
|
class OZZ_ANIMATION_DLL TrackTriggeringJob::Iterator {
|
2021-11-11 21:22:24 +01:00
|
|
|
public:
|
|
|
|
Iterator() : job_(nullptr), outer_(0.f), inner_(0) {}
|
|
|
|
|
|
|
|
// Evaluate next edge.
|
|
|
|
// Calling this function on an end iterator results in an assertion in debug,
|
|
|
|
// an undefined behavior otherwise.
|
|
|
|
const Iterator& operator++();
|
|
|
|
Iterator operator++(int) {
|
|
|
|
Iterator prev = *this;
|
|
|
|
++*this;
|
|
|
|
return prev;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Compare with other iterators.
|
|
|
|
bool operator!=(const Iterator& _it) const {
|
|
|
|
return inner_ != _it.inner_ || outer_ != _it.outer_ || job_ != _it.job_;
|
|
|
|
}
|
|
|
|
bool operator==(const Iterator& _it) const {
|
|
|
|
return job_ == _it.job_ && outer_ == _it.outer_ && inner_ == _it.inner_;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Dereferencing operators.
|
|
|
|
const Edge& operator*() const {
|
|
|
|
assert(*this != job_->end() && "Can't dereference end iterator.");
|
|
|
|
return edge_;
|
|
|
|
}
|
|
|
|
const Edge* operator->() const {
|
|
|
|
assert(*this != job_->end() && "Can't dereference end iterator.");
|
|
|
|
return &edge_;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
friend struct TrackTriggeringJob;
|
|
|
|
|
|
|
|
// Constructors used by the job.
|
|
|
|
explicit Iterator(const TrackTriggeringJob* _job);
|
|
|
|
struct End {};
|
|
|
|
Iterator(const TrackTriggeringJob* _job, End)
|
|
|
|
: job_(_job),
|
|
|
|
outer_(0.f),
|
|
|
|
inner_(-2) { // Can never be reached while looping.
|
|
|
|
}
|
|
|
|
|
|
|
|
// Job this iterator works on.
|
|
|
|
const TrackTriggeringJob* job_;
|
|
|
|
|
|
|
|
// Current value of the outer loop, aka a ratio cursor between from and to.
|
|
|
|
float outer_;
|
|
|
|
|
|
|
|
// Current value of the inner loop, aka a key frame index.
|
|
|
|
ptrdiff_t inner_;
|
|
|
|
|
|
|
|
// Latest evaluated edge.
|
|
|
|
Edge edge_;
|
|
|
|
};
|
|
|
|
|
|
|
|
// end() job function inline implementation.
|
|
|
|
inline TrackTriggeringJob::Iterator TrackTriggeringJob::end() const {
|
|
|
|
return Iterator(this, Iterator::End());
|
|
|
|
}
|
|
|
|
} // namespace animation
|
|
|
|
} // namespace ozz
|
|
|
|
#endif // OZZ_OZZ_ANIMATION_RUNTIME_TRACK_TRIGGERING_JOB_H_
|