svn merge -r39781:39792 https://svn.blender.org/svnroot/bf-blender/trunk/blender...
[blender-staging.git] / source / gameengine / Converter / BL_SkinDeformer.cpp
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 /** \file gameengine/Converter/BL_SkinDeformer.cpp
31  *  \ingroup bgeconv
32  */
33
34
35 #if defined(WIN32) && !defined(FREE_WINDOWS)
36 #pragma warning (disable : 4786)
37 #endif //WIN32
38
39 // Eigen2 stuff used for BGEDeformVerts
40 #include <Eigen/Core>
41 #include <Eigen/LU>
42
43 #include "BL_SkinDeformer.h"
44 #include "CTR_Map.h"
45 #include "STR_HashedString.h"
46 #include "RAS_IPolygonMaterial.h"
47 #include "RAS_MeshObject.h"
48
49 //#include "BL_ArmatureController.h"
50 #include "DNA_armature_types.h"
51 #include "DNA_action_types.h"
52 #include "DNA_mesh_types.h"
53 #include "DNA_meshdata_types.h"
54 #include "BLI_utildefines.h"
55 #include "BKE_armature.h"
56 #include "BKE_action.h"
57 #include "MT_Point3.h"
58
59 extern "C"{
60         #include "BKE_lattice.h"
61         #include "BKE_deform.h"
62 }
63  
64
65 #include "BLI_blenlib.h"
66 #include "BLI_math.h"
67
68 #define __NLA_DEFNORMALS
69 //#undef __NLA_DEFNORMALS
70
71 BL_SkinDeformer::BL_SkinDeformer(BL_DeformableGameObject *gameobj,
72                                                                 struct Object *bmeshobj, 
73                                                                 class RAS_MeshObject *mesh,
74                                                                 BL_ArmatureObject* arma)
75                                                         :       //
76                                                         BL_MeshDeformer(gameobj, bmeshobj, mesh),
77                                                         m_armobj(arma),
78                                                         m_lastArmaUpdate(-1),
79                                                         //m_defbase(&bmeshobj->defbase),
80                                                         m_releaseobject(false),
81                                                         m_poseApplied(false),
82                                                         m_recalcNormal(true),
83                                                         m_copyNormals(false),
84                                                         m_dfnrToPC(NULL)
85 {
86         copy_m4_m4(m_obmat, bmeshobj->obmat);
87 };
88
89 BL_SkinDeformer::BL_SkinDeformer(
90         BL_DeformableGameObject *gameobj,
91         struct Object *bmeshobj_old,    // Blender object that owns the new mesh
92         struct Object *bmeshobj_new,    // Blender object that owns the original mesh
93         class RAS_MeshObject *mesh,
94         bool release_object,
95         bool recalc_normal,
96         BL_ArmatureObject* arma)        :       
97                 BL_MeshDeformer(gameobj, bmeshobj_old, mesh),
98                 m_armobj(arma),
99                 m_lastArmaUpdate(-1),
100                 //m_defbase(&bmeshobj_old->defbase),
101                 m_releaseobject(release_object),
102                 m_recalcNormal(recalc_normal),
103                 m_copyNormals(false),
104                 m_dfnrToPC(NULL)
105         {
106                 // this is needed to ensure correct deformation of mesh:
107                 // the deformation is done with Blender's armature_deform_verts() function
108                 // that takes an object as parameter and not a mesh. The object matrice is used
109                 // in the calculation, so we must use the matrix of the original object to
110                 // simulate a pure replacement of the mesh.
111                 copy_m4_m4(m_obmat, bmeshobj_new->obmat);
112         }
113
114 BL_SkinDeformer::~BL_SkinDeformer()
115 {
116         if(m_releaseobject && m_armobj)
117                 m_armobj->Release();
118         if(m_dfnrToPC)
119                 delete [] m_dfnrToPC;
120 }
121
122 void BL_SkinDeformer::Relink(CTR_Map<class CTR_HashedPtr, void*>*map)
123 {
124         if (m_armobj) {
125                 void **h_obj = (*map)[m_armobj];
126
127                 if (h_obj)
128                         m_armobj = (BL_ArmatureObject*)(*h_obj);
129                 else
130                         m_armobj=NULL;
131         }
132
133         BL_MeshDeformer::Relink(map);
134 }
135
136 bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat)
137 {
138         RAS_MeshSlot::iterator it;
139         RAS_MeshMaterial *mmat;
140         RAS_MeshSlot *slot;
141         size_t i, nmat, imat;
142
143         // update the vertex in m_transverts
144         if (!Update())
145                 return false;
146
147         if (m_transverts) {
148                 // the vertex cache is unique to this deformer, no need to update it
149                 // if it wasn't updated! We must update all the materials at once
150                 // because we will not get here again for the other material
151                 nmat = m_pMeshObject->NumMaterials();
152                 for (imat=0; imat<nmat; imat++) {
153                         mmat = m_pMeshObject->GetMeshMaterial(imat);
154                         if(!mmat->m_slots[(void*)m_gameobj])
155                                 continue;
156
157                         slot = *mmat->m_slots[(void*)m_gameobj];
158
159                         // for each array
160                         for(slot->begin(it); !slot->end(it); slot->next(it)) {
161                                 // for each vertex
162                                 // copy the untransformed data from the original mvert
163                                 for(i=it.startvertex; i<it.endvertex; i++) {
164                                         RAS_TexVert& v = it.vertex[i];
165                                         v.SetXYZ(m_transverts[v.getOrigIndex()]);
166                                         if (m_copyNormals)
167                                                 v.SetNormal(m_transnors[v.getOrigIndex()]);
168                                 }
169                         }
170                 }
171
172                 if (m_copyNormals)
173                         m_copyNormals = false;
174         }
175         return true;
176 }
177
178 RAS_Deformer *BL_SkinDeformer::GetReplica()
179 {
180         BL_SkinDeformer *result;
181
182         result = new BL_SkinDeformer(*this);
183         /* there is m_armobj that must be fixed but we cannot do it now, it will be done in Relink */
184         result->ProcessReplica();
185         return result;
186 }
187
188 void BL_SkinDeformer::ProcessReplica()
189 {
190         BL_MeshDeformer::ProcessReplica();
191         m_lastArmaUpdate = -1;
192         m_releaseobject = false;
193         m_dfnrToPC = NULL;
194 }
195
196 void BL_SkinDeformer::BlenderDeformVerts()
197 {
198         float obmat[4][4];      // the original object matrix
199         Object* par_arma = m_armobj->GetArmatureObject();
200
201         // save matrix first
202         copy_m4_m4(obmat, m_objMesh->obmat);
203         // set reference matrix
204         copy_m4_m4(m_objMesh->obmat, m_obmat);
205
206         armature_deform_verts( par_arma, m_objMesh, NULL, m_transverts, NULL, m_bmesh->totvert, ARM_DEF_VGROUP, NULL, NULL );
207                 
208         // restore matrix 
209         copy_m4_m4(m_objMesh->obmat, obmat);
210
211 #ifdef __NLA_DEFNORMALS
212                 if (m_recalcNormal)
213                         RecalcNormals();
214 #endif
215 }
216
217 void BL_SkinDeformer::BGEDeformVerts()
218 {
219         Object *par_arma = m_armobj->GetArmatureObject();
220         MDeformVert *dverts = m_bmesh->dvert;
221         bDeformGroup *dg;
222         int numGroups = BLI_countlist(&m_objMesh->defbase);
223
224         if (!dverts)
225                 return;
226
227         if (m_dfnrToPC == NULL)
228         {
229                 m_dfnrToPC = new bPoseChannel*[numGroups];
230                 int i;
231                 for (i=0, dg=(bDeformGroup*)m_objMesh->defbase.first;
232                         dg;
233                         ++i, dg=(bDeformGroup*)dg->next)
234                 {
235                         m_dfnrToPC[i] = get_pose_channel(par_arma->pose, dg->name);
236
237                         if (m_dfnrToPC[i] && m_dfnrToPC[i]->bone->flag & BONE_NO_DEFORM)
238                                 m_dfnrToPC[i] = NULL;
239                 }
240         }
241
242
243         for (int i=0; i<m_bmesh->totvert; ++i)
244         {
245                 float contrib = 0.f, weight, max_weight=0.f;
246                 Bone *bone;
247                 bPoseChannel *pchan=NULL;
248                 MDeformVert *dvert;
249                 Eigen::Map<Eigen::Vector3f> norm(m_transnors[i]);
250                 Eigen::Vector4f vec(0, 0, 0, 1);
251                 Eigen::Matrix4f norm_chan_mat;
252                 Eigen::Vector4f co(m_transverts[i][0],
253                                                         m_transverts[i][1],
254                                                         m_transverts[i][2],
255                                                         1.f);
256
257                 dvert = dverts+i;
258
259                 if (!dvert->totweight)
260                         continue;
261
262                 for (int j=0; j<dvert->totweight; ++j)
263                 {
264                         int index = dvert->dw[j].def_nr;
265
266                         if (index < numGroups && (pchan=m_dfnrToPC[index]))
267                         {
268                                 weight = dvert->dw[j].weight;
269                                 bone = pchan->bone;
270
271                                 if (weight)
272                                 {
273                                         Eigen::Vector4f cop(co);
274                                         Eigen::Matrix4f chan_mat = Eigen::Matrix4f::Map((float*)pchan->chan_mat);
275
276                                         // Update Vertex Position
277                                         cop = chan_mat*cop;
278                                         vec += (cop - co)*weight;
279
280                                         // Save the most influential channel so we can use it to update the vertex normal
281                                         if (weight > max_weight)
282                                         {
283                                                 max_weight = weight;
284                                                 norm_chan_mat = chan_mat;
285                                         }
286
287                                         contrib += weight;
288                                 }
289                         }
290                 }
291
292                 
293                 // Update Vertex Normal
294                 norm = norm_chan_mat.corner<3, 3>(Eigen::TopLeft)*norm;
295                                 
296                 if (contrib > 0.0001f)
297                 {
298                         vec *= 1.f/contrib;
299                         co += vec;
300                 }
301
302                 m_transverts[i][0] = co[0];
303                 m_transverts[i][1] = co[1];
304                 m_transverts[i][2] = co[2];
305         }
306         m_copyNormals = true;
307 }
308
309 bool BL_SkinDeformer::UpdateInternal(bool shape_applied)
310 {
311         /* See if the armature has been updated for this frame */
312         if (PoseUpdated()){     
313
314                 if(!shape_applied) {
315                         /* store verts locally */
316                         VerifyStorage();
317                 
318                         /* duplicate */
319                         for (int v =0; v<m_bmesh->totvert; v++)
320                         {
321                                 VECCOPY(m_transverts[v], m_bmesh->mvert[v].co);
322                                 VECCOPY(m_transnors[v], m_bmesh->mvert[v].no);
323                         }
324                 }
325
326                 m_armobj->ApplyPose();
327
328                 switch (m_armobj->GetVertDeformType())
329                 {
330                         case ARM_VDEF_BGE_CPU:
331                                 BGEDeformVerts();
332                                 break;
333                         case ARM_VDEF_BLENDER:
334                         default:
335                                 BlenderDeformVerts();
336                 }
337
338                 /* Update the current frame */
339                 m_lastArmaUpdate=m_armobj->GetLastFrame();
340
341                 m_armobj->RestorePose();
342                 /* dynamic vertex, cannot use display list */
343                 m_bDynamic = true;
344                 /* indicate that the m_transverts and normals are up to date */
345                 return true;
346         }
347
348         return false;
349 }
350
351 bool BL_SkinDeformer::Update(void)
352 {
353         return UpdateInternal(false);
354 }
355
356 /* XXX note: I propose to drop this function */
357 void BL_SkinDeformer::SetArmature(BL_ArmatureObject *armobj)
358 {
359         // only used to set the object now
360         m_armobj = armobj;
361 }