svn merge -r 15292:15392 https://svn.blender.org/svnroot/bf-blender/trunk/blender
[blender.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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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 #ifdef WIN32
31 #pragma warning (disable : 4786)
32 #endif //WIN32
33
34 #include "BL_SkinDeformer.h"
35 #include "GEN_Map.h"
36 #include "STR_HashedString.h"
37 #include "RAS_IPolygonMaterial.h"
38 #include "BL_SkinMeshObject.h"
39
40 //#include "BL_ArmatureController.h"
41 #include "DNA_armature_types.h"
42 #include "DNA_action_types.h"
43 #include "DNA_mesh_types.h"
44 #include "DNA_meshdata_types.h"
45 #include "BKE_armature.h"
46 #include "BKE_action.h"
47 #include "MT_Point3.h"
48
49 extern "C"{
50         #include "BKE_lattice.h"
51 }
52  #include "BKE_utildefines.h"
53
54 #include "BLI_blenlib.h"
55 #include "BLI_arithb.h"
56
57 #define __NLA_DEFNORMALS
58 //#undef __NLA_DEFNORMALS
59
60 BL_SkinDeformer::BL_SkinDeformer(struct Object *bmeshobj, 
61                                                                 class BL_SkinMeshObject *mesh,
62                                                                 BL_ArmatureObject* arma)
63                                                         :       //
64                                                         BL_MeshDeformer(bmeshobj, mesh),
65                                                         m_armobj(arma),
66                                                         m_lastArmaUpdate(-1),
67                                                         m_defbase(&bmeshobj->defbase),
68                                                         m_releaseobject(false)
69 {
70         Mat4CpyMat4(m_obmat, bmeshobj->obmat);
71 };
72
73 BL_SkinDeformer::BL_SkinDeformer(
74         struct Object *bmeshobj_old,    // Blender object that owns the new mesh
75         struct Object *bmeshobj_new,    // Blender object that owns the original mesh
76         class BL_SkinMeshObject *mesh,
77         bool release_object,
78         BL_ArmatureObject* arma)        :       
79                 BL_MeshDeformer(bmeshobj_old, mesh),
80                 m_armobj(arma),
81                 m_lastArmaUpdate(-1),
82                 m_defbase(&bmeshobj_old->defbase),
83                 m_releaseobject(release_object)
84         {
85                 // this is needed to ensure correct deformation of mesh:
86                 // the deformation is done with Blender's armature_deform_verts() function
87                 // that takes an object as parameter and not a mesh. The object matrice is used
88                 // in the calculation, so we must use the matrix of the original object to
89                 // simulate a pure replacement of the mesh.
90                 Mat4CpyMat4(m_obmat, bmeshobj_new->obmat);
91         }
92
93 BL_SkinDeformer::~BL_SkinDeformer()
94 {
95         if(m_releaseobject && m_armobj)
96                 m_armobj->Release();
97 }
98
99 bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat)
100 {
101         size_t                  i, j, index;
102         vecVertexArray  array;
103         vecIndexArrays  mvarray;
104         vecMDVertArray  dvarray;
105         vecIndexArrays  diarray;
106
107         RAS_TexVert *tv;
108         MT_Point3 pt;
109 //      float co[3];
110
111         Update();
112
113         array = m_pMeshObject->GetVertexCache(mat);
114         mvarray = m_pMeshObject->GetMVertCache(mat);
115         diarray = m_pMeshObject->GetDIndexCache(mat);
116         // For each array
117         for (i=0; i<array.size(); i++) {
118                 //      For each vertex
119                 for (j=0; j<array[i]->size(); j++) {
120
121                         tv = &((*array[i])[j]);
122                         
123                         index = ((*diarray[i])[j]);
124                         
125                         //      Copy the untransformed data from the original mvert
126                         //      Set the data
127                         tv->SetXYZ(m_transverts[((*mvarray[i])[index])]);
128                 }
129         }
130
131         return true;
132 }
133
134 RAS_Deformer *BL_SkinDeformer::GetReplica()
135 {
136         BL_SkinDeformer *result;
137
138         result = new BL_SkinDeformer(*this);
139         result->ProcessReplica();
140         return result;
141 }
142
143 void BL_SkinDeformer::ProcessReplica()
144 {
145 }
146
147 //void where_is_pose (Object *ob);
148 //void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3], int numVerts, int deformflag); 
149 bool BL_SkinDeformer::Update(void)
150 {
151         /* See if the armature has been updated for this frame */
152         if (PoseUpdated()){     
153                 float obmat[4][4];      // the original object matrice 
154                 
155                 /* XXX note: where_is_pose() (from BKE_armature.h) calculates all matrices needed to start deforming */
156                 /* but it requires the blender object pointer... */
157
158                 Object* par_arma = m_armobj->GetArmatureObject();
159                 where_is_pose( par_arma ); 
160
161                 /* store verts locally */
162                 VerifyStorage();
163         
164                 /* duplicate */
165                 for (int v =0; v<m_bmesh->totvert; v++)
166                         VECCOPY(m_transverts[v], m_bmesh->mvert[v].co);
167
168                 // save matrix first
169                 Mat4CpyMat4(obmat, m_objMesh->obmat);
170                 // set reference matrix
171                 Mat4CpyMat4(m_objMesh->obmat, m_obmat);
172
173                 armature_deform_verts( par_arma, m_objMesh, NULL, m_transverts, NULL, m_bmesh->totvert, ARM_DEF_VGROUP, NULL, NULL );
174                 
175                 // restore matrix 
176                 Mat4CpyMat4(m_objMesh->obmat, obmat);
177
178 #ifdef __NLA_DEFNORMALS
179                 RecalcNormals();
180 #endif
181
182                 /* Update the current frame */
183                 m_lastArmaUpdate=m_armobj->GetLastFrame();
184                 
185                 /* indicate that the m_transverts and normals are up to date */
186                 return true;
187         }
188         return false;
189 }
190
191 /* XXX note: I propose to drop this function */
192 void BL_SkinDeformer::SetArmature(BL_ArmatureObject *armobj)
193 {
194         // only used to set the object now
195         m_armobj = armobj;
196 }