Blender V2.61 - r43446

BL_SkinDeformer.cpp

Go to the documentation of this file.
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 }