Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): none yet. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 * Simple deformation controller that restores a mesh to its rest position 00027 */ 00028 00034 #if defined(WIN32) && !defined(FREE_WINDOWS) 00035 // This warning tells us about truncation of __long__ stl-generated names. 00036 // It can occasionally cause DevStudio to have internal compiler warnings. 00037 #pragma warning( disable : 4786 ) 00038 #endif 00039 00040 #include "RAS_IPolygonMaterial.h" 00041 #include "BL_DeformableGameObject.h" 00042 #include "BL_MeshDeformer.h" 00043 #include "RAS_MeshObject.h" 00044 #include "DNA_mesh_types.h" 00045 #include "DNA_meshdata_types.h" 00046 00047 #include "CTR_Map.h" 00048 #include "STR_HashedString.h" 00049 #include "BLI_math.h" 00050 00051 bool BL_MeshDeformer::Apply(RAS_IPolyMaterial*) 00052 { 00053 size_t i; 00054 00055 // only apply once per frame if the mesh is actually modified 00056 if(m_pMeshObject->MeshModified() && 00057 m_lastDeformUpdate != m_gameobj->GetLastFrame()) { 00058 // For each material 00059 for(list<RAS_MeshMaterial>::iterator mit= m_pMeshObject->GetFirstMaterial(); 00060 mit != m_pMeshObject->GetLastMaterial(); ++ mit) { 00061 if(!mit->m_slots[(void*)m_gameobj]) 00062 continue; 00063 00064 RAS_MeshSlot *slot = *mit->m_slots[(void*)m_gameobj]; 00065 RAS_MeshSlot::iterator it; 00066 00067 // for each array 00068 for(slot->begin(it); !slot->end(it); slot->next(it)) { 00069 // For each vertex 00070 for(i=it.startvertex; i<it.endvertex; i++) { 00071 RAS_TexVert& v = it.vertex[i]; 00072 v.SetXYZ(m_bmesh->mvert[v.getOrigIndex()].co); 00073 } 00074 } 00075 } 00076 00077 m_lastDeformUpdate = m_gameobj->GetLastFrame(); 00078 00079 return true; 00080 } 00081 00082 return false; 00083 } 00084 00085 BL_MeshDeformer::~BL_MeshDeformer() 00086 { 00087 if (m_transverts) 00088 delete [] m_transverts; 00089 if (m_transnors) 00090 delete [] m_transnors; 00091 } 00092 00093 void BL_MeshDeformer::ProcessReplica() 00094 { 00095 m_transverts = NULL; 00096 m_transnors = NULL; 00097 m_tvtot = 0; 00098 m_bDynamic=false; 00099 m_lastDeformUpdate = -1; 00100 } 00101 00102 void BL_MeshDeformer::Relink(CTR_Map<class CTR_HashedPtr, void*>*map) 00103 { 00104 void **h_obj = (*map)[m_gameobj]; 00105 00106 if (h_obj) 00107 m_gameobj = (BL_DeformableGameObject*)(*h_obj); 00108 else 00109 m_gameobj = NULL; 00110 } 00111 00115 void BL_MeshDeformer::RecalcNormals() 00116 { 00117 /* We don't normalize for performance, not doing it for faces normals 00118 * gives area-weight normals which often look better anyway, and use 00119 * GL_NORMALIZE so we don't have to do per vertex normalization either 00120 * since the GPU can do it faster */ 00121 list<RAS_MeshMaterial>::iterator mit; 00122 RAS_MeshSlot::iterator it; 00123 size_t i; 00124 00125 /* set vertex normals to zero */ 00126 memset(m_transnors, 0, sizeof(float)*3*m_bmesh->totvert); 00127 00128 /* add face normals to vertices. */ 00129 for(mit = m_pMeshObject->GetFirstMaterial(); 00130 mit != m_pMeshObject->GetLastMaterial(); ++ mit) { 00131 if(!mit->m_slots[(void*)m_gameobj]) 00132 continue; 00133 00134 RAS_MeshSlot *slot = *mit->m_slots[(void*)m_gameobj]; 00135 00136 for(slot->begin(it); !slot->end(it); slot->next(it)) { 00137 int nvert = (int)it.array->m_type; 00138 00139 for(i=0; i<it.totindex; i+=nvert) { 00140 RAS_TexVert& v1 = it.vertex[it.index[i]]; 00141 RAS_TexVert& v2 = it.vertex[it.index[i+1]]; 00142 RAS_TexVert& v3 = it.vertex[it.index[i+2]]; 00143 RAS_TexVert *v4 = NULL; 00144 00145 const float *co1 = m_transverts[v1.getOrigIndex()]; 00146 const float *co2 = m_transverts[v2.getOrigIndex()]; 00147 const float *co3 = m_transverts[v3.getOrigIndex()]; 00148 const float *co4 = NULL; 00149 00150 /* compute face normal */ 00151 float fnor[3], n1[3], n2[3]; 00152 00153 if(nvert == 4) { 00154 v4 = &it.vertex[it.index[i+3]]; 00155 co4 = m_transverts[v4->getOrigIndex()]; 00156 00157 n1[0]= co1[0]-co3[0]; 00158 n1[1]= co1[1]-co3[1]; 00159 n1[2]= co1[2]-co3[2]; 00160 00161 n2[0]= co2[0]-co4[0]; 00162 n2[1]= co2[1]-co4[1]; 00163 n2[2]= co2[2]-co4[2]; 00164 } 00165 else { 00166 n1[0]= co1[0]-co2[0]; 00167 n2[0]= co2[0]-co3[0]; 00168 n1[1]= co1[1]-co2[1]; 00169 00170 n2[1]= co2[1]-co3[1]; 00171 n1[2]= co1[2]-co2[2]; 00172 n2[2]= co2[2]-co3[2]; 00173 } 00174 00175 fnor[0]= n1[1]*n2[2] - n1[2]*n2[1]; 00176 fnor[1]= n1[2]*n2[0] - n1[0]*n2[2]; 00177 fnor[2]= n1[0]*n2[1] - n1[1]*n2[0]; 00178 normalize_v3(fnor); 00179 00180 /* add to vertices for smooth normals */ 00181 float *vn1 = m_transnors[v1.getOrigIndex()]; 00182 float *vn2 = m_transnors[v2.getOrigIndex()]; 00183 float *vn3 = m_transnors[v3.getOrigIndex()]; 00184 00185 vn1[0] += fnor[0]; vn1[1] += fnor[1]; vn1[2] += fnor[2]; 00186 vn2[0] += fnor[0]; vn2[1] += fnor[1]; vn2[2] += fnor[2]; 00187 vn3[0] += fnor[0]; vn3[1] += fnor[1]; vn3[2] += fnor[2]; 00188 00189 if(v4) { 00190 float *vn4 = m_transnors[v4->getOrigIndex()]; 00191 vn4[0] += fnor[0]; vn4[1] += fnor[1]; vn4[2] += fnor[2]; 00192 } 00193 00194 /* in case of flat - just assign, the vertices are split */ 00195 if(v1.getFlag() & RAS_TexVert::FLAT) { 00196 v1.SetNormal(fnor); 00197 v2.SetNormal(fnor); 00198 v3.SetNormal(fnor); 00199 if(v4) 00200 v4->SetNormal(fnor); 00201 } 00202 } 00203 } 00204 } 00205 00206 /* assign smooth vertex normals */ 00207 for(mit = m_pMeshObject->GetFirstMaterial(); 00208 mit != m_pMeshObject->GetLastMaterial(); ++ mit) { 00209 if(!mit->m_slots[(void*)m_gameobj]) 00210 continue; 00211 00212 RAS_MeshSlot *slot = *mit->m_slots[(void*)m_gameobj]; 00213 00214 for(slot->begin(it); !slot->end(it); slot->next(it)) { 00215 for(i=it.startvertex; i<it.endvertex; i++) { 00216 RAS_TexVert& v = it.vertex[i]; 00217 00218 if(!(v.getFlag() & RAS_TexVert::FLAT)) 00219 v.SetNormal(m_transnors[v.getOrigIndex()]); //.safe_normalized() 00220 } 00221 } 00222 } 00223 } 00224 00225 void BL_MeshDeformer::VerifyStorage() 00226 { 00227 /* Ensure that we have the right number of verts assigned */ 00228 if (m_tvtot!=m_bmesh->totvert){ 00229 if (m_transverts) 00230 delete [] m_transverts; 00231 if (m_transnors) 00232 delete [] m_transnors; 00233 00234 m_transverts=new float[m_bmesh->totvert][3]; 00235 m_transnors=new float[m_bmesh->totvert][3]; 00236 m_tvtot = m_bmesh->totvert; 00237 } 00238 } 00239