f7df35af21d484d89d2d77e7a3dfc553d0a39ab7
[blender-staging.git] / source / gameengine / Converter / BL_MeshDeformer.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  * Simple deformation controller that restores a mesh to its rest position
32  */
33
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37
38 #ifdef WIN32
39 // This warning tells us about truncation of __long__ stl-generated names.
40 // It can occasionally cause DevStudio to have internal compiler warnings.
41 #pragma warning( disable : 4786 )     
42 #endif
43
44 #include "RAS_IPolygonMaterial.h"
45 #include "BL_MeshDeformer.h"
46 #include "BL_SkinMeshObject.h"
47 #include "DNA_mesh_types.h"
48 #include "DNA_meshdata_types.h"
49 #include "BLI_arithb.h"
50
51 #include "GEN_Map.h"
52 #include "STR_HashedString.h"
53
54
55 bool BL_MeshDeformer::Apply(RAS_IPolyMaterial *mat)
56 {
57         size_t                  i, j, index;
58         vecVertexArray  array;
59         vecIndexArrays  mvarray;
60         vecIndexArrays  diarray;
61         float co[3];
62         
63         RAS_TexVert *tv;
64         MVert   *mvert;
65         
66         // For each material
67         array = m_pMeshObject->GetVertexCache(mat);
68         mvarray = m_pMeshObject->GetMVertCache(mat);
69         diarray = m_pMeshObject->GetDIndexCache(mat);
70         
71         // For each array
72         for (i=0; i<array.size(); i++){
73                 //      For each vertex
74                 for (j=0; j<array[i]->size(); j++){
75                         tv = &((*array[i])[j]);
76                         index = ((*diarray[i])[j]);
77
78                         mvert = &(m_bmesh->mvert[((*mvarray[i])[index])]);
79                         tv->SetXYZ(MT_Point3(mvert->co));
80                 }
81         }
82         return true;
83 }
84
85 BL_MeshDeformer::~BL_MeshDeformer()
86 {       
87         if (m_transverts)
88                 delete []m_transverts;
89         if (m_transnors)
90                 delete []m_transnors;
91 };
92
93 /**
94  * @warning This function is expensive!
95  */
96 void BL_MeshDeformer::RecalcNormals()
97 {
98         int v, f;
99         float fnor[3], co1[3], co2[3], co3[3], co4[3];
100
101         /* Clear all vertex normal accumulators */
102         for (v =0; v<m_bmesh->totvert; v++){
103                 m_transnors[v]=MT_Point3(0,0,0);
104         }
105         
106         /* Find the face normals */
107         for (f = 0; f<m_bmesh->totface; f++){
108                 // Make new face normal based on the transverts
109                 MFace *mf= &((MFace*)m_bmesh->mface)[f];
110                 
111                 if (mf->v3) {
112                         for (int vl=0; vl<3; vl++){
113                                 co1[vl]=m_transverts[mf->v1][vl];
114                                 co2[vl]=m_transverts[mf->v2][vl];
115                                 co3[vl]=m_transverts[mf->v3][vl];
116                                 if (mf->v4)
117                                         co4[vl]=m_transverts[mf->v4][vl];
118                         }
119
120                         /* FIXME: Use moto */
121                         if (mf->v4)
122                                 CalcNormFloat4(co1, co2, co3, co4, fnor);
123                         else
124                                 CalcNormFloat(co1, co2, co3, fnor);
125         
126                         /* Decide which normals are affected by this face's normal */
127                         m_transnors[mf->v1]+=MT_Point3(fnor);
128                         m_transnors[mf->v2]+=MT_Point3(fnor);
129                         m_transnors[mf->v3]+=MT_Point3(fnor);
130                         if (mf->v4)
131                                 m_transnors[mf->v4]+=MT_Point3(fnor);
132
133                 }
134                 
135         }
136         
137         for (v =0; v<m_bmesh->totvert; v++){
138 //              float nor[3];
139
140                 m_transnors[v]=m_transnors[v].safe_normalized();
141 //              nor[0]=m_transnors[v][0];
142 //              nor[1]=m_transnors[v][1];
143 //              nor[2]=m_transnors[v][2];
144                 
145         };
146 }
147
148 void BL_MeshDeformer::VerifyStorage()
149 {
150         /* Ensure that we have the right number of verts assigned */
151         if (m_tvtot!=m_bmesh->totvert+m_bmesh->totface){
152                 if (m_transverts)
153                         delete []m_transverts;
154                 if (m_transnors)
155                         delete []m_transnors;
156                 
157                 m_transnors =new MT_Point3[m_bmesh->totvert+m_bmesh->totface];
158                 m_transverts=new MT_Point3[m_bmesh->totvert];
159                 m_tvtot = m_bmesh->totvert;
160         }
161 }
162