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) 2005 by the Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * Contributor(s): Daniel Dunbar 00022 * Ton Roosendaal, 00023 * Ben Batt, 00024 * Brecht Van Lommel, 00025 * Campbell Barton 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 * 00029 */ 00030 00036 #include "DNA_scene_types.h" 00037 #include "DNA_object_types.h" 00038 #include "DNA_meshdata_types.h" 00039 00040 #include "MEM_guardedalloc.h" 00041 00042 #include "BLI_math.h" 00043 #include "BLI_utildefines.h" 00044 00045 00046 #include "BKE_collision.h" 00047 #include "BKE_cdderivedmesh.h" 00048 #include "BKE_global.h" 00049 #include "BKE_modifier.h" 00050 #include "BKE_object.h" 00051 #include "BKE_pointcache.h" 00052 #include "BKE_scene.h" 00053 00054 #include "MOD_util.h" 00055 00056 static void initData(ModifierData *md) 00057 { 00058 CollisionModifierData *collmd = (CollisionModifierData*) md; 00059 00060 collmd->x = NULL; 00061 collmd->xnew = NULL; 00062 collmd->current_x = NULL; 00063 collmd->current_xnew = NULL; 00064 collmd->current_v = NULL; 00065 collmd->time_x = collmd->time_xnew = -1000; 00066 collmd->numverts = 0; 00067 collmd->bvhtree = NULL; 00068 } 00069 00070 static void freeData(ModifierData *md) 00071 { 00072 CollisionModifierData *collmd = (CollisionModifierData*) md; 00073 00074 if (collmd) 00075 { 00076 if(collmd->bvhtree) 00077 BLI_bvhtree_free(collmd->bvhtree); 00078 if(collmd->x) 00079 MEM_freeN(collmd->x); 00080 if(collmd->xnew) 00081 MEM_freeN(collmd->xnew); 00082 if(collmd->current_x) 00083 MEM_freeN(collmd->current_x); 00084 if(collmd->current_xnew) 00085 MEM_freeN(collmd->current_xnew); 00086 if(collmd->current_v) 00087 MEM_freeN(collmd->current_v); 00088 if(collmd->mfaces) 00089 MEM_freeN(collmd->mfaces); 00090 00091 collmd->x = NULL; 00092 collmd->xnew = NULL; 00093 collmd->current_x = NULL; 00094 collmd->current_xnew = NULL; 00095 collmd->current_v = NULL; 00096 collmd->time_x = collmd->time_xnew = -1000; 00097 collmd->numverts = 0; 00098 collmd->bvhtree = NULL; 00099 collmd->mfaces = NULL; 00100 } 00101 } 00102 00103 static int dependsOnTime(ModifierData *UNUSED(md)) 00104 { 00105 return 1; 00106 } 00107 00108 static void deformVerts(ModifierData *md, Object *ob, 00109 DerivedMesh *derivedData, 00110 float (*vertexCos)[3], 00111 int UNUSED(numVerts), 00112 int UNUSED(useRenderParams), 00113 int UNUSED(isFinalCalc)) 00114 { 00115 CollisionModifierData *collmd = (CollisionModifierData*) md; 00116 DerivedMesh *dm = NULL; 00117 MVert *tempVert = NULL; 00118 00119 /* if possible use/create DerivedMesh */ 00120 if(derivedData) dm = CDDM_copy(derivedData); 00121 else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob); 00122 00123 if(!ob->pd) 00124 { 00125 printf("CollisionModifier deformVerts: Should not happen!\n"); 00126 return; 00127 } 00128 00129 if(dm) 00130 { 00131 float current_time = 0; 00132 unsigned int numverts = 0; 00133 00134 CDDM_apply_vert_coords(dm, vertexCos); 00135 CDDM_calc_normals(dm); 00136 00137 current_time = BKE_curframe(md->scene); 00138 00139 if(G.rt > 0) 00140 printf("current_time %f, collmd->time_xnew %f\n", current_time, collmd->time_xnew); 00141 00142 numverts = dm->getNumVerts ( dm ); 00143 00144 if((current_time > collmd->time_xnew)|| (BKE_ptcache_get_continue_physics())) 00145 { 00146 unsigned int i; 00147 00148 // check if mesh has changed 00149 if(collmd->x && (numverts != collmd->numverts)) 00150 freeData((ModifierData *)collmd); 00151 00152 if(collmd->time_xnew == -1000) // first time 00153 { 00154 collmd->x = dm->dupVertArray(dm); // frame start position 00155 00156 for ( i = 0; i < numverts; i++ ) 00157 { 00158 // we save global positions 00159 mul_m4_v3( ob->obmat, collmd->x[i].co ); 00160 } 00161 00162 collmd->xnew = MEM_dupallocN(collmd->x); // frame end position 00163 collmd->current_x = MEM_dupallocN(collmd->x); // inter-frame 00164 collmd->current_xnew = MEM_dupallocN(collmd->x); // inter-frame 00165 collmd->current_v = MEM_dupallocN(collmd->x); // inter-frame 00166 00167 collmd->numverts = numverts; 00168 00169 collmd->mfaces = dm->dupFaceArray(dm); 00170 collmd->numfaces = dm->getNumFaces(dm); 00171 00172 // create bounding box hierarchy 00173 collmd->bvhtree = bvhtree_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->x, numverts, ob->pd->pdef_sboft); 00174 00175 collmd->time_x = collmd->time_xnew = current_time; 00176 } 00177 else if(numverts == collmd->numverts) 00178 { 00179 // put positions to old positions 00180 tempVert = collmd->x; 00181 collmd->x = collmd->xnew; 00182 collmd->xnew = tempVert; 00183 collmd->time_x = collmd->time_xnew; 00184 00185 memcpy(collmd->xnew, dm->getVertArray(dm), numverts*sizeof(MVert)); 00186 00187 for ( i = 0; i < numverts; i++ ) 00188 { 00189 // we save global positions 00190 mul_m4_v3( ob->obmat, collmd->xnew[i].co ); 00191 } 00192 00193 memcpy(collmd->current_xnew, collmd->x, numverts*sizeof(MVert)); 00194 memcpy(collmd->current_x, collmd->x, numverts*sizeof(MVert)); 00195 00196 /* check if GUI setting has changed for bvh */ 00197 if(collmd->bvhtree) 00198 { 00199 if(ob->pd->pdef_sboft != BLI_bvhtree_getepsilon(collmd->bvhtree)) 00200 { 00201 BLI_bvhtree_free(collmd->bvhtree); 00202 collmd->bvhtree = bvhtree_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sboft); 00203 } 00204 00205 } 00206 00207 /* happens on file load (ONLY when i decomment changes in readfile.c) */ 00208 if(!collmd->bvhtree) 00209 { 00210 collmd->bvhtree = bvhtree_build_from_mvert(collmd->mfaces, collmd->numfaces, collmd->current_x, numverts, ob->pd->pdef_sboft); 00211 } 00212 else 00213 { 00214 // recalc static bounding boxes 00215 bvhtree_update_from_mvert ( collmd->bvhtree, collmd->mfaces, collmd->numfaces, collmd->current_x, collmd->current_xnew, collmd->numverts, 1 ); 00216 } 00217 00218 collmd->time_xnew = current_time; 00219 } 00220 else if(numverts != collmd->numverts) 00221 { 00222 freeData((ModifierData *)collmd); 00223 } 00224 00225 } 00226 else if(current_time < collmd->time_xnew) 00227 { 00228 freeData((ModifierData *)collmd); 00229 } 00230 else 00231 { 00232 if(numverts != collmd->numverts) 00233 { 00234 freeData((ModifierData *)collmd); 00235 } 00236 } 00237 } 00238 00239 if(dm) 00240 dm->release(dm); 00241 } 00242 00243 00244 ModifierTypeInfo modifierType_Collision = { 00245 /* name */ "Collision", 00246 /* structName */ "CollisionModifierData", 00247 /* structSize */ sizeof(CollisionModifierData), 00248 /* type */ eModifierTypeType_OnlyDeform, 00249 /* flags */ eModifierTypeFlag_AcceptsMesh 00250 | eModifierTypeFlag_Single, 00251 00252 /* copyData */ NULL, 00253 /* deformVerts */ deformVerts, 00254 /* deformMatrices */ NULL, 00255 /* deformVertsEM */ NULL, 00256 /* deformMatricesEM */ NULL, 00257 /* applyModifier */ NULL, 00258 /* applyModifierEM */ NULL, 00259 /* initData */ initData, 00260 /* requiredDataMask */ NULL, 00261 /* freeData */ freeData, 00262 /* isDisabled */ NULL, 00263 /* updateDepgraph */ NULL, 00264 /* dependsOnTime */ dependsOnTime, 00265 /* dependsOnNormals */ NULL, 00266 /* foreachObjectLink */ NULL, 00267 /* foreachIDLink */ NULL, 00268 /* foreachTexLink */ NULL, 00269 };