OpenShot Library | libopenshot  0.1.9
KeyFrame.h
Go to the documentation of this file.
1 /**
2  * @file
3  * @brief Header file for the Keyframe class
4  * @author Jonathan Thomas <jonathan@openshot.org>
5  *
6  * @section LICENSE
7  *
8  * Copyright (c) 2008-2014 OpenShot Studios, LLC
9  * <http://www.openshotstudios.com/>. This file is part of
10  * OpenShot Library (libopenshot), an open-source project dedicated to
11  * delivering high quality video editing and animation solutions to the
12  * world. For more information visit <http://www.openshot.org/>.
13  *
14  * OpenShot Library (libopenshot) is free software: you can redistribute it
15  * and/or modify it under the terms of the GNU Lesser General Public License
16  * as published by the Free Software Foundation, either version 3 of the
17  * License, or (at your option) any later version.
18  *
19  * OpenShot Library (libopenshot) is distributed in the hope that it will be
20  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public License
25  * along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
26  */
27 
28 #ifndef OPENSHOT_KEYFRAME_H
29 #define OPENSHOT_KEYFRAME_H
30 
31 #include <iostream>
32 #include <iomanip>
33 #include <math.h>
34 #include <assert.h>
35 #include <vector>
36 #include "Exceptions.h"
37 #include "Fraction.h"
38 #include "Coordinate.h"
39 #include "Point.h"
40 #include "Json.h"
41 
42 using namespace std;
43 using namespace openshot;
44 
45 namespace openshot {
46 
47  /**
48  * @brief A Keyframe is a collection of Point instances, which is used to vary a number or property over time.
49  *
50  * Keyframes are used to animate and interpolate values of properties over time. For example, a single property
51  * can use a Keyframe instead of a constant value. Assume you want to slide an image (from left to right) over
52  * a video. You can create a Keyframe which will adjust the X value of the image over 100 frames (or however many
53  * frames the animation needs to last) from the value of 0 to 640.
54  *
55  * Please see the following <b>Example Code</b>:
56  * \code
57  * Keyframe k1;
58  * k1.AddPoint(Point(1,0));
59  * k1.AddPoint(Point(100,640));
60  *
61  * kf.PrintValues();
62  * \endcode
63  */
64  class Keyframe {
65  private:
66  bool needs_update;
67  double FactorialLookup[4];
68 
69  /*
70  * Because points can be added in any order, we need to reorder them
71  * in ascending order based on the point.co.X value. This simplifies
72  * processing the curve, due to all the points going from left to right.
73  */
74  void ReorderPoints();
75 
76  // Process an individual segment
77  void ProcessSegment(int Segment, Point p1, Point p2);
78 
79  // create lookup table for fast factorial calculation
80  void CreateFactorialTable();
81 
82  // Get a factorial for a coordinate
83  double Factorial(int64_t n);
84 
85  // Calculate the factorial function for Bernstein basis
86  double Ni(int64_t n, int64_t i);
87 
88  // Calculate Bernstein Basis
89  double Bernstein(int64_t n, int64_t i, double t);
90 
91  public:
92  vector<Point> Points; ///< Vector of all Points
93  vector<Coordinate> Values; ///< Vector of all Values (i.e. the processed coordinates from the curve)
94 
95  /// Default constructor for the Keyframe class
96  Keyframe();
97 
98  /// Constructor which sets the default point & coordinate at X=0
99  Keyframe(double value);
100 
101  /// Add a new point on the key-frame. Each point has a primary coordinate, a left handle, and a right handle.
102  void AddPoint(Point p);
103 
104  /// Add a new point on the key-frame, with some defaults set (BEZIER)
105  void AddPoint(double x, double y);
106 
107  /// Add a new point on the key-frame, with a specific interpolation type
108  void AddPoint(double x, double y, InterpolationType interpolate);
109 
110  /// Does this keyframe contain a specific point
111  bool Contains(Point p);
112 
113  /// Flip all the points in this openshot::Keyframe (useful for reversing an effect or transition, etc...)
114  void FlipPoints();
115 
116  /// Get the index of a point by matching a coordinate
117  int64_t FindIndex(Point p);
118 
119  /// Get the value at a specific index
120  double GetValue(int64_t index);
121 
122  /// Get the rounded INT value at a specific index
123  int GetInt(int64_t index);
124 
125  /// Get the rounded LONG value at a specific index
126  int64_t GetLong(int64_t index);
127 
128  /// Get the fraction that represents how many times this value is repeated in the curve
129  Fraction GetRepeatFraction(int64_t index);
130 
131  /// Get the change in Y value (from the previous Y value)
132  double GetDelta(int64_t index);
133 
134  /// Get a point at a specific index
135  Point& GetPoint(int64_t index);
136 
137  /// Get current point (or closest point to the right) from the X coordinate (i.e. the frame number)
138  Point GetClosestPoint(Point p);
139 
140  /// Get current point (or closest point) from the X coordinate (i.e. the frame number)
141  /// Either use the closest left point, or right point
142  Point GetClosestPoint(Point p, bool useLeft);
143 
144  /// Get previous point (
145  Point GetPreviousPoint(Point p);
146 
147  /// Get max point (by Y coordinate)
148  Point GetMaxPoint();
149 
150  // Get the number of values (i.e. coordinates on the X axis)
151  int64_t GetLength();
152 
153  /// Get the number of points (i.e. # of points)
154  int64_t GetCount();
155 
156  /// Get the direction of the curve at a specific index (increasing or decreasing)
157  bool IsIncreasing(int index);
158 
159  /// Get and Set JSON methods
160  string Json(); ///< Generate JSON string of this object
161  Json::Value JsonValue(); ///< Generate Json::JsonValue for this object
162  void SetJson(string value); ///< Load JSON string into this object
163  void SetJsonValue(Json::Value root); ///< Load Json::JsonValue into this object
164 
165  /**
166  * @brief Calculate all of the values for this keyframe.
167  *
168  * This clears any existing data in the "values" vector. This method is automatically called
169  * by AddPoint(), so you don't typically need to call this method.
170  */
171  void Process();
172 
173  /// Remove a point by matching a coordinate
174  void RemovePoint(Point p);
175 
176  /// Remove a point by index
177  void RemovePoint(int64_t index);
178 
179  /// Scale all points by a percentage (good for evenly lengthening or shortening an openshot::Keyframe)
180  /// 1.0 = same size, 1.05 = 5% increase, etc...
181  void ScalePoints(double scale);
182 
183  /// Replace an existing point with a new point
184  void UpdatePoint(int64_t index, Point p);
185 
186  /// Print a list of points
187  void PrintPoints();
188 
189  /// Print just the Y value of the point's primary coordinate
190  void PrintValues();
191 
192  };
193 
194 }
195 
196 #endif
vector< Coordinate > Values
Vector of all Values (i.e. the processed coordinates from the curve)
Definition: KeyFrame.h:93
Header file for Fraction class.
Header file for Point class.
A Point is the basic building block of a key-frame curve.
Definition: Point.h:81
Header file for all Exception classes.
Header file for JSON class.
This class represents a fraction.
Definition: Fraction.h:42
vector< Point > Points
Vector of all Points.
Definition: KeyFrame.h:92
InterpolationType
This controls how a Keyframe uses this point to interpolate between two points.
Definition: Point.h:45
This namespace is the default namespace for all code in the openshot library.
Header file for Coordinate class.
A Keyframe is a collection of Point instances, which is used to vary a number or property over time...
Definition: KeyFrame.h:64