Last of the config.h mods...
[blender.git] / source / gameengine / Converter / BL_SkinDeformer.cpp
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL 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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36
37 #ifdef WIN32
38 #pragma warning (disable : 4786)
39 #endif //WIN32
40
41 #include "GEN_Map.h"
42 #include "STR_HashedString.h"
43 #include "RAS_IPolygonMaterial.h"
44 #include "BL_SkinMeshObject.h"
45
46 //#include "BL_ArmatureController.h"
47 #include "BL_SkinDeformer.h"
48 #include "DNA_armature_types.h"
49 #include "DNA_action_types.h"
50 #include "DNA_mesh_types.h"
51 #include "BKE_armature.h"
52 #include "BKE_action.h"
53 #include "MT_Point3.h"
54
55 #include "BLI_blenlib.h"
56 #include "BLI_arithb.h"
57
58 #define __NLA_DEFNORMALS
59 //#undef __NLA_DEFNORMALS
60
61 BL_SkinDeformer::~BL_SkinDeformer()
62 {
63 };
64
65 bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat)
66 {
67         int                     i, j, index;
68         vecVertexArray  array;
69 #ifdef __NLA_OLDDEFORM
70         vecMVertArray   mvarray;
71 #else
72         vecIndexArrays  mvarray;
73 #endif
74         vecMDVertArray  dvarray;
75         vecIndexArrays  diarray;
76
77         RAS_TexVert *tv;
78 #ifdef __NLA_OLDDEFORM
79         MVert   *mvert;
80         MDeformVert     *dvert;
81 #endif
82         MT_Point3 pt;
83 //      float co[3];
84
85         if (!m_armobj)
86                 return false;
87
88         Update();
89
90         array = m_pMeshObject->GetVertexCache(mat);
91 #ifdef __NLA_OLDDEFORM
92         dvarray = m_pMeshObject->GetDVertCache(mat);
93 #endif
94         mvarray = m_pMeshObject->GetMVertCache(mat);
95         diarray = m_pMeshObject->GetDIndexCache(mat);
96         
97
98         // For each array
99         for (i=0; i<array.size(); i++){
100                 //      For each vertex
101                 for (j=0; j<array[i]->size(); j++){
102
103                         tv = &((*array[i])[j]);
104                         
105                         index = ((*diarray[i])[j]);
106 #ifdef __NLA_OLDDEFORM
107                         pt = tv->xyz();
108                         mvert = ((*mvarray[i])[index]);
109                         dvert = ((*dvarray[i])[index]);
110 #endif
111                         
112                         //      Copy the untransformed data from the original mvert
113 #ifdef __NLA_OLDDEFORM
114                         co[0]=mvert->co[0];
115                         co[1]=mvert->co[1];
116                         co[2]=mvert->co[2];
117
118                         //      Do the deformation
119                         GB_calc_armature_deform(co, dvert);
120                         tv->SetXYZ(co);
121 #else
122                         //      Set the data
123                         tv->SetXYZ(m_transverts[((*mvarray[i])[index])]);
124 #ifdef __NLA_DEFNORMALS
125
126                         tv->SetNormal(m_transnors[((*mvarray[i])[index])]);
127 #endif
128 #endif
129                 }
130         }
131         
132         return true;
133 }
134
135 RAS_Deformer *BL_SkinDeformer::GetReplica()
136 {
137         BL_SkinDeformer *result;
138
139         result = new BL_SkinDeformer(*this);
140         result->ProcessReplica();
141         return result;
142 }
143
144 void BL_SkinDeformer::ProcessReplica()
145 {
146 }
147
148 void BL_SkinDeformer::Update(void)
149 {
150
151         /* See if the armature has been updated for this frame */
152         if (m_lastUpdate!=m_armobj->GetLastFrame()){    
153                 
154                 /* Do all of the posing necessary */
155                 GB_init_armature_deform (m_defbase, m_premat, m_postmat);
156                 m_armobj->ApplyPose();
157                 precalc_armature_posemats (m_armobj->GetArmature());
158                 for (Bone *curBone=(Bone*)m_armobj->GetArmature()->bonebase.first; curBone; curBone=(Bone*)curBone->next)
159                         precalc_bone_defmat(curBone);
160                 
161                 VerifyStorage();
162
163                 /* Transform the verts & store locally */
164                 for (int v =0; v<m_bmesh->totvert; v++){
165                         float co[3];
166
167                         co[0]=m_bmesh->mvert[v].co[0];
168                         co[1]=m_bmesh->mvert[v].co[1];
169                         co[2]=m_bmesh->mvert[v].co[2];
170                         GB_calc_armature_deform(co, &m_bmesh->dvert[v]);
171
172                         m_transverts[v]=MT_Point3(co);
173                 }
174                 
175                 RecalcNormals();
176                 
177
178                 /* Update the current frame */
179                 m_lastUpdate=m_armobj->GetLastFrame();
180         }
181 }
182
183 void BL_SkinDeformer::SetArmature(BL_ArmatureObject *armobj)
184 {
185         m_armobj = armobj;
186
187         for (bDeformGroup *dg=(bDeformGroup*)m_defbase->first; dg; dg=(bDeformGroup*)dg->next)
188                         dg->data = (void*)get_named_bone(m_armobj->GetArmature(), dg->name);
189                 
190                 GB_validate_defgroups(m_bmesh, m_defbase);
191 }