Cleanup: remove redundant doxygen \file argument
[blender.git] / source / blender / collada / SkinInfo.cpp
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 \ingroup collada
18  */
19
20
21 #include <algorithm>
22
23 #if !defined(WIN32)
24 #include <stdint.h>
25 #endif
26
27 /* COLLADABU_ASSERT, may be able to remove later */
28 #include "COLLADABUPlatform.h"
29
30 #include "BLI_listbase.h"
31 #include "BLI_math.h"
32 #include "BLI_compiler_attrs.h"
33
34 #include "DNA_armature_types.h"
35 #include "DNA_modifier_types.h"
36 #include "DNA_scene_types.h"
37
38 #include "BKE_action.h"
39 #include "BKE_object.h"
40 #include "BKE_object_deform.h"
41
42 #include "ED_mesh.h"
43 #include "ED_object.h"
44
45 #include "SkinInfo.h"
46 #include "collada_utils.h"
47
48 // use name, or fall back to original id if name not present (name is optional)
49 template<class T>
50 static const char *bc_get_joint_name(T *node)
51 {
52         const std::string& id = node->getName();
53         return id.size() ? id.c_str() : node->getOriginalId().c_str();
54 }
55
56 // This is used to store data passed in write_controller_data.
57 // Arrays from COLLADAFW::SkinControllerData lose ownership, so do this class members
58 // so that arrays don't get freed until we free them explicitly.
59 SkinInfo::SkinInfo()
60 {
61         /* pass */
62 }
63
64 SkinInfo::SkinInfo(const SkinInfo& skin) : weights(skin.weights),
65         joint_data(skin.joint_data),
66         unit_converter(skin.unit_converter),
67         ob_arm(skin.ob_arm),
68         controller_uid(skin.controller_uid),
69         parent(skin.parent)
70 {
71         copy_m4_m4(bind_shape_matrix, (float (*)[4])skin.bind_shape_matrix);
72
73         transfer_uint_array_data_const(skin.joints_per_vertex, joints_per_vertex);
74         transfer_uint_array_data_const(skin.weight_indices, weight_indices);
75         transfer_int_array_data_const(skin.joint_indices, joint_indices);
76 }
77
78 SkinInfo::SkinInfo(UnitConverter *conv) : unit_converter(conv), ob_arm(NULL), parent(NULL) {
79 }
80
81 // nobody owns the data after this, so it should be freed manually with releaseMemory
82 template <class T>
83 void SkinInfo::transfer_array_data(T& src, T& dest)
84 {
85         dest.setData(src.getData(), src.getCount());
86         src.yieldOwnerShip();
87         dest.yieldOwnerShip();
88 }
89
90 // when src is const we cannot src.yieldOwnerShip, this is used by copy constructor
91 void SkinInfo::transfer_int_array_data_const(const COLLADAFW::IntValuesArray& src, COLLADAFW::IntValuesArray& dest)
92 {
93         dest.setData((int *)src.getData(), src.getCount());
94         dest.yieldOwnerShip();
95 }
96
97 void SkinInfo::transfer_uint_array_data_const(const COLLADAFW::UIntValuesArray& src, COLLADAFW::UIntValuesArray& dest)
98 {
99         dest.setData((unsigned int *)src.getData(), src.getCount());
100         dest.yieldOwnerShip();
101 }
102
103 void SkinInfo::borrow_skin_controller_data(const COLLADAFW::SkinControllerData *skin)
104 {
105         transfer_array_data((COLLADAFW::UIntValuesArray &)skin->getJointsPerVertex(), joints_per_vertex);
106         transfer_array_data((COLLADAFW::UIntValuesArray &)skin->getWeightIndices(), weight_indices);
107         transfer_array_data((COLLADAFW::IntValuesArray &)skin->getJointIndices(), joint_indices);
108         // transfer_array_data(skin->getWeights(), weights);
109
110         // cannot transfer data for FloatOrDoubleArray, copy values manually
111         const COLLADAFW::FloatOrDoubleArray& weight = skin->getWeights();
112         for (unsigned int i = 0; i < weight.getValuesCount(); i++)
113                 weights.push_back(bc_get_float_value(weight, i));
114
115         unit_converter->dae_matrix_to_mat4_(bind_shape_matrix, skin->getBindShapeMatrix());
116 }
117
118 void SkinInfo::free()
119 {
120         joints_per_vertex.releaseMemory();
121         weight_indices.releaseMemory();
122         joint_indices.releaseMemory();
123         // weights.releaseMemory();
124 }
125
126 // using inverse bind matrices to construct armature
127 // it is safe to invert them to get the original matrices
128 // because if they are inverse matrices, they can be inverted
129 void SkinInfo::add_joint(const COLLADABU::Math::Matrix4& matrix)
130 {
131         JointData jd;
132         unit_converter->dae_matrix_to_mat4_(jd.inv_bind_mat, matrix);
133         joint_data.push_back(jd);
134 }
135
136 void SkinInfo::set_controller(const COLLADAFW::SkinController *co)
137 {
138         controller_uid = co->getUniqueId();
139
140         // fill in joint UIDs
141         const COLLADAFW::UniqueIdArray& joint_uids = co->getJoints();
142         for (unsigned int i = 0; i < joint_uids.getCount(); i++) {
143                 joint_data[i].joint_uid = joint_uids[i];
144
145                 // // store armature pointer
146                 // JointData& jd = joint_index_to_joint_info_map[i];
147                 // jd.ob_arm = ob_arm;
148
149                 // now we'll be able to get inv bind matrix from joint id
150                 // joint_id_to_joint_index_map[joint_ids[i]] = i;
151         }
152 }
153
154 // called from write_controller
155 Object *SkinInfo::create_armature(Main *bmain, Scene *scene, ViewLayer *view_layer)
156 {
157         ob_arm = bc_add_object(bmain, scene, view_layer, OB_ARMATURE, NULL);
158         return ob_arm;
159 }
160
161 Object *SkinInfo::set_armature(Object *ob_arm)
162 {
163         if (this->ob_arm)
164                 return this->ob_arm;
165
166         this->ob_arm = ob_arm;
167         return ob_arm;
168 }
169
170 bool SkinInfo::get_joint_inv_bind_matrix(float inv_bind_mat[4][4], COLLADAFW::Node *node)
171 {
172         const COLLADAFW::UniqueId& uid = node->getUniqueId();
173         std::vector<JointData>::iterator it;
174         for (it = joint_data.begin(); it != joint_data.end(); it++) {
175                 if ((*it).joint_uid == uid) {
176                         copy_m4_m4(inv_bind_mat, (*it).inv_bind_mat);
177                         return true;
178                 }
179         }
180
181         return false;
182 }
183
184 Object *SkinInfo::BKE_armature_from_object()
185 {
186         return ob_arm;
187 }
188
189 const COLLADAFW::UniqueId& SkinInfo::get_controller_uid()
190 {
191         return controller_uid;
192 }
193
194 // check if this skin controller references a joint or any descendant of it
195 //
196 // some nodes may not be referenced by SkinController,
197 // in this case to determine if the node belongs to this armature,
198 // we need to search down the tree
199 bool SkinInfo::uses_joint_or_descendant(COLLADAFW::Node *node)
200 {
201         const COLLADAFW::UniqueId& uid = node->getUniqueId();
202         std::vector<JointData>::iterator it;
203         for (it = joint_data.begin(); it != joint_data.end(); it++) {
204                 if ((*it).joint_uid == uid)
205                         return true;
206         }
207
208         COLLADAFW::NodePointerArray& children = node->getChildNodes();
209         for (unsigned int i = 0; i < children.getCount(); i++) {
210                 if (uses_joint_or_descendant(children[i]))
211                         return true;
212         }
213
214         return false;
215 }
216
217 void SkinInfo::link_armature(bContext *C, Object *ob, std::map<COLLADAFW::UniqueId, COLLADAFW::Node *>& joint_by_uid,
218                              TransformReader *tm)
219 {
220         Main *bmain = CTX_data_main(C);
221         Scene *scene = CTX_data_scene(C);
222
223         ModifierData *md = ED_object_modifier_add(NULL, bmain, scene, ob, NULL, eModifierType_Armature);
224         ArmatureModifierData *amd = (ArmatureModifierData *)md;
225         amd->object = ob_arm;
226
227 #if 1
228         /* XXX Why do we enforce objects to be children of Armatures if they weren't so before ?*/
229         if (!BKE_object_is_child_recursive(ob_arm, ob)) {
230                 bc_set_parent(ob, ob_arm, C);
231         }
232 #else
233         Object workob;
234         ob->parent = ob_arm;
235         ob->partype = PAROBJECT;
236
237         BKE_object_workob_calc_parent(scene, ob, &workob);
238         invert_m4_m4(ob->parentinv, workob.obmat);
239
240         DEG_id_tag_update(&obn->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
241 #endif
242         copy_m4_m4(ob->obmat, bind_shape_matrix);
243         BKE_object_apply_mat4(ob, ob->obmat, 0, 0);
244
245         amd->deformflag = ARM_DEF_VGROUP;
246
247         // create all vertex groups
248         std::vector<JointData>::iterator it;
249         int joint_index;
250         for (it = joint_data.begin(), joint_index = 0; it != joint_data.end(); it++, joint_index++) {
251                 const char *name = "Group";
252
253                 // skip joints that have invalid UID
254                 if ((*it).joint_uid == COLLADAFW::UniqueId::INVALID) continue;
255
256                 // name group by joint node name
257
258                 if (joint_by_uid.find((*it).joint_uid) != joint_by_uid.end()) {
259                         name = bc_get_joint_name(joint_by_uid[(*it).joint_uid]);
260                 }
261
262                 BKE_object_defgroup_add_name(ob, name);
263         }
264
265         // <vcount> - number of joints per vertex - joints_per_vertex
266         // <v> - [[bone index, weight index] * joints per vertex] * vertices - weight indices
267         // ^ bone index can be -1 meaning weight toward bind shape, how to express this in Blender?
268
269         // for each vertex in weight indices
270         //      for each bone index in vertex
271         //              add vertex to group at group index
272         //              treat group index -1 specially
273
274         // get def group by index with BLI_findlink
275
276         for (unsigned int vertex = 0, weight = 0; vertex < joints_per_vertex.getCount(); vertex++) {
277
278                 unsigned int limit = weight + joints_per_vertex[vertex];
279                 for (; weight < limit; weight++) {
280                         int joint = joint_indices[weight], joint_weight = weight_indices[weight];
281
282                         // -1 means "weight towards the bind shape", we just don't assign it to any group
283                         if (joint != -1) {
284                                 bDeformGroup *def = (bDeformGroup *)BLI_findlink(&ob->defbase, joint);
285
286                                 ED_vgroup_vert_add(ob, def, vertex, weights[joint_weight], WEIGHT_REPLACE);
287                         }
288                 }
289         }
290 }
291
292 bPoseChannel *SkinInfo::get_pose_channel_from_node(COLLADAFW::Node *node)
293 {
294         return BKE_pose_channel_find_name(ob_arm->pose, bc_get_joint_name(node));
295 }
296
297 void SkinInfo::set_parent(Object *_parent)
298 {
299         parent = _parent;
300 }
301
302 Object *SkinInfo::get_parent()
303 {
304         return parent;
305 }
306
307 void SkinInfo::find_root_joints(const std::vector<COLLADAFW::Node *> &root_joints,
308                                 std::map<COLLADAFW::UniqueId, COLLADAFW::Node *>& joint_by_uid,
309                                 std::vector<COLLADAFW::Node *>& result)
310 {
311         std::vector<COLLADAFW::Node *>::const_iterator it;
312         // for each root_joint
313         for (it = root_joints.begin(); it != root_joints.end(); it++) {
314                 COLLADAFW::Node *root = *it;
315                 std::vector<JointData>::iterator ji;
316                 //for each joint_data in this skin
317                 for (ji = joint_data.begin(); ji != joint_data.end(); ji++) {
318                         if (joint_by_uid.find((*ji).joint_uid) != joint_by_uid.end()) {
319                                 //get joint node from joint map
320                                 COLLADAFW::Node *joint = joint_by_uid[(*ji).joint_uid];
321
322                                 //find if joint node is in the tree belonging to the root_joint
323                                 if (find_node_in_tree(joint, root)) {
324                                         if (std::find(result.begin(), result.end(), root) == result.end())
325                                                 result.push_back(root);
326                                 }
327                         }
328                 }
329         }
330 }
331
332 bool SkinInfo::find_node_in_tree(COLLADAFW::Node *node, COLLADAFW::Node *tree_root)
333 {
334         if (node == tree_root)
335                 return true;
336
337         COLLADAFW::NodePointerArray& children = tree_root->getChildNodes();
338         for (unsigned int i = 0; i < children.getCount(); i++) {
339                 if (find_node_in_tree(node, children[i]))
340                         return true;
341         }
342
343         return false;
344 }