Blender  V2.59
BL_SkinDeformer.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: BL_SkinDeformer.cpp 36523 2011-05-06 20:18:42Z blendix $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00021  * All rights reserved.
00022  *
00023  * The Original Code is: all of this file.
00024  *
00025  * Contributor(s): none yet.
00026  *
00027  * ***** END GPL LICENSE BLOCK *****
00028  */
00029 
00035 #if defined(WIN32) && !defined(FREE_WINDOWS)
00036 #pragma warning (disable : 4786)
00037 #endif //WIN32
00038 
00039 #include "BL_SkinDeformer.h"
00040 #include "CTR_Map.h"
00041 #include "STR_HashedString.h"
00042 #include "RAS_IPolygonMaterial.h"
00043 #include "RAS_MeshObject.h"
00044 
00045 //#include "BL_ArmatureController.h"
00046 #include "DNA_armature_types.h"
00047 #include "DNA_action_types.h"
00048 #include "DNA_mesh_types.h"
00049 #include "DNA_meshdata_types.h"
00050 #include "BLI_utildefines.h"
00051 #include "BKE_armature.h"
00052 #include "BKE_action.h"
00053 #include "MT_Point3.h"
00054 
00055 extern "C"{
00056         #include "BKE_lattice.h"
00057 }
00058  
00059 
00060 #include "BLI_blenlib.h"
00061 #include "BLI_math.h"
00062 
00063 #define __NLA_DEFNORMALS
00064 //#undef __NLA_DEFNORMALS
00065 
00066 BL_SkinDeformer::BL_SkinDeformer(BL_DeformableGameObject *gameobj,
00067                                                                 struct Object *bmeshobj, 
00068                                                                 class RAS_MeshObject *mesh,
00069                                                                 BL_ArmatureObject* arma)
00070                                                         :       //
00071                                                         BL_MeshDeformer(gameobj, bmeshobj, mesh),
00072                                                         m_armobj(arma),
00073                                                         m_lastArmaUpdate(-1),
00074                                                         //m_defbase(&bmeshobj->defbase),
00075                                                         m_releaseobject(false),
00076                                                         m_poseApplied(false),
00077                                                         m_recalcNormal(true)
00078 {
00079         copy_m4_m4(m_obmat, bmeshobj->obmat);
00080 };
00081 
00082 BL_SkinDeformer::BL_SkinDeformer(
00083         BL_DeformableGameObject *gameobj,
00084         struct Object *bmeshobj_old,    // Blender object that owns the new mesh
00085         struct Object *bmeshobj_new,    // Blender object that owns the original mesh
00086         class RAS_MeshObject *mesh,
00087         bool release_object,
00088         bool recalc_normal,
00089         BL_ArmatureObject* arma)        :       
00090                 BL_MeshDeformer(gameobj, bmeshobj_old, mesh),
00091                 m_armobj(arma),
00092                 m_lastArmaUpdate(-1),
00093                 //m_defbase(&bmeshobj_old->defbase),
00094                 m_releaseobject(release_object),
00095                 m_recalcNormal(recalc_normal)
00096         {
00097                 // this is needed to ensure correct deformation of mesh:
00098                 // the deformation is done with Blender's armature_deform_verts() function
00099                 // that takes an object as parameter and not a mesh. The object matrice is used
00100                 // in the calculation, so we must use the matrix of the original object to
00101                 // simulate a pure replacement of the mesh.
00102                 copy_m4_m4(m_obmat, bmeshobj_new->obmat);
00103         }
00104 
00105 BL_SkinDeformer::~BL_SkinDeformer()
00106 {
00107         if(m_releaseobject && m_armobj)
00108                 m_armobj->Release();
00109 }
00110 
00111 void BL_SkinDeformer::Relink(CTR_Map<class CTR_HashedPtr, void*>*map)
00112 {
00113         if (m_armobj) {
00114                 void **h_obj = (*map)[m_armobj];
00115 
00116                 if (h_obj)
00117                         m_armobj = (BL_ArmatureObject*)(*h_obj);
00118                 else
00119                         m_armobj=NULL;
00120         }
00121 
00122         BL_MeshDeformer::Relink(map);
00123 }
00124 
00125 bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat)
00126 {
00127         RAS_MeshSlot::iterator it;
00128         RAS_MeshMaterial *mmat;
00129         RAS_MeshSlot *slot;
00130         size_t i, nmat, imat;
00131 
00132         // update the vertex in m_transverts
00133         if (!Update())
00134                 return false;
00135 
00136         if (m_transverts) {
00137                 // the vertex cache is unique to this deformer, no need to update it
00138                 // if it wasn't updated! We must update all the materials at once
00139                 // because we will not get here again for the other material
00140                 nmat = m_pMeshObject->NumMaterials();
00141                 for (imat=0; imat<nmat; imat++) {
00142                         mmat = m_pMeshObject->GetMeshMaterial(imat);
00143                         if(!mmat->m_slots[(void*)m_gameobj])
00144                                 continue;
00145 
00146                         slot = *mmat->m_slots[(void*)m_gameobj];
00147 
00148                         // for each array
00149                         for(slot->begin(it); !slot->end(it); slot->next(it)) {
00150                                 // for each vertex
00151                                 // copy the untransformed data from the original mvert
00152                                 for(i=it.startvertex; i<it.endvertex; i++) {
00153                                         RAS_TexVert& v = it.vertex[i];
00154                                         v.SetXYZ(m_transverts[v.getOrigIndex()]);
00155                                 }
00156                         }
00157                 }
00158         }
00159         return true;
00160 }
00161 
00162 RAS_Deformer *BL_SkinDeformer::GetReplica()
00163 {
00164         BL_SkinDeformer *result;
00165 
00166         result = new BL_SkinDeformer(*this);
00167         /* there is m_armobj that must be fixed but we cannot do it now, it will be done in Relink */
00168         result->ProcessReplica();
00169         return result;
00170 }
00171 
00172 void BL_SkinDeformer::ProcessReplica()
00173 {
00174         BL_MeshDeformer::ProcessReplica();
00175         m_lastArmaUpdate = -1;
00176         m_releaseobject = false;
00177 }
00178 
00179 //void where_is_pose (Object *ob);
00180 //void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3], int numVerts, int deformflag); 
00181 bool BL_SkinDeformer::UpdateInternal(bool shape_applied)
00182 {
00183         /* See if the armature has been updated for this frame */
00184         if (PoseUpdated()){     
00185                 float obmat[4][4];      // the original object matrice 
00186 
00187                 /* XXX note: where_is_pose() (from BKE_armature.h) calculates all matrices needed to start deforming */
00188                 /* but it requires the blender object pointer... */
00189                 Object* par_arma = m_armobj->GetArmatureObject();
00190 
00191                 if(!shape_applied) {
00192                         /* store verts locally */
00193                         VerifyStorage();
00194                 
00195                         /* duplicate */
00196                         for (int v =0; v<m_bmesh->totvert; v++)
00197                                 VECCOPY(m_transverts[v], m_bmesh->mvert[v].co);
00198                 }
00199 
00200                 m_armobj->ApplyPose();
00201 
00202                 // save matrix first
00203                 copy_m4_m4(obmat, m_objMesh->obmat);
00204                 // set reference matrix
00205                 copy_m4_m4(m_objMesh->obmat, m_obmat);
00206 
00207                 armature_deform_verts( par_arma, m_objMesh, NULL, m_transverts, NULL, m_bmesh->totvert, ARM_DEF_VGROUP, NULL, NULL );
00208                 
00209                 // restore matrix 
00210                 copy_m4_m4(m_objMesh->obmat, obmat);
00211 
00212 #ifdef __NLA_DEFNORMALS
00213                 if (m_recalcNormal)
00214                         RecalcNormals();
00215 #endif
00216 
00217                 /* Update the current frame */
00218                 m_lastArmaUpdate=m_armobj->GetLastFrame();
00219 
00220                 m_armobj->RestorePose();
00221                 /* dynamic vertex, cannot use display list */
00222                 m_bDynamic = true;
00223                 /* indicate that the m_transverts and normals are up to date */
00224                 return true;
00225         }
00226 
00227         return false;
00228 }
00229 
00230 bool BL_SkinDeformer::Update(void)
00231 {
00232         return UpdateInternal(false);
00233 }
00234 
00235 /* XXX note: I propose to drop this function */
00236 void BL_SkinDeformer::SetArmature(BL_ArmatureObject *armobj)
00237 {
00238         // only used to set the object now
00239         m_armobj = armobj;
00240 }