|
Blender
V2.59
|
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 }