1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 /** \file
18  * \ingroup collada
19  */
20 
21 #pragma once
22 
23 #include <map>
24 #include <vector>
25 
26 #include "COLLADAFWAnimation.h"
27 #include "COLLADAFWAnimationCurve.h"
28 #include "COLLADAFWAnimationList.h"
29 #include "COLLADAFWCamera.h"
30 #include "COLLADAFWEffect.h"
31 #include "COLLADAFWInstanceGeometry.h"
32 #include "COLLADAFWLight.h"
33 #include "COLLADAFWMaterial.h"
34 #include "COLLADAFWNode.h"
35 #include "COLLADAFWUniqueId.h"
36 
37 #include "BKE_context.h"
38 
39 #include "DNA_anim_types.h"
40 
41 #include "DNA_camera_types.h"
42 #include "DNA_light_types.h"
43 #include "DNA_object_types.h"
44 #include "DNA_scene_types.h"
45 
46 //#include "ArmatureImporter.h"
47 #include "TransformReader.h"
48 
49 #include "collada_internal.h"
50 
51 class ArmatureImporter;
52 
53 class AnimationImporterBase {
54  public:
55   /* virtual void change_eul_to_quat(Object *ob, bAction *act) = 0; */
56 };
57 
58 class AnimationImporter : private TransformReader, public AnimationImporterBase {
59  private:
60   bContext *mContext;
61   ArmatureImporter *armature_importer;
62   Scene *scene;
63 
64   std::map<COLLADAFW::UniqueId, std::vector<FCurve *>> curve_map;
65   std::map<COLLADAFW::UniqueId, TransformReader::Animation> uid_animated_map;
66   // std::map<bActionGroup*, std::vector<FCurve*> > fcurves_actionGroup_map;
67   std::map<COLLADAFW::UniqueId, const COLLADAFW::AnimationList *> animlist_map;
68   std::vector<FCurve *> unused_curves;
69   std::map<COLLADAFW::UniqueId, Object *> joint_objects;
70 
71   FCurve *create_fcurve(int array_index, const char *rna_path);
72 
73   void add_bezt(FCurve *fcu,
74                 float frame,
75                 float value,
76                 eBezTriple_Interpolation ipo = BEZT_IPO_LIN);
77 
78   /* create one or several fcurves depending on the number of parameters being animated */
79   void animation_to_fcurves(COLLADAFW::AnimationCurve *curve);
80 
81   void fcurve_deg_to_rad(FCurve *cu);
82   void fcurve_scale(FCurve *cu, int scale);
83 
84   void fcurve_is_used(FCurve *fcu);
85 
86   void add_fcurves_to_object(Main *bmain,
87                              Object *ob,
88                              std::vector<FCurve *> &curves,
89                              char *rna_path,
90                              int array_index,
91                              Animation *animated);
92 
93   int typeFlag;
94 
95   std::string import_from_version;
96 
97   enum lightAnim {
98     //      INANIMATE = 0,
99     LIGHT_COLOR = 2,
100     LIGHT_FOA = 4,
101     LIGHT_FOE = 8,
102   };
103 
104   enum cameraAnim {
105     //      INANIMATE = 0,
106     CAMERA_XFOV = 2,
107     CAMERA_XMAG = 4,
108     CAMERA_YFOV = 8,
109     CAMERA_YMAG = 16,
110     CAMERA_ZFAR = 32,
111     CAMERA_ZNEAR = 64,
112   };
113 
114   enum matAnim {
115     MATERIAL_SHININESS = 2,
116     MATERIAL_SPEC_COLOR = 4,
117     MATERIAL_DIFF_COLOR = 1 << 3,
118     MATERIAL_TRANSPARENCY = 1 << 4,
119     MATERIAL_IOR = 1 << 5,
120   };
121 
122   enum AnimationType {
123     BC_INANIMATE = 0,
124     BC_NODE_TRANSFORM = 1,
125   };
126 
127   struct AnimMix {
128     int transform;
129     int light;
130     int camera;
131     int material;
132     int texture;
133   };
134 
135  public:
AnimationImporter(bContext * C,UnitConverter * conv,ArmatureImporter * arm,Scene * scene)136   AnimationImporter(bContext *C, UnitConverter *conv, ArmatureImporter *arm, Scene *scene)
137       : TransformReader(conv), mContext(C), armature_importer(arm), scene(scene)
138   {
139   }
140 
141   ~AnimationImporter();
142 
143   void set_import_from_version(std::string import_from_version);
144   bool write_animation(const COLLADAFW::Animation *anim);
145 
146   /* called on post-process stage after writeVisualScenes */
147   bool write_animation_list(const COLLADAFW::AnimationList *animlist);
148 
149   void read_node_transform(COLLADAFW::Node *node, Object *ob);
150 #if 0
151   virtual void change_eul_to_quat(Object *ob, bAction *act);
152 #endif
153 
154   void translate_Animations(COLLADAFW::Node *Node,
155                             std::map<COLLADAFW::UniqueId, COLLADAFW::Node *> &root_map,
156                             std::multimap<COLLADAFW::UniqueId, Object *> &object_map,
157                             std::map<COLLADAFW::UniqueId, const COLLADAFW::Object *> FW_object_map,
158                             std::map<COLLADAFW::UniqueId, Material *> uid_material_map);
159 
160   AnimMix *get_animation_type(
161       const COLLADAFW::Node *node,
162       std::map<COLLADAFW::UniqueId, const COLLADAFW::Object *> FW_object_map);
163 
164   void apply_matrix_curves(Object *ob,
165                            std::vector<FCurve *> &animcurves,
166                            COLLADAFW::Node *root,
167                            COLLADAFW::Node *node,
168                            COLLADAFW::Transformation *tm);
169 
170   void add_bone_animation_sampled(Object *ob,
171                                   std::vector<FCurve *> &animcurves,
172                                   COLLADAFW::Node *root,
173                                   COLLADAFW::Node *node,
174                                   COLLADAFW::Transformation *tm);
175 
176   void Assign_transform_animations(COLLADAFW::Transformation *transform,
177                                    const COLLADAFW::AnimationList::AnimationBinding *binding,
178                                    std::vector<FCurve *> *curves,
179                                    bool is_joint,
180                                    char *joint_path);
181 
182   void Assign_color_animations(const COLLADAFW::UniqueId &listid,
183                                ListBase *AnimCurves,
184                                const char *anim_type);
185   void Assign_float_animations(const COLLADAFW::UniqueId &listid,
186                                ListBase *AnimCurves,
187                                const char *anim_type);
188   void Assign_lens_animations(const COLLADAFW::UniqueId &listid,
189                               ListBase *AnimCurves,
190                               const double aspect,
191                               Camera *cam,
192                               const char *anim_type,
193                               int fov_type);
194 
195   int setAnimType(const COLLADAFW::Animatable *prop, int type, int addition);
196 
197   void modify_fcurve(std::vector<FCurve *> *curves,
198                      const char *rna_path,
199                      int array_index,
200                      int scale = 1);
201   void unused_fcurve(std::vector<FCurve *> *curves);
202   /* prerequisites:
203    * animlist_map - map animlist id -> animlist
204    * curve_map - map anim id -> curve(s) */
205   Object *translate_animation_OLD(COLLADAFW::Node *node,
206                                   std::map<COLLADAFW::UniqueId, Object *> &object_map,
207                                   std::map<COLLADAFW::UniqueId, COLLADAFW::Node *> &root_map,
208                                   COLLADAFW::Transformation::TransformationType tm_type,
209                                   Object *par_job = NULL);
210 
211   void find_frames(std::vector<float> *frames, std::vector<FCurve *> *curves);
212   void find_frames_old(std::vector<float> *frames,
213                        COLLADAFW::Node *node,
214                        COLLADAFW::Transformation::TransformationType tm_type);
215   /* internal, better make it private
216    * warning: evaluates only rotation
217    * prerequisites: animlist_map, curve_map */
218   void evaluate_transform_at_frame(float mat[4][4], COLLADAFW::Node *node, float fra);
219 
220   /* return true to indicate that mat contains a sane value */
221   bool evaluate_animation(COLLADAFW::Transformation *tm,
222                           float mat[4][4],
223                           float fra,
224                           const char *node_id);
225 
226   /* gives a world-space mat of joint at rest position */
227   void get_joint_rest_mat(float mat[4][4], COLLADAFW::Node *root, COLLADAFW::Node *node);
228 
229   /* gives a world-space mat, end's mat not included */
230   bool calc_joint_parent_mat_rest(float mat[4][4],
231                                   float par[4][4],
232                                   COLLADAFW::Node *node,
233                                   COLLADAFW::Node *end);
234 
235   float convert_to_focal_length(float in_xfov, int fov_type, float aspect, float sensorx);
236 
237 #ifdef ARMATURE_TEST
238   Object *get_joint_object(COLLADAFW::Node *root, COLLADAFW::Node *node, Object *par_job);
239 #endif
240 
241 #if 0
242   /* recursively evaluates joint tree until end is found, mat then is world-space matrix of end
243    * mat must be identity on enter, node must be root */
244   bool evaluate_joint_world_transform_at_frame(
245       float mat[4][4], float par[4][4], COLLADAFW::Node *node, COLLADAFW::Node *end, float fra);
246 #endif
247 
248   void add_bone_fcurve(Object *ob, COLLADAFW::Node *node, FCurve *fcu);
249 
250   void extra_data_importer(std::string elementName);
251 };
252