synfig-core  1.0.3
bone.h
Go to the documentation of this file.
1 /* === S Y N F I G ========================================================= */
22 /* ========================================================================= */
23 
24 /* === S T A R T =========================================================== */
25 
26 #ifndef __SYNFIG_BONE_H
27 #define __SYNFIG_BONE_H
28 
29 /* === H E A D E R S ======================================================= */
30 #include <iostream>
31 #include "matrix.h"
32 #include "uniqueid.h"
33 #include "string.h"
34 #include "guid.h"
35 #include <vector>
36 #include <ETL/handle>
37 
38 /* === M A C R O S ========================================================= */
39 
40 // how many hex digits of the guid string to show in debug messages
41 #define GUID_PREFIX_LEN 6
42 
43 #define COUT_BONE(bone) \
44  cout<<"[name]="<<bone.name_<<endl; \
45  cout<<"[origin]="<<bone.origin_<<endl; \
46  cout<<"[angle]="<<bone.angle_<<endl; \
47  cout<<"[scalelx]="<<bone.scalelx_<<endl; \
48  cout<<"[scalex]="<<bone.scalex_<<endl; \
49  cout<<"[length]="<<bone.length_<<endl; \
50  cout<<"[width]="<<bone.width_<<endl; \
51  cout<<"[tipwidth]="<<bone.tipwidth_<<endl; \
52  cout<<"[depth]="<<bone.depth_<<endl; \
53  cout<<"[parent]="<<bone.parent_<<endl
54 
55 /* === T Y P E D E F S ===================================================== */
56 
57 /* === C L A S S E S & S T R U C T S ======================================= */
58 namespace synfig {
59 
60 class ValueNode_Bone;
61 
62 class Bone: public UniqueID
63 {
64  /*
65  -- ** -- T Y P E S -----------------------------------------------------------
66  */
67 
68 public:
69  typedef etl::handle<Bone> Handle;
70 
71  struct Shape {
76  inline Shape():
77  r0(0.0), r1(0.0) { }
78  inline Shape(const Vector &p0, Real r0, const Vector &p1, Real r1):
79  p0(p0), r0(r0), p1(p1), r1(r1) { }
80  };
81 
82  // typedef etl::loose_handle<Bone> LooseHandle;
83 
84  /*
85  -- ** -- D A T A -------------------------------------------------------------
86  */
87 
88 private:
90  String name_;
92  Point origin_;
94  Angle angle_;
96  Real scalelx_;
98  Real scalex_;
100  Real length_;
102  Real width_;
104  Real tipwidth_;
106  Real depth_;
108  const ValueNode_Bone* parent_;
109 
110  Matrix animated_matrix_;
111 
112 public:
114  Bone();
116  Bone(const Point &origin, const Point &tip);
118  Bone(const String &name, const Point &origin, const Angle &angle, const Real &length, ValueNode_Bone* p=0);
120  const String& get_name()const {return name_;}
121  void set_name(const String &x) {name_=x;}
122 
124  const Point& get_origin()const {return origin_;}
125  void set_origin(const Point &x) {origin_=x;}
126 
128  const Angle& get_angle()const {return angle_;}
129  void set_angle(const Angle &x) {angle_=x;}
130 
132  const Real& get_scalelx()const {return scalelx_;}
133  void set_scalelx(const Real &x) {scalelx_=x;}
134 
136  const Real& get_scalex()const {return scalex_;}
137  void set_scalex(const Real &x) {scalex_=x;}
138 
140  const Real& get_length()const {return length_;}
141  void set_length(const Real &x) {length_=x<0.00001?0.00001:x;}
142 
144  const Real& get_width()const {return width_;}
145  void set_width(const Real &x) {width_=x;}
146 
148  const Real& get_tipwidth()const {return tipwidth_;}
149  void set_tipwidth(const Real &x) {tipwidth_=x;}
150 
152  const Real& get_depth()const {return depth_;}
153  void set_depth(const Real &x) {depth_=x;}
154 
157  Point get_tip();
158 
160  // const Bone &get_parent() {return *parent_;}
161  const ValueNode_Bone* get_parent()const;
162  void set_parent(const ValueNode_Bone* parent);
163 
164  void add_bone_to_map();
165  Bone* find_bone_in_map(int uid);
166 
173  Matrix get_animated_matrix() const { return animated_matrix_; }
174  void set_animated_matrix(Matrix x) { animated_matrix_ = x; }
175 
176  Vector get_local_scale() const { return Vector(scalelx_, 1.0); }
177 
181  synfig::String get_string()const;
182 
183  bool is_root()const;
184 
185  Shape get_shape() const;
186 
187  static Real distance_to_shape_center_percent(const Shape &shape, const Vector &x);
188  static Real influence_function(Real distance_percent);
189 
190  static Real influence_percent(const Shape &shape, const Vector &x)
192 
195 
197  { return influence_percent(get_shape(), x); }
198 
199  // checks if point belongs to the range of influence of current bone
200  bool have_influence_on(const Vector &x)const
201  { return distance_to_shape_center_percent(x) > 0.0; }
202 }; // END of class Bone
203 
204 }; // END of namespace synfig
205 /* === E N D =============================================================== */
206 
207 #endif
208 /*
209  * Alternative to Bone *parent_
210  * ======================================================================
211  * I think that we can leave the bone as a simple information holder
212  * and only give it the responsibility of:
213  * Set and get:
214  * -origin,
215  * -angle,
216  * -scalelx,
217  * -scalely,
218  * -scalex,
219  * -scaley,
220  * -length
221  * -strength,
222  * -ParentID: this is new: This is the UniqueID value of the parent bone.
223  * Initially it is set to a non valid number (I think that -1 is fine)
224  * so it means that it is a root bone. Later an external object can set it
225  * to a valid UniqueID to mean that that's the parent ID.
226  * parent_tree is not needed.
227  * -Skeletons Pointer (see below)
228  * Also the bone should:
229  * -get_animated_matrix
230  * -get_tip
231  *
232  * Then it comes the concept of ValueNode_Skeletons. The Skeletons (notice that
233  * it is plural because there can be more than one root bone) is like the ValueNode_Bline,
234  * a linkable value.
235  * It is like a normal list of bones (like bline is a normal list of blinepoints).
236  * This list of bones has just that, bones. So the skeleton is not an expandable tree with
237  * a potential loop problem; it is just a list of objects.
238  *
239  * The ValueNode_Skeletons is responsible for:
240  * 1) Calculate the complete setup matrix of a bone based on the hierarchy
241  * 2) Calculate the complete animated matrix of a bone based on the hierarchy
242  * 3) (Re)Parent a bone. Or (Un)Parent it
243  * 4) Remove the bone from the list. It would set the parent UniqueID=-1 and the Skeletons
244  * pointer to be 0.
245  * 5) Add a new bone to the list. The bone constructor would receive a Skeleton pointer and
246  * eventually a parent UniqueID besides the rest of information to fill the date (origin, etc.).
247  *
248  * It would look like that:
249  *
250  * ValueNode_Skeletons
251  * ValueNode_Bone Bone1
252  * ValueNode_Bone Bone2
253  * ...
254  * ValueNode_Bone BoneN
255  *
256  * To perform the tasks 1), 2), 3) or 4) the ValueNode_Skeletons should perform a seek into the
257  * list of bones by its UniqueID value. For example to calcualte the setup matrix it should
258  * reconstruct the bone hierarchy from the current bone to the root parent. Due to that now,
259  * it is only stored the UniqueID of the parent (and not a pointer), it is the skeletons veluenode
260  * who have to perform all the job: find all the parents and multiply in the correct order (depth) its
261  * matrixes. The same happen for the animated matrix.
262  * For reparent it is the same. It is just a modification of the parent UniqueID.
263  * Remove a bone from the list would imply remove all its children from the list. A warning should be triggered.
264  * A bone that has a null pointer to Skeletons means that it is orphaned completely. Its parent UniqueID
265  * must be -1 in that case. Anyway the bone like that can be used again in other skeleton. Just need to
266  * insert it in the Skeletons list by modifying the Skeletons pointer and filling the proper parent UniqueID.
267  * The Skeletons pointer is not an animatable ValueNode. It can be a Handle if you like. The parent
268  * UniqueID can be animatable.
269  * In this way every computation is slower but would be easier to define, visible to the user
270  * and more consistent with the ValueNode concept.
271  *
272  * This variation of concept doesn't imply anything new in the ValueNode_VertexBone.
273  * So the ValueNode_VertexBone should look like:
274  *
275  * ValueNode_VertexBone
276  * Vertex Free
277  * Vertex Setup
278  * ValueNode_DynamicList Bone_weight_pairs
279  * BoneWeightPair
280  * ValueNode_Bone Bone
281  * Real Weight
282  *
283  * As well as the Bone having a pointer to the Skeletons it is possible for the VertexBone_ValueNode
284  * to calculate the weighted matrixes as stated in the wiki. It just has to retrieve the
285  * ValueNode_Skeleton and ask it to perform the known tasks. Later the ValueNode_VertexBone
286  * would do the weight calculation.
287  *
288  * How does it look?
289  */