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