|
Blender
V2.59
|
00001 /* 00002 * $Id: MOD_particleinstance.c 35817 2011-03-27 13:49:53Z campbellbarton $ 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_meshdata_types.h" 00039 00040 #include "MEM_guardedalloc.h" 00041 00042 #include "BLI_math.h" 00043 #include "BLI_listbase.h" 00044 #include "BLI_rand.h" 00045 #include "BLI_utildefines.h" 00046 00047 #include "BKE_cdderivedmesh.h" 00048 #include "BKE_lattice.h" 00049 #include "BKE_modifier.h" 00050 #include "BKE_particle.h" 00051 #include "BKE_pointcache.h" 00052 00053 #include "MOD_util.h" 00054 00055 #include "depsgraph_private.h" 00056 00057 00058 static void initData(ModifierData *md) 00059 { 00060 ParticleInstanceModifierData *pimd= (ParticleInstanceModifierData*) md; 00061 00062 pimd->flag = eParticleInstanceFlag_Parents|eParticleInstanceFlag_Unborn| 00063 eParticleInstanceFlag_Alive|eParticleInstanceFlag_Dead; 00064 pimd->psys = 1; 00065 pimd->position = 1.0f; 00066 pimd->axis = 2; 00067 00068 } 00069 static void copyData(ModifierData *md, ModifierData *target) 00070 { 00071 ParticleInstanceModifierData *pimd= (ParticleInstanceModifierData*) md; 00072 ParticleInstanceModifierData *tpimd= (ParticleInstanceModifierData*) target; 00073 00074 tpimd->ob = pimd->ob; 00075 tpimd->psys = pimd->psys; 00076 tpimd->flag = pimd->flag; 00077 tpimd->axis = pimd->axis; 00078 tpimd->position = pimd->position; 00079 tpimd->random_position = pimd->random_position; 00080 } 00081 00082 static int dependsOnTime(ModifierData *UNUSED(md)) 00083 { 00084 return 0; 00085 } 00086 static void updateDepgraph(ModifierData *md, DagForest *forest, 00087 struct Scene *UNUSED(scene), 00088 Object *UNUSED(ob), 00089 DagNode *obNode) 00090 { 00091 ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData*) md; 00092 00093 if (pimd->ob) { 00094 DagNode *curNode = dag_get_node(forest, pimd->ob); 00095 00096 dag_add_relation(forest, curNode, obNode, 00097 DAG_RL_DATA_DATA | DAG_RL_OB_DATA, 00098 "Particle Instance Modifier"); 00099 } 00100 } 00101 00102 static void foreachObjectLink(ModifierData *md, Object *ob, 00103 ObjectWalkFunc walk, void *userData) 00104 { 00105 ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData*) md; 00106 00107 walk(userData, ob, &pimd->ob); 00108 } 00109 00110 static DerivedMesh * applyModifier(ModifierData *md, Object *ob, 00111 DerivedMesh *derivedData, 00112 int UNUSED(useRenderParams), 00113 int UNUSED(isFinalCalc)) 00114 { 00115 DerivedMesh *dm = derivedData, *result; 00116 ParticleInstanceModifierData *pimd= (ParticleInstanceModifierData*) md; 00117 ParticleSimulationData sim; 00118 ParticleSystem *psys= NULL; 00119 ParticleData *pa= NULL, *pars= NULL; 00120 MFace *mface, *orig_mface; 00121 MVert *mvert, *orig_mvert; 00122 int i,totvert, totpart=0, totface, maxvert, maxface, first_particle=0; 00123 short track=ob->trackflag%3, trackneg, axis = pimd->axis; 00124 float max_co=0.0, min_co=0.0, temp_co[3], cross[3]; 00125 float *size=NULL; 00126 00127 trackneg=((ob->trackflag>2)?1:0); 00128 00129 if(pimd->ob==ob){ 00130 pimd->ob= NULL; 00131 return derivedData; 00132 } 00133 00134 if(pimd->ob){ 00135 psys = BLI_findlink(&pimd->ob->particlesystem,pimd->psys-1); 00136 if(psys==NULL || psys->totpart==0) 00137 return derivedData; 00138 } 00139 else return derivedData; 00140 00141 if(pimd->flag & eParticleInstanceFlag_Parents) 00142 totpart+=psys->totpart; 00143 if(pimd->flag & eParticleInstanceFlag_Children){ 00144 if(totpart==0) 00145 first_particle=psys->totpart; 00146 totpart+=psys->totchild; 00147 } 00148 00149 if(totpart==0) 00150 return derivedData; 00151 00152 sim.scene = md->scene; 00153 sim.ob = pimd->ob; 00154 sim.psys = psys; 00155 sim.psmd = psys_get_modifier(pimd->ob, psys); 00156 00157 if(pimd->flag & eParticleInstanceFlag_UseSize) { 00158 int p; 00159 float *si; 00160 si = size = MEM_callocN(totpart * sizeof(float), "particle size array"); 00161 00162 if(pimd->flag & eParticleInstanceFlag_Parents) { 00163 for(p=0, pa= psys->particles; p<psys->totpart; p++, pa++, si++) 00164 *si = pa->size; 00165 } 00166 00167 if(pimd->flag & eParticleInstanceFlag_Children) { 00168 ChildParticle *cpa = psys->child; 00169 00170 for(p=0; p<psys->totchild; p++, cpa++, si++) { 00171 *si = psys_get_child_size(psys, cpa, 0.0f, NULL); 00172 } 00173 } 00174 } 00175 00176 pars=psys->particles; 00177 00178 totvert=dm->getNumVerts(dm); 00179 totface=dm->getNumFaces(dm); 00180 00181 maxvert=totvert*totpart; 00182 maxface=totface*totpart; 00183 00184 psys->lattice=psys_get_lattice(&sim); 00185 00186 if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED){ 00187 00188 float min_r[3], max_r[3]; 00189 INIT_MINMAX(min_r, max_r); 00190 dm->getMinMax(dm, min_r, max_r); 00191 min_co=min_r[track]; 00192 max_co=max_r[track]; 00193 } 00194 00195 result = CDDM_from_template(dm, maxvert,dm->getNumEdges(dm)*totpart,maxface); 00196 00197 mvert=result->getVertArray(result); 00198 orig_mvert=dm->getVertArray(dm); 00199 00200 for(i=0; i<maxvert; i++){ 00201 MVert *inMV; 00202 MVert *mv = mvert + i; 00203 ParticleKey state; 00204 00205 inMV = orig_mvert + i%totvert; 00206 DM_copy_vert_data(dm, result, i%totvert, i, 1); 00207 *mv = *inMV; 00208 00209 /*change orientation based on object trackflag*/ 00210 copy_v3_v3(temp_co, mv->co); 00211 mv->co[axis]=temp_co[track]; 00212 mv->co[(axis+1)%3]=temp_co[(track+1)%3]; 00213 mv->co[(axis+2)%3]=temp_co[(track+2)%3]; 00214 00215 if((psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) && pimd->flag & eParticleInstanceFlag_Path){ 00216 float ran = 0.0f; 00217 if(pimd->random_position != 0.0f) { 00218 BLI_srandom(psys->seed + (i/totvert)%totpart); 00219 ran = pimd->random_position * BLI_frand(); 00220 } 00221 00222 if(pimd->flag & eParticleInstanceFlag_KeepShape) { 00223 state.time = pimd->position * (1.0f - ran); 00224 } 00225 else { 00226 state.time=(mv->co[axis]-min_co)/(max_co-min_co) * pimd->position * (1.0f - ran); 00227 00228 if(trackneg) 00229 state.time=1.0f-state.time; 00230 00231 mv->co[axis] = 0.0; 00232 } 00233 00234 psys_get_particle_on_path(&sim, first_particle + i/totvert, &state,1); 00235 00236 normalize_v3(state.vel); 00237 00238 /* TODO: incremental rotations somehow */ 00239 if(state.vel[axis] < -0.9999f || state.vel[axis] > 0.9999f) { 00240 state.rot[0] = 1; 00241 state.rot[1] = state.rot[2] = state.rot[3] = 0.0f; 00242 } 00243 else { 00244 float temp[3] = {0.0f,0.0f,0.0f}; 00245 temp[axis] = 1.0f; 00246 00247 cross_v3_v3v3(cross, temp, state.vel); 00248 00249 /* state.vel[axis] is the only component surviving from a dot product with the axis */ 00250 axis_angle_to_quat(state.rot,cross,saacos(state.vel[axis])); 00251 } 00252 00253 } 00254 else{ 00255 state.time=-1.0; 00256 psys_get_particle_state(&sim, first_particle + i/totvert, &state,1); 00257 } 00258 00259 mul_qt_v3(state.rot,mv->co); 00260 if(pimd->flag & eParticleInstanceFlag_UseSize) 00261 mul_v3_fl(mv->co, size[i/totvert]); 00262 VECADD(mv->co,mv->co,state.co); 00263 } 00264 00265 mface=result->getFaceArray(result); 00266 orig_mface=dm->getFaceArray(dm); 00267 00268 for(i=0; i<maxface; i++){ 00269 MFace *inMF; 00270 MFace *mf = mface + i; 00271 00272 if(pimd->flag & eParticleInstanceFlag_Parents){ 00273 if(i/totface>=psys->totpart){ 00274 if(psys->part->childtype==PART_CHILD_PARTICLES) 00275 pa=psys->particles+(psys->child+i/totface-psys->totpart)->parent; 00276 else 00277 pa= NULL; 00278 } 00279 else 00280 pa=pars+i/totface; 00281 } 00282 else{ 00283 if(psys->part->childtype==PART_CHILD_PARTICLES) 00284 pa=psys->particles+(psys->child+i/totface)->parent; 00285 else 00286 pa= NULL; 00287 } 00288 00289 if(pa){ 00290 if(pa->alive==PARS_UNBORN && (pimd->flag&eParticleInstanceFlag_Unborn)==0) continue; 00291 if(pa->alive==PARS_ALIVE && (pimd->flag&eParticleInstanceFlag_Alive)==0) continue; 00292 if(pa->alive==PARS_DEAD && (pimd->flag&eParticleInstanceFlag_Dead)==0) continue; 00293 } 00294 00295 inMF = orig_mface + i%totface; 00296 DM_copy_face_data(dm, result, i%totface, i, 1); 00297 *mf = *inMF; 00298 00299 mf->v1+=(i/totface)*totvert; 00300 mf->v2+=(i/totface)*totvert; 00301 mf->v3+=(i/totface)*totvert; 00302 if(mf->v4) 00303 mf->v4+=(i/totface)*totvert; 00304 } 00305 00306 CDDM_calc_edges(result); 00307 CDDM_calc_normals(result); 00308 00309 if(psys->lattice){ 00310 end_latt_deform(psys->lattice); 00311 psys->lattice= NULL; 00312 } 00313 00314 if(size) 00315 MEM_freeN(size); 00316 00317 return result; 00318 } 00319 static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, 00320 struct EditMesh *UNUSED(editData), 00321 DerivedMesh *derivedData) 00322 { 00323 return applyModifier(md, ob, derivedData, 0, 1); 00324 } 00325 00326 00327 ModifierTypeInfo modifierType_ParticleInstance = { 00328 /* name */ "ParticleInstance", 00329 /* structName */ "ParticleInstanceModifierData", 00330 /* structSize */ sizeof(ParticleInstanceModifierData), 00331 /* type */ eModifierTypeType_Constructive, 00332 /* flags */ eModifierTypeFlag_AcceptsMesh 00333 | eModifierTypeFlag_SupportsMapping 00334 | eModifierTypeFlag_SupportsEditmode 00335 | eModifierTypeFlag_EnableInEditmode, 00336 00337 /* copyData */ copyData, 00338 /* deformVerts */ NULL, 00339 /* deformMatrices */ NULL, 00340 /* deformVertsEM */ NULL, 00341 /* deformMatricesEM */ NULL, 00342 /* applyModifier */ applyModifier, 00343 /* applyModifierEM */ applyModifierEM, 00344 /* initData */ initData, 00345 /* requiredDataMask */ NULL, 00346 /* freeData */ NULL, 00347 /* isDisabled */ NULL, 00348 /* updateDepgraph */ updateDepgraph, 00349 /* dependsOnTime */ dependsOnTime, 00350 /* dependsOnNormals */ NULL, 00351 /* foreachObjectLink */ foreachObjectLink, 00352 /* foreachIDLink */ NULL, 00353 };