RavEngine
Loading...
Searching...
No Matches
track_triggering_job.h
1//----------------------------------------------------------------------------//
2// //
3// ozz-animation is hosted at http://github.com/guillaumeblanc/ozz-animation //
4// and distributed under the MIT License (MIT). //
5// //
6// Copyright (c) Guillaume Blanc //
7// //
8// Permission is hereby granted, free of charge, to any person obtaining a //
9// copy of this software and associated documentation files (the "Software"), //
10// to deal in the Software without restriction, including without limitation //
11// the rights to use, copy, modify, merge, publish, distribute, sublicense, //
12// and/or sell copies of the Software, and to permit persons to whom the //
13// Software is furnished to do so, subject to the following conditions: //
14// //
15// The above copyright notice and this permission notice shall be included in //
16// all copies or substantial portions of the Software. //
17// //
18// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR //
19// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //
20// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL //
21// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER //
22// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING //
23// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER //
24// DEALINGS IN THE SOFTWARE. //
25// //
26//----------------------------------------------------------------------------//
27
28#ifndef OZZ_OZZ_ANIMATION_RUNTIME_TRACK_TRIGGERING_JOB_H_
29#define OZZ_OZZ_ANIMATION_RUNTIME_TRACK_TRIGGERING_JOB_H_
30
31#include "ozz/animation/runtime/export.h"
32#include "ozz/base/platform.h"
33
34namespace ozz {
35namespace animation {
36
37class FloatTrack;
38
39// Track edge triggering job implementation. Edge triggering wording refers to
40// signal processing, where a signal edge is a transition from low to high or
41// from high to low. It is called an "edge" because of the square wave which
42// represents a signal has edges at those points. A rising edge is the
43// transition from low to high, a falling edge is from high to low.
44// TrackTriggeringJob detects when track curve crosses a threshold value,
45// triggering dated events that can be processed as state changes.
46// Only FloatTrack is supported, because comparing to a threshold for other
47// track types isn't possible.
48// The job execution actually performs a lazy evaluation of edges. It builds an
49// iterator that will process the next edge on each call to ++ operator.
50struct OZZ_ANIMATION_DLL TrackTriggeringJob {
52
53 // Validates job parameters.
54 bool Validate() const;
55
56 // Validates and executes job. Execution is lazy. Iterator operator ++ is
57 // actually doing the processing work.
58 bool Run() const;
59
60 // Input range. 0 is the beginning of the track, 1 is the end.
61 // from and to can be of any sign, any order, and any range. The job will
62 // perform accordingly:
63 // - if difference between from and to is greater than 1, the iterator will
64 // loop multiple times on the track.
65 // - if from is greater than to, then the track is processed backward (rising
66 // edges in forward become falling ones).
67 float from;
68 float to;
69
70 // Edge detection threshold value.
71 // A rising edge is detected as soon as the track value becomes greater than
72 // the threshold.
73 // A falling edge is detected as soon as the track value becomes smaller or
74 // equal than the threshold.
75 float threshold;
76
77 // Track to sample.
78 const FloatTrack* track;
79
80 // Job output iterator.
81 class Iterator;
82 Iterator* iterator;
83
84 // Returns an iterator referring to the past-the-end element. It should only
85 // be used to test if iterator loop reached the end (using operator !=), and
86 // shall not be dereferenced.
87 Iterator end() const;
88
89 // Structure of an edge as detected by the job.
90 struct Edge {
91 float ratio; // Ratio at which track value crossed threshold.
92 bool rising; // true is edge is rising (getting higher than threshold).
93 };
94};
95
96// Iterator implementation. Calls to ++ operator will compute the next edge. It
97// should be compared (using operator !=) to job's end iterator to test if the
98// last edge has been reached.
99class OZZ_ANIMATION_DLL TrackTriggeringJob::Iterator {
100 public:
101 Iterator() : job_(nullptr), outer_(0.f), inner_(0) {}
102
103 // Evaluate next edge.
104 // Calling this function on an end iterator results in an assertion in debug,
105 // an undefined behavior otherwise.
106 const Iterator& operator++();
107 Iterator operator++(int) {
108 Iterator prev = *this;
109 ++*this;
110 return prev;
111 }
112
113 // Compare with other iterators.
114 bool operator!=(const Iterator& _it) const {
115 return inner_ != _it.inner_ || outer_ != _it.outer_ || job_ != _it.job_;
116 }
117 bool operator==(const Iterator& _it) const {
118 return job_ == _it.job_ && outer_ == _it.outer_ && inner_ == _it.inner_;
119 }
120
121 // Dereferencing operators.
122 const Edge& operator*() const {
123 assert(*this != job_->end() && "Can't dereference end iterator.");
124 return edge_;
125 }
126 const Edge* operator->() const {
127 assert(*this != job_->end() && "Can't dereference end iterator.");
128 return &edge_;
129 }
130
131 private:
132 friend struct TrackTriggeringJob;
133
134 // Constructors used by the job.
135 explicit Iterator(const TrackTriggeringJob* _job);
136 struct End {};
137 Iterator(const TrackTriggeringJob* _job, End)
138 : job_(_job),
139 outer_(0.f),
140 inner_(-2) { // Can never be reached while looping.
141 }
142
143 // Job this iterator works on.
144 const TrackTriggeringJob* job_;
145
146 // Current value of the outer loop, aka a ratio cursor between from and to.
147 float outer_;
148
149 // Current value of the inner loop, aka a key frame index.
150 ptrdiff_t inner_;
151
152 // Latest evaluated edge.
153 Edge edge_;
154};
155
156// end() job function inline implementation.
157inline TrackTriggeringJob::Iterator TrackTriggeringJob::end() const {
158 return Iterator(this, Iterator::End());
159}
160} // namespace animation
161} // namespace ozz
162#endif // OZZ_OZZ_ANIMATION_RUNTIME_TRACK_TRIGGERING_JOB_H_
Definition track.h:154
Definition track_triggering_job.h:90
Definition track_triggering_job.h:50