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 */ 00027 00033 #if defined(WIN32) && !defined(FREE_WINDOWS) 00034 #pragma warning (disable : 4786) 00035 #endif //WIN32 00036 00037 // Eigen3 stuff used for BGEDeformVerts 00038 #include <Eigen/Core> 00039 #include <Eigen/LU> 00040 00041 #include "BL_SkinDeformer.h" 00042 #include "CTR_Map.h" 00043 #include "STR_HashedString.h" 00044 #include "RAS_IPolygonMaterial.h" 00045 #include "RAS_MeshObject.h" 00046 00047 //#include "BL_ArmatureController.h" 00048 #include "DNA_armature_types.h" 00049 #include "DNA_action_types.h" 00050 #include "DNA_mesh_types.h" 00051 #include "DNA_meshdata_types.h" 00052 #include "BLI_utildefines.h" 00053 #include "BKE_armature.h" 00054 #include "BKE_action.h" 00055 #include "MT_Point3.h" 00056 00057 extern "C"{ 00058 #include "BKE_lattice.h" 00059 #include "BKE_deform.h" 00060 } 00061 00062 00063 #include "BLI_blenlib.h" 00064 #include "BLI_math.h" 00065 00066 #define __NLA_DEFNORMALS 00067 //#undef __NLA_DEFNORMALS 00068 00069 BL_SkinDeformer::BL_SkinDeformer(BL_DeformableGameObject *gameobj, 00070 struct Object *bmeshobj, 00071 class RAS_MeshObject *mesh, 00072 BL_ArmatureObject* arma) 00073 : // 00074 BL_MeshDeformer(gameobj, bmeshobj, mesh), 00075 m_armobj(arma), 00076 m_lastArmaUpdate(-1), 00077 //m_defbase(&bmeshobj->defbase), 00078 m_releaseobject(false), 00079 m_poseApplied(false), 00080 m_recalcNormal(true), 00081 m_copyNormals(false), 00082 m_dfnrToPC(NULL) 00083 { 00084 copy_m4_m4(m_obmat, bmeshobj->obmat); 00085 }; 00086 00087 BL_SkinDeformer::BL_SkinDeformer( 00088 BL_DeformableGameObject *gameobj, 00089 struct Object *bmeshobj_old, // Blender object that owns the new mesh 00090 struct Object *bmeshobj_new, // Blender object that owns the original mesh 00091 class RAS_MeshObject *mesh, 00092 bool release_object, 00093 bool recalc_normal, 00094 BL_ArmatureObject* arma) : 00095 BL_MeshDeformer(gameobj, bmeshobj_old, mesh), 00096 m_armobj(arma), 00097 m_lastArmaUpdate(-1), 00098 //m_defbase(&bmeshobj_old->defbase), 00099 m_releaseobject(release_object), 00100 m_recalcNormal(recalc_normal), 00101 m_copyNormals(false), 00102 m_dfnrToPC(NULL) 00103 { 00104 // this is needed to ensure correct deformation of mesh: 00105 // the deformation is done with Blender's armature_deform_verts() function 00106 // that takes an object as parameter and not a mesh. The object matrice is used 00107 // in the calculation, so we must use the matrix of the original object to 00108 // simulate a pure replacement of the mesh. 00109 copy_m4_m4(m_obmat, bmeshobj_new->obmat); 00110 } 00111 00112 BL_SkinDeformer::~BL_SkinDeformer() 00113 { 00114 if(m_releaseobject && m_armobj) 00115 m_armobj->Release(); 00116 if(m_dfnrToPC) 00117 delete [] m_dfnrToPC; 00118 } 00119 00120 void BL_SkinDeformer::Relink(CTR_Map<class CTR_HashedPtr, void*>*map) 00121 { 00122 if (m_armobj) { 00123 void **h_obj = (*map)[m_armobj]; 00124 00125 if (h_obj) 00126 m_armobj = (BL_ArmatureObject*)(*h_obj); 00127 else 00128 m_armobj=NULL; 00129 } 00130 00131 BL_MeshDeformer::Relink(map); 00132 } 00133 00134 bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat) 00135 { 00136 RAS_MeshSlot::iterator it; 00137 RAS_MeshMaterial *mmat; 00138 RAS_MeshSlot *slot; 00139 size_t i, nmat, imat; 00140 00141 // update the vertex in m_transverts 00142 if (!Update()) 00143 return false; 00144 00145 if (m_transverts) { 00146 // the vertex cache is unique to this deformer, no need to update it 00147 // if it wasn't updated! We must update all the materials at once 00148 // because we will not get here again for the other material 00149 nmat = m_pMeshObject->NumMaterials(); 00150 for (imat=0; imat<nmat; imat++) { 00151 mmat = m_pMeshObject->GetMeshMaterial(imat); 00152 if(!mmat->m_slots[(void*)m_gameobj]) 00153 continue; 00154 00155 slot = *mmat->m_slots[(void*)m_gameobj]; 00156 00157 // for each array 00158 for(slot->begin(it); !slot->end(it); slot->next(it)) { 00159 // for each vertex 00160 // copy the untransformed data from the original mvert 00161 for(i=it.startvertex; i<it.endvertex; i++) { 00162 RAS_TexVert& v = it.vertex[i]; 00163 v.SetXYZ(m_transverts[v.getOrigIndex()]); 00164 if (m_copyNormals) 00165 v.SetNormal(m_transnors[v.getOrigIndex()]); 00166 } 00167 } 00168 } 00169 00170 if (m_copyNormals) 00171 m_copyNormals = false; 00172 } 00173 return true; 00174 } 00175 00176 RAS_Deformer *BL_SkinDeformer::GetReplica() 00177 { 00178 BL_SkinDeformer *result; 00179 00180 result = new BL_SkinDeformer(*this); 00181 /* there is m_armobj that must be fixed but we cannot do it now, it will be done in Relink */ 00182 result->ProcessReplica(); 00183 return result; 00184 } 00185 00186 void BL_SkinDeformer::ProcessReplica() 00187 { 00188 BL_MeshDeformer::ProcessReplica(); 00189 m_lastArmaUpdate = -1; 00190 m_releaseobject = false; 00191 m_dfnrToPC = NULL; 00192 } 00193 00194 void BL_SkinDeformer::BlenderDeformVerts() 00195 { 00196 float obmat[4][4]; // the original object matrix 00197 Object* par_arma = m_armobj->GetArmatureObject(); 00198 00199 // save matrix first 00200 copy_m4_m4(obmat, m_objMesh->obmat); 00201 // set reference matrix 00202 copy_m4_m4(m_objMesh->obmat, m_obmat); 00203 00204 armature_deform_verts( par_arma, m_objMesh, NULL, m_transverts, NULL, m_bmesh->totvert, ARM_DEF_VGROUP, NULL, NULL ); 00205 00206 // restore matrix 00207 copy_m4_m4(m_objMesh->obmat, obmat); 00208 00209 #ifdef __NLA_DEFNORMALS 00210 if (m_recalcNormal) 00211 RecalcNormals(); 00212 #endif 00213 } 00214 00215 void BL_SkinDeformer::BGEDeformVerts() 00216 { 00217 Object *par_arma = m_armobj->GetArmatureObject(); 00218 MDeformVert *dverts = m_bmesh->dvert; 00219 bDeformGroup *dg; 00220 int defbase_tot = BLI_countlist(&m_objMesh->defbase); 00221 00222 if (!dverts) 00223 return; 00224 00225 if (m_dfnrToPC == NULL) 00226 { 00227 m_dfnrToPC = new bPoseChannel*[defbase_tot]; 00228 int i; 00229 for (i=0, dg=(bDeformGroup*)m_objMesh->defbase.first; 00230 dg; 00231 ++i, dg=(bDeformGroup*)dg->next) 00232 { 00233 m_dfnrToPC[i] = get_pose_channel(par_arma->pose, dg->name); 00234 00235 if (m_dfnrToPC[i] && m_dfnrToPC[i]->bone->flag & BONE_NO_DEFORM) 00236 m_dfnrToPC[i] = NULL; 00237 } 00238 } 00239 00240 MDeformVert *dv= dverts; 00241 00242 for (int i=0; i<m_bmesh->totvert; ++i, dv++) 00243 { 00244 float contrib = 0.f, weight, max_weight=0.f; 00245 bPoseChannel *pchan=NULL; 00246 Eigen::Map<Eigen::Vector3f> norm(m_transnors[i]); 00247 Eigen::Vector4f vec(0, 0, 0, 1); 00248 Eigen::Matrix4f norm_chan_mat; 00249 Eigen::Vector4f co(m_transverts[i][0], 00250 m_transverts[i][1], 00251 m_transverts[i][2], 00252 1.f); 00253 00254 if (!dv->totweight) 00255 continue; 00256 00257 MDeformWeight *dw= dv->dw; 00258 00259 for (unsigned int j= dv->totweight; j != 0; j--, dw++) 00260 { 00261 const int index = dw->def_nr; 00262 00263 if (index < defbase_tot && (pchan=m_dfnrToPC[index])) 00264 { 00265 weight = dw->weight; 00266 00267 if (weight) 00268 { 00269 Eigen::Vector4f cop(co); 00270 Eigen::Matrix4f chan_mat = Eigen::Matrix4f::Map((float*)pchan->chan_mat); 00271 00272 // Update Vertex Position 00273 cop = chan_mat*cop; 00274 vec += (cop - co)*weight; 00275 00276 // Save the most influential channel so we can use it to update the vertex normal 00277 if (weight > max_weight) 00278 { 00279 max_weight = weight; 00280 norm_chan_mat = chan_mat; 00281 } 00282 00283 contrib += weight; 00284 } 00285 } 00286 } 00287 00288 00289 // Update Vertex Normal 00290 norm = norm_chan_mat.topLeftCorner<3, 3>()*norm; 00291 00292 if (contrib > 0.0001f) 00293 { 00294 vec *= 1.f/contrib; 00295 co += vec; 00296 } 00297 00298 m_transverts[i][0] = co[0]; 00299 m_transverts[i][1] = co[1]; 00300 m_transverts[i][2] = co[2]; 00301 } 00302 m_copyNormals = true; 00303 } 00304 00305 bool BL_SkinDeformer::UpdateInternal(bool shape_applied) 00306 { 00307 /* See if the armature has been updated for this frame */ 00308 if (PoseUpdated()){ 00309 00310 if(!shape_applied) { 00311 /* store verts locally */ 00312 VerifyStorage(); 00313 00314 /* duplicate */ 00315 for (int v =0; v<m_bmesh->totvert; v++) 00316 { 00317 copy_v3_v3(m_transverts[v], m_bmesh->mvert[v].co); 00318 normal_short_to_float_v3(m_transnors[v], m_bmesh->mvert[v].no); 00319 } 00320 } 00321 00322 m_armobj->ApplyPose(); 00323 00324 switch (m_armobj->GetVertDeformType()) 00325 { 00326 case ARM_VDEF_BGE_CPU: 00327 BGEDeformVerts(); 00328 break; 00329 case ARM_VDEF_BLENDER: 00330 default: 00331 BlenderDeformVerts(); 00332 } 00333 00334 /* Update the current frame */ 00335 m_lastArmaUpdate=m_armobj->GetLastFrame(); 00336 00337 m_armobj->RestorePose(); 00338 /* dynamic vertex, cannot use display list */ 00339 m_bDynamic = true; 00340 /* indicate that the m_transverts and normals are up to date */ 00341 return true; 00342 } 00343 00344 return false; 00345 } 00346 00347 bool BL_SkinDeformer::Update(void) 00348 { 00349 return UpdateInternal(false); 00350 } 00351 00352 /* XXX note: I propose to drop this function */ 00353 void BL_SkinDeformer::SetArmature(BL_ArmatureObject *armobj) 00354 { 00355 // only used to set the object now 00356 m_armobj = armobj; 00357 }