Merge branch 'master' into blender2.8
[blender.git] / source / blender / modifiers / intern / MOD_particleinstance.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software  Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2005 by the Blender Foundation.
19  * All rights reserved.
20  *
21  * Contributor(s): Daniel Dunbar
22  *                 Ton Roosendaal,
23  *                 Ben Batt,
24  *                 Brecht Van Lommel,
25  *                 Campbell Barton
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  *
29  */
30
31 /** \file blender/modifiers/intern/MOD_particleinstance.c
32  *  \ingroup modifiers
33  */
34
35
36 #include "DNA_meshdata_types.h"
37
38 #include "MEM_guardedalloc.h"
39
40 #include "BLI_math.h"
41 #include "BLI_listbase.h"
42 #include "BLI_rand.h"
43 #include "BLI_string.h"
44 #include "BLI_utildefines.h"
45
46 #include "BKE_cdderivedmesh.h"
47 #include "BKE_effect.h"
48 #include "BKE_global.h"
49 #include "BKE_lattice.h"
50 #include "BKE_library_query.h"
51 #include "BKE_modifier.h"
52 #include "BKE_particle.h"
53 #include "BKE_pointcache.h"
54
55 #include "DEG_depsgraph_build.h"
56
57 static void initData(ModifierData *md)
58 {
59         ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *) md;
60
61         pimd->flag = eParticleInstanceFlag_Parents | eParticleInstanceFlag_Unborn |
62                      eParticleInstanceFlag_Alive | eParticleInstanceFlag_Dead;
63         pimd->psys = 1;
64         pimd->position = 1.0f;
65         pimd->axis = 2;
66         pimd->space = eParticleInstanceSpace_World;
67         pimd->particle_amount = 1.0f;
68         pimd->particle_offset = 0.0f;
69
70         STRNCPY(pimd->index_layer_name, "");
71         STRNCPY(pimd->value_layer_name, "");
72 }
73 static void copyData(ModifierData *md, ModifierData *target)
74 {
75 #if 0
76         ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *) md;
77         ParticleInstanceModifierData *tpimd = (ParticleInstanceModifierData *) target;
78 #endif
79         modifier_copyData_generic(md, target);
80 }
81
82 static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
83 {
84         ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
85         CustomDataMask dataMask = 0;
86
87         if (pimd->index_layer_name[0] != '\0' ||
88             pimd->value_layer_name[0] != '\0')
89         {
90                 dataMask |= CD_MASK_MLOOPCOL;
91         }
92
93         return dataMask;
94
95 }
96
97 static bool isDisabled(ModifierData *md, int useRenderParams)
98 {
99         ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
100         ParticleSystem *psys;
101         ModifierData *ob_md;
102
103         if (!pimd->ob)
104                 return true;
105
106         psys = BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1);
107         if (psys == NULL)
108                 return true;
109
110         /* If the psys modifier is disabled we cannot use its data.
111          * First look up the psys modifier from the object, then check if it is enabled.
112          */
113         for (ob_md = pimd->ob->modifiers.first; ob_md; ob_md = ob_md->next) {
114                 if (ob_md->type == eModifierType_ParticleSystem) {
115                         ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)ob_md;
116                         if (psmd->psys == psys) {
117                                 int required_mode;
118
119                                 if (useRenderParams) required_mode = eModifierMode_Render;
120                                 else required_mode = eModifierMode_Realtime;
121
122                                 if (!modifier_isEnabled(md->scene, ob_md, required_mode))
123                                         return true;
124
125                                 break;
126                         }
127                 }
128         }
129
130         return false;
131 }
132
133 static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
134 {
135         ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *) md;
136         if (pimd->ob != NULL) {
137                 DEG_add_object_relation(ctx->node, pimd->ob, DEG_OB_COMP_TRANSFORM, "Particle Instance Modifier");
138                 DEG_add_object_relation(ctx->node, pimd->ob, DEG_OB_COMP_GEOMETRY, "Particle Instance Modifier");
139         }
140 }
141
142 static void foreachObjectLink(ModifierData *md, Object *ob,
143                               ObjectWalkFunc walk, void *userData)
144 {
145         ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *) md;
146
147         walk(userData, ob, &pimd->ob, IDWALK_CB_NOP);
148 }
149
150 static bool particle_skip(ParticleInstanceModifierData *pimd, ParticleSystem *psys, int p)
151 {
152         const bool between = (psys->part->childtype == PART_CHILD_FACES);
153         ParticleData *pa;
154         int totpart, randp, minp, maxp;
155
156         if (p >= psys->totpart) {
157                 ChildParticle *cpa = psys->child + (p - psys->totpart);
158                 pa = psys->particles + (between? cpa->pa[0]: cpa->parent);
159         }
160         else {
161                 pa = psys->particles + p;
162         }
163
164         if (pa) {
165                 if (pa->alive == PARS_UNBORN && (pimd->flag & eParticleInstanceFlag_Unborn) == 0) return true;
166                 if (pa->alive == PARS_ALIVE && (pimd->flag & eParticleInstanceFlag_Alive) == 0) return true;
167                 if (pa->alive == PARS_DEAD && (pimd->flag & eParticleInstanceFlag_Dead) == 0) return true;
168         }
169
170         if (pimd->particle_amount == 1.0f) {
171                 /* Early output, all particles are to be instanced. */
172                 return false;
173         }
174
175         /* Randomly skip particles based on desired amount of visible particles. */
176
177         totpart = psys->totpart + psys->totchild;
178
179         /* TODO make randomization optional? */
180         randp = (int)(psys_frand(psys, 3578 + p) * totpart) % totpart;
181
182         minp = (int)(totpart * pimd->particle_offset) % (totpart+1);
183         maxp = (int)(totpart * (pimd->particle_offset + pimd->particle_amount)) % (totpart+1);
184
185         if (maxp > minp) {
186                 return randp < minp || randp >= maxp;
187         }
188         else if (maxp < minp) {
189                 return randp < minp && randp >= maxp;
190         }
191         else {
192                 return true;
193         }
194
195         return false;
196 }
197
198 static void store_float_in_vcol(MLoopCol *vcol, float float_value)
199 {
200         const uchar value = FTOCHAR(float_value);
201         vcol->r = vcol->g = vcol->b = value;
202         vcol->a = 1.0f;
203 }
204
205 static DerivedMesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx,
206                                   DerivedMesh *derivedData)
207 {
208         DerivedMesh *dm = derivedData, *result;
209         ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *) md;
210         ParticleSimulationData sim;
211         ParticleSystem *psys = NULL;
212         ParticleData *pa = NULL;
213         MPoly *mpoly, *orig_mpoly;
214         MLoop *mloop, *orig_mloop;
215         MVert *mvert, *orig_mvert;
216         int totvert, totpoly, totloop , totedge;
217         int maxvert, maxpoly, maxloop, maxedge, part_end = 0, part_start;
218         int k, p, p_skip;
219         short track = ctx->object->trackflag % 3, trackneg, axis = pimd->axis;
220         float max_co = 0.0, min_co = 0.0, temp_co[3];
221         float *size = NULL;
222         float spacemat[4][4];
223         const bool use_parents = pimd->flag & eParticleInstanceFlag_Parents;
224         const bool use_children = pimd->flag & eParticleInstanceFlag_Children;
225         bool between;
226
227         trackneg = ((ctx->object->trackflag > 2) ? 1 : 0);
228
229         if (pimd->ob == ctx->object) {
230                 pimd->ob = NULL;
231                 return derivedData;
232         }
233
234         if (pimd->ob) {
235                 psys = BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1);
236                 if (psys == NULL || psys->totpart == 0)
237                         return derivedData;
238         }
239         else {
240                 return derivedData;
241         }
242
243         part_start = use_parents ? 0 : psys->totpart;
244
245         part_end = 0;
246         if (use_parents)
247                 part_end += psys->totpart;
248         if (use_children)
249                 part_end += psys->totchild;
250
251         if (part_end == 0)
252                 return derivedData;
253
254         sim.depsgraph = ctx->depsgraph;
255         sim.scene = md->scene;
256         sim.ob = pimd->ob;
257         sim.psys = psys;
258         sim.psmd = psys_get_modifier(pimd->ob, psys);
259         between = (psys->part->childtype == PART_CHILD_FACES);
260
261         if (pimd->flag & eParticleInstanceFlag_UseSize) {
262                 float *si;
263                 si = size = MEM_calloc_arrayN(part_end, sizeof(float), "particle size array");
264
265                 if (pimd->flag & eParticleInstanceFlag_Parents) {
266                         for (p = 0, pa = psys->particles; p < psys->totpart; p++, pa++, si++)
267                                 *si = pa->size;
268                 }
269
270                 if (pimd->flag & eParticleInstanceFlag_Children) {
271                         ChildParticle *cpa = psys->child;
272
273                         for (p = 0; p < psys->totchild; p++, cpa++, si++) {
274                                 *si = psys_get_child_size(psys, cpa, 0.0f, NULL);
275                         }
276                 }
277         }
278
279         switch (pimd->space) {
280                 case eParticleInstanceSpace_World:
281                         /* particle states are in world space already */
282                         unit_m4(spacemat);
283                         break;
284                 case eParticleInstanceSpace_Local:
285                         /* get particle states in the particle object's local space */
286                         invert_m4_m4(spacemat, pimd->ob->obmat);
287                         break;
288                 default:
289                         /* should not happen */
290                         BLI_assert(false);
291                         break;
292         }
293
294         totvert = dm->getNumVerts(dm);
295         totpoly = dm->getNumPolys(dm);
296         totloop = dm->getNumLoops(dm);
297         totedge = dm->getNumEdges(dm);
298
299         /* count particles */
300         maxvert = 0;
301         maxpoly = 0;
302         maxloop = 0;
303         maxedge = 0;
304
305         for (p = part_start; p < part_end; p++) {
306                 if (particle_skip(pimd, psys, p))
307                         continue;
308
309                 maxvert += totvert;
310                 maxpoly += totpoly;
311                 maxloop += totloop;
312                 maxedge += totedge;
313         }
314
315         psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
316
317         if (psys->flag & (PSYS_HAIR_DONE | PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) {
318                 float min[3], max[3];
319                 INIT_MINMAX(min, max);
320                 dm->getMinMax(dm, min, max);
321                 min_co = min[track];
322                 max_co = max[track];
323         }
324
325         result = CDDM_from_template(dm, maxvert, maxedge, 0, maxloop, maxpoly);
326
327         mvert = result->getVertArray(result);
328         orig_mvert = dm->getVertArray(dm);
329         mpoly = result->getPolyArray(result);
330         orig_mpoly = dm->getPolyArray(dm);
331         mloop = result->getLoopArray(result);
332         orig_mloop = dm->getLoopArray(dm);
333
334         MLoopCol *mloopcols_index = CustomData_get_layer_named(&result->loopData, CD_MLOOPCOL, pimd->index_layer_name);
335         MLoopCol *mloopcols_value = CustomData_get_layer_named(&result->loopData, CD_MLOOPCOL, pimd->value_layer_name);
336         int *vert_part_index = NULL;
337         float *vert_part_value = NULL;
338         if (mloopcols_index != NULL) {
339                 vert_part_index = MEM_calloc_arrayN(maxvert, sizeof(int), "vertex part index array");
340         }
341         if (mloopcols_value) {
342                 vert_part_value = MEM_calloc_arrayN(maxvert, sizeof(float), "vertex part value array");
343         }
344
345         for (p = part_start, p_skip = 0; p < part_end; p++) {
346                 float prev_dir[3];
347                 float frame[4]; /* frame orientation quaternion */
348                 float p_random = psys_frand(psys, 77091 + 283*p);
349
350                 /* skip particle? */
351                 if (particle_skip(pimd, psys, p))
352                         continue;
353
354                 /* set vertices coordinates */
355                 for (k = 0; k < totvert; k++) {
356                         ParticleKey state;
357                         MVert *inMV;
358                         int vindex = p_skip * totvert + k;
359                         MVert *mv = mvert + vindex;
360
361                         inMV = orig_mvert + k;
362                         DM_copy_vert_data(dm, result, k, p_skip * totvert + k, 1);
363                         *mv = *inMV;
364
365                         if (vert_part_index != NULL) {
366                                 vert_part_index[vindex] = p;
367                         }
368                         if (vert_part_value != NULL) {
369                                 vert_part_value[vindex] = p_random;
370                         }
371
372                         /*change orientation based on object trackflag*/
373                         copy_v3_v3(temp_co, mv->co);
374                         mv->co[axis] = temp_co[track];
375                         mv->co[(axis + 1) % 3] = temp_co[(track + 1) % 3];
376                         mv->co[(axis + 2) % 3] = temp_co[(track + 2) % 3];
377
378                         /* get particle state */
379                         if ((psys->flag & (PSYS_HAIR_DONE | PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) &&
380                             (pimd->flag & eParticleInstanceFlag_Path))
381                         {
382                                 float ran = 0.0f;
383                                 if (pimd->random_position != 0.0f) {
384                                         ran = pimd->random_position * BLI_hash_frand(psys->seed + p);
385                                 }
386
387                                 if (pimd->flag & eParticleInstanceFlag_KeepShape) {
388                                         state.time = pimd->position * (1.0f - ran);
389                                 }
390                                 else {
391                                         state.time = (mv->co[axis] - min_co) / (max_co - min_co) * pimd->position * (1.0f - ran);
392
393                                         if (trackneg)
394                                                 state.time = 1.0f - state.time;
395
396                                         mv->co[axis] = 0.0;
397                                 }
398
399                                 psys_get_particle_on_path(&sim, p, &state, 1);
400
401                                 normalize_v3(state.vel);
402
403                                 /* Incrementally Rotating Frame (Bishop Frame) */
404                                 if (k == 0) {
405                                         float hairmat[4][4];
406                                         float mat[3][3];
407
408                                         if (p < psys->totpart)
409                                                 pa = psys->particles + p;
410                                         else {
411                                                 ChildParticle *cpa = psys->child + (p - psys->totpart);
412                                                 pa = psys->particles + (between? cpa->pa[0]: cpa->parent);
413                                         }
414                                         psys_mat_hair_to_global(sim.ob, sim.psmd->dm_final, sim.psys->part->from, pa, hairmat);
415                                         copy_m3_m4(mat, hairmat);
416                                         /* to quaternion */
417                                         mat3_to_quat(frame, mat);
418
419                                         if (pimd->rotation > 0.0f || pimd->random_rotation > 0.0f) {
420                                                 float angle = 2.0f*M_PI * (pimd->rotation + pimd->random_rotation * (psys_frand(psys, 19957323 + p) - 0.5f));
421                                                 float eul[3] = { 0.0f, 0.0f, angle };
422                                                 float rot[4];
423
424                                                 eul_to_quat(rot, eul);
425                                                 mul_qt_qtqt(frame, frame, rot);
426                                         }
427
428                                         /* note: direction is same as normal vector currently,
429                                          * but best to keep this separate so the frame can be
430                                          * rotated later if necessary
431                                          */
432                                         copy_v3_v3(prev_dir, state.vel);
433                                 }
434                                 else {
435                                         float rot[4];
436
437                                         /* incrementally rotate along bend direction */
438                                         rotation_between_vecs_to_quat(rot, prev_dir, state.vel);
439                                         mul_qt_qtqt(frame, rot, frame);
440
441                                         copy_v3_v3(prev_dir, state.vel);
442                                 }
443
444                                 copy_qt_qt(state.rot, frame);
445 #if 0
446                                 /* Absolute Frame (Frenet Frame) */
447                                 if (state.vel[axis] < -0.9999f || state.vel[axis] > 0.9999f) {
448                                         unit_qt(state.rot);
449                                 }
450                                 else {
451                                         float cross[3];
452                                         float temp[3] = {0.0f, 0.0f, 0.0f};
453                                         temp[axis] = 1.0f;
454
455                                         cross_v3_v3v3(cross, temp, state.vel);
456
457                                         /* state.vel[axis] is the only component surviving from a dot product with the axis */
458                                         axis_angle_to_quat(state.rot, cross, saacos(state.vel[axis]));
459                                 }
460 #endif
461                         }
462                         else {
463                                 state.time = -1.0;
464                                 psys_get_particle_state(&sim, p, &state, 1);
465                         }
466
467                         mul_qt_v3(state.rot, mv->co);
468                         if (pimd->flag & eParticleInstanceFlag_UseSize)
469                                 mul_v3_fl(mv->co, size[p]);
470                         add_v3_v3(mv->co, state.co);
471
472                         mul_m4_v3(spacemat, mv->co);
473                 }
474
475                 /* create edges and adjust edge vertex indices*/
476                 DM_copy_edge_data(dm, result, 0, p_skip * totedge, totedge);
477                 MEdge *me = CDDM_get_edges(result) + p_skip * totedge;
478                 for (k = 0; k < totedge; k++, me++) {
479                         me->v1 += p_skip * totvert;
480                         me->v2 += p_skip * totvert;
481                 }
482
483                 /* create polys and loops */
484                 for (k = 0; k < totpoly; k++) {
485
486                         MPoly *inMP = orig_mpoly + k;
487                         MPoly *mp = mpoly + p_skip * totpoly + k;
488
489                         DM_copy_poly_data(dm, result, k, p_skip * totpoly + k, 1);
490                         *mp = *inMP;
491                         mp->loopstart += p_skip * totloop;
492
493                         {
494                                 MLoop *inML = orig_mloop + inMP->loopstart;
495                                 MLoop *ml = mloop + mp->loopstart;
496                                 int j = mp->totloop;
497
498                                 DM_copy_loop_data(dm, result, inMP->loopstart, mp->loopstart, j);
499                                 for (; j; j--, ml++, inML++) {
500                                         ml->v = inML->v + (p_skip * totvert);
501                                         ml->e = inML->e + (p_skip * totedge);
502                                         const int ml_index = (ml - mloop);
503                                         if (mloopcols_index != NULL) {
504                                                 const int part_index = vert_part_index[ml->v];
505                                                 store_float_in_vcol(&mloopcols_index[ml_index], (float)part_index / psys->totpart);
506                                         }
507                                         if (mloopcols_value != NULL) {
508                                                 const float part_value = vert_part_value[ml->v];
509                                                 store_float_in_vcol(&mloopcols_value[ml_index], part_value);
510                                         }
511                                 }
512                         }
513                 }
514                 p_skip++;
515         }
516
517         if (psys->lattice_deform_data) {
518                 end_latt_deform(psys->lattice_deform_data);
519                 psys->lattice_deform_data = NULL;
520         }
521
522         if (size)
523                 MEM_freeN(size);
524
525         MEM_SAFE_FREE(vert_part_index);
526         MEM_SAFE_FREE(vert_part_value);
527
528         result->dirty |= DM_DIRTY_NORMALS;
529
530         return result;
531 }
532 ModifierTypeInfo modifierType_ParticleInstance = {
533         /* name */              "ParticleInstance",
534         /* structName */        "ParticleInstanceModifierData",
535         /* structSize */        sizeof(ParticleInstanceModifierData),
536         /* type */              eModifierTypeType_Constructive,
537         /* flags */             eModifierTypeFlag_AcceptsMesh |
538                                 eModifierTypeFlag_SupportsMapping |
539                                 eModifierTypeFlag_SupportsEditmode |
540                                 eModifierTypeFlag_EnableInEditmode,
541
542         /* copyData */          copyData,
543
544         /* deformVerts_DM */    NULL,
545         /* deformMatrices_DM */ NULL,
546         /* deformVertsEM_DM */  NULL,
547         /* deformMatricesEM_DM*/NULL,
548         /* applyModifier_DM */  applyModifier,
549         /* applyModifierEM_DM */NULL,
550
551         /* deformVerts */       NULL,
552         /* deformMatrices */    NULL,
553         /* deformVertsEM */     NULL,
554         /* deformMatricesEM */  NULL,
555         /* applyModifier */     NULL,
556         /* applyModifierEM */   NULL,
557
558         /* initData */          initData,
559         /* requiredDataMask */  requiredDataMask,
560         /* freeData */          NULL,
561         /* isDisabled */        isDisabled,
562         /* updateDepsgraph */   updateDepsgraph,
563         /* dependsOnTime */     NULL,
564         /* dependsOnNormals */  NULL,
565         /* foreachObjectLink */ foreachObjectLink,
566         /* foreachIDLink */     NULL,
567         /* foreachTexLink */    NULL,
568 };