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