Motive Animation System
An open source project by FPL.
 All Classes Functions Variables Typedefs Friends Pages
util.h
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef MOTIVE_UTIL_H_
16 #define MOTIVE_UTIL_H_
17 
18 #include "motive/motivator.h"
19 #include "motive/target.h"
20 
21 namespace motive {
22 
23 /// Direction to boost the value.
24 enum TwitchDirection {
25  kTwitchDirectionNone, /// Do nothing.
26  kTwitchDirectionPositive, /// Give the velocity a positive boost.
27  kTwitchDirectionNegative /// Give the velocity a negative boost.
28 };
29 
30 /// @class Settled1f
31 /// @brief Helper to determine if we're "at the target" and "stopped".
32 struct Settled1f {
33  Settled1f() : max_difference(0.0f), max_velocity(0.0f) {}
34 
35  /// Return true if our distance from target is and velocity are less than
36  /// this class' threshold.
37  bool Settled(float dist, float velocity) const {
38  return fabs(dist) <= max_difference && fabs(velocity) <= max_velocity;
39  }
40 
41  /// Return true if `motivator` is "at the target" and "stopped".
42  template <class Motivator>
43  bool Settled(const Motivator& motivator) const {
44  float differences[Motivator::kDimensions];
45  float velocities[Motivator::kDimensions];
46  motivator.Differences(differences);
47  motivator.Velocities(velocities);
48  for (int i = 0; i < Motivator::kDimensions; ++i) {
49  if (!Settled(differences[i], velocities[i])) return false;
50  }
51  return true;
52  }
53 
54  /// Consider ourselves "at the target" if the absolute difference between
55  /// the value and the target is less than this.
57 
58  /// Consider ourselves "stopped" if the absolute velocity is less than this.
59  float max_velocity;
60 };
61 
62 template <>
63 inline bool Settled1f::Settled<Motivator1f>(const Motivator1f& motivator)
64  const {
65  return Settled(motivator.Difference(), motivator.Velocity());
66 }
67 
68 /// If `motivator` is "at the target" and "stopped" give it a boost in
69 /// `direction`.
70 ///
71 /// A little boost is useful to demonstrate responsiveness to user input,
72 /// even when you can't logically change to a new state. A slight boost that
73 /// then settles back to its original value (via an OvershootMotivator, for
74 /// example) looks and feels correct.
75 inline void Twitch(TwitchDirection direction, float velocity,
76  const Settled1f& settled, Motivator1f* motivator) {
77  if (direction != kTwitchDirectionNone && settled.Settled(*motivator)) {
78  motivator->SetTarget(Current1f(
79  motivator->Value(),
80  direction == kTwitchDirectionPositive ? velocity : -velocity));
81  }
82 }
83 
84 } // namespace motive
85 
86 #endif // MOTIVE_UTIL_H_
bool Settled(const Motivator &motivator) const
Return true if motivator is "at the target" and "stopped".
Definition: util.h:43
float max_velocity
Consider ourselves "stopped" if the absolute velocity is less than this.
Definition: util.h:59
bool Settled(float dist, float velocity) const
Definition: util.h:37
Helper to determine if we're "at the target" and "stopped".
Definition: util.h:32
Drives a value towards a target value, or along a path.
Definition: motivator.h:47
float max_difference
Definition: util.h:56
Animate a vector of floating-point values.
Definition: motivator.h:365