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