doxygen: prevent GPL license block from being parsed as doxygen comment.
[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., 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 #if defined(WIN32) && !defined(FREE_WINDOWS)
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 "RAS_MeshObject.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 "BLI_utildefines.h"
46 #include "BKE_armature.h"
47 #include "BKE_action.h"
48 #include "MT_Point3.h"
49
50 extern "C"{
51         #include "BKE_lattice.h"
52 }
53  
54
55 #include "BLI_blenlib.h"
56 #include "BLI_math.h"
57
58 #define __NLA_DEFNORMALS
59 //#undef __NLA_DEFNORMALS
60
61 BL_SkinDeformer::BL_SkinDeformer(BL_DeformableGameObject *gameobj,
62                                                                 struct Object *bmeshobj, 
63                                                                 class RAS_MeshObject *mesh,
64                                                                 BL_ArmatureObject* arma)
65                                                         :       //
66                                                         BL_MeshDeformer(gameobj, bmeshobj, mesh),
67                                                         m_armobj(arma),
68                                                         m_lastArmaUpdate(-1),
69                                                         //m_defbase(&bmeshobj->defbase),
70                                                         m_releaseobject(false),
71                                                         m_poseApplied(false),
72                                                         m_recalcNormal(true)
73 {
74         copy_m4_m4(m_obmat, bmeshobj->obmat);
75 };
76
77 BL_SkinDeformer::BL_SkinDeformer(
78         BL_DeformableGameObject *gameobj,
79         struct Object *bmeshobj_old,    // Blender object that owns the new mesh
80         struct Object *bmeshobj_new,    // Blender object that owns the original mesh
81         class RAS_MeshObject *mesh,
82         bool release_object,
83         bool recalc_normal,
84         BL_ArmatureObject* arma)        :       
85                 BL_MeshDeformer(gameobj, bmeshobj_old, mesh),
86                 m_armobj(arma),
87                 m_lastArmaUpdate(-1),
88                 //m_defbase(&bmeshobj_old->defbase),
89                 m_releaseobject(release_object),
90                 m_recalcNormal(recalc_normal)
91         {
92                 // this is needed to ensure correct deformation of mesh:
93                 // the deformation is done with Blender's armature_deform_verts() function
94                 // that takes an object as parameter and not a mesh. The object matrice is used
95                 // in the calculation, so we must use the matrix of the original object to
96                 // simulate a pure replacement of the mesh.
97                 copy_m4_m4(m_obmat, bmeshobj_new->obmat);
98         }
99
100 BL_SkinDeformer::~BL_SkinDeformer()
101 {
102         if(m_releaseobject && m_armobj)
103                 m_armobj->Release();
104 }
105
106 void BL_SkinDeformer::Relink(GEN_Map<class GEN_HashedPtr, void*>*map)
107 {
108         if (m_armobj) {
109                 void **h_obj = (*map)[m_armobj];
110
111                 if (h_obj)
112                         m_armobj = (BL_ArmatureObject*)(*h_obj);
113                 else
114                         m_armobj=NULL;
115         }
116
117         BL_MeshDeformer::Relink(map);
118 }
119
120 bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat)
121 {
122         RAS_MeshSlot::iterator it;
123         RAS_MeshMaterial *mmat;
124         RAS_MeshSlot *slot;
125         size_t i, nmat, imat;
126
127         // update the vertex in m_transverts
128         if (!Update())
129                 return false;
130
131         if (m_transverts) {
132                 // the vertex cache is unique to this deformer, no need to update it
133                 // if it wasn't updated! We must update all the materials at once
134                 // because we will not get here again for the other material
135                 nmat = m_pMeshObject->NumMaterials();
136                 for (imat=0; imat<nmat; imat++) {
137                         mmat = m_pMeshObject->GetMeshMaterial(imat);
138                         if(!mmat->m_slots[(void*)m_gameobj])
139                                 continue;
140
141                         slot = *mmat->m_slots[(void*)m_gameobj];
142
143                         // for each array
144                         for(slot->begin(it); !slot->end(it); slot->next(it)) {
145                                 // for each vertex
146                                 // copy the untransformed data from the original mvert
147                                 for(i=it.startvertex; i<it.endvertex; i++) {
148                                         RAS_TexVert& v = it.vertex[i];
149                                         v.SetXYZ(m_transverts[v.getOrigIndex()]);
150                                 }
151                         }
152                 }
153         }
154         return true;
155 }
156
157 RAS_Deformer *BL_SkinDeformer::GetReplica()
158 {
159         BL_SkinDeformer *result;
160
161         result = new BL_SkinDeformer(*this);
162         /* there is m_armobj that must be fixed but we cannot do it now, it will be done in Relink */
163         result->ProcessReplica();
164         return result;
165 }
166
167 void BL_SkinDeformer::ProcessReplica()
168 {
169         BL_MeshDeformer::ProcessReplica();
170         m_lastArmaUpdate = -1;
171         m_releaseobject = false;
172 }
173
174 //void where_is_pose (Object *ob);
175 //void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3], int numVerts, int deformflag); 
176 bool BL_SkinDeformer::UpdateInternal(bool shape_applied)
177 {
178         /* See if the armature has been updated for this frame */
179         if (PoseUpdated()){     
180                 float obmat[4][4];      // the original object matrice 
181
182                 /* XXX note: where_is_pose() (from BKE_armature.h) calculates all matrices needed to start deforming */
183                 /* but it requires the blender object pointer... */
184                 Object* par_arma = m_armobj->GetArmatureObject();
185
186                 if(!shape_applied) {
187                         /* store verts locally */
188                         VerifyStorage();
189                 
190                         /* duplicate */
191                         for (int v =0; v<m_bmesh->totvert; v++)
192                                 VECCOPY(m_transverts[v], m_bmesh->mvert[v].co);
193                 }
194
195                 m_armobj->ApplyPose();
196
197                 // save matrix first
198                 copy_m4_m4(obmat, m_objMesh->obmat);
199                 // set reference matrix
200                 copy_m4_m4(m_objMesh->obmat, m_obmat);
201
202                 armature_deform_verts( par_arma, m_objMesh, NULL, m_transverts, NULL, m_bmesh->totvert, ARM_DEF_VGROUP, NULL, NULL );
203                 
204                 // restore matrix 
205                 copy_m4_m4(m_objMesh->obmat, obmat);
206
207 #ifdef __NLA_DEFNORMALS
208                 if (m_recalcNormal)
209                         RecalcNormals();
210 #endif
211
212                 /* Update the current frame */
213                 m_lastArmaUpdate=m_armobj->GetLastFrame();
214
215                 m_armobj->RestorePose();
216                 /* dynamic vertex, cannot use display list */
217                 m_bDynamic = true;
218                 /* indicate that the m_transverts and normals are up to date */
219                 return true;
220         }
221
222         return false;
223 }
224
225 bool BL_SkinDeformer::Update(void)
226 {
227         return UpdateInternal(false);
228 }
229
230 /* XXX note: I propose to drop this function */
231 void BL_SkinDeformer::SetArmature(BL_ArmatureObject *armobj)
232 {
233         // only used to set the object now
234         m_armobj = armobj;
235 }