Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/modifiers/intern/MOD_particleinstance.c
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/modifiers/intern/MOD_particleinstance.c')
-rw-r--r--source/blender/modifiers/intern/MOD_particleinstance.c929
1 files changed, 467 insertions, 462 deletions
diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c
index 189255a7dd1..718c1e6a038 100644
--- a/source/blender/modifiers/intern/MOD_particleinstance.c
+++ b/source/blender/modifiers/intern/MOD_particleinstance.c
@@ -48,497 +48,502 @@
static void initData(ModifierData *md)
{
- ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *) md;
-
- pimd->flag = eParticleInstanceFlag_Parents | eParticleInstanceFlag_Unborn |
- eParticleInstanceFlag_Alive | eParticleInstanceFlag_Dead;
- pimd->psys = 1;
- pimd->position = 1.0f;
- pimd->axis = 2;
- pimd->space = eParticleInstanceSpace_World;
- pimd->particle_amount = 1.0f;
- pimd->particle_offset = 0.0f;
-
- STRNCPY(pimd->index_layer_name, "");
- STRNCPY(pimd->value_layer_name, "");
+ ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
+
+ pimd->flag = eParticleInstanceFlag_Parents | eParticleInstanceFlag_Unborn |
+ eParticleInstanceFlag_Alive | eParticleInstanceFlag_Dead;
+ pimd->psys = 1;
+ pimd->position = 1.0f;
+ pimd->axis = 2;
+ pimd->space = eParticleInstanceSpace_World;
+ pimd->particle_amount = 1.0f;
+ pimd->particle_offset = 0.0f;
+
+ STRNCPY(pimd->index_layer_name, "");
+ STRNCPY(pimd->value_layer_name, "");
}
-static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
+static void requiredDataMask(Object *UNUSED(ob),
+ ModifierData *md,
+ CustomData_MeshMasks *r_cddata_masks)
{
- ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
+ ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
- if (pimd->index_layer_name[0] != '\0' ||
- pimd->value_layer_name[0] != '\0')
- {
- r_cddata_masks->lmask |= CD_MASK_MLOOPCOL;
- }
+ if (pimd->index_layer_name[0] != '\0' || pimd->value_layer_name[0] != '\0') {
+ r_cddata_masks->lmask |= CD_MASK_MLOOPCOL;
+ }
}
static bool isDisabled(const struct Scene *scene, ModifierData *md, bool useRenderParams)
{
- ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
- ParticleSystem *psys;
- ModifierData *ob_md;
-
- if (!pimd->ob)
- return true;
-
- psys = BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1);
- if (psys == NULL)
- return true;
-
- /* If the psys modifier is disabled we cannot use its data.
- * First look up the psys modifier from the object, then check if it is enabled.
- */
- for (ob_md = pimd->ob->modifiers.first; ob_md; ob_md = ob_md->next) {
- if (ob_md->type == eModifierType_ParticleSystem) {
- ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)ob_md;
- if (psmd->psys == psys) {
- int required_mode;
-
- if (useRenderParams) required_mode = eModifierMode_Render;
- else required_mode = eModifierMode_Realtime;
-
- if (!modifier_isEnabled(scene, ob_md, required_mode))
- return true;
-
- break;
- }
- }
- }
-
- return false;
+ ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
+ ParticleSystem *psys;
+ ModifierData *ob_md;
+
+ if (!pimd->ob)
+ return true;
+
+ psys = BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1);
+ if (psys == NULL)
+ return true;
+
+ /* If the psys modifier is disabled we cannot use its data.
+ * First look up the psys modifier from the object, then check if it is enabled.
+ */
+ for (ob_md = pimd->ob->modifiers.first; ob_md; ob_md = ob_md->next) {
+ if (ob_md->type == eModifierType_ParticleSystem) {
+ ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)ob_md;
+ if (psmd->psys == psys) {
+ int required_mode;
+
+ if (useRenderParams)
+ required_mode = eModifierMode_Render;
+ else
+ required_mode = eModifierMode_Realtime;
+
+ if (!modifier_isEnabled(scene, ob_md, required_mode))
+ return true;
+
+ break;
+ }
+ }
+ }
+
+ return false;
}
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
- ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *) md;
- if (pimd->ob != NULL) {
- DEG_add_object_relation(ctx->node, pimd->ob, DEG_OB_COMP_TRANSFORM, "Particle Instance Modifier");
- DEG_add_object_relation(ctx->node, pimd->ob, DEG_OB_COMP_GEOMETRY, "Particle Instance Modifier");
- }
+ ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
+ if (pimd->ob != NULL) {
+ DEG_add_object_relation(
+ ctx->node, pimd->ob, DEG_OB_COMP_TRANSFORM, "Particle Instance Modifier");
+ DEG_add_object_relation(
+ ctx->node, pimd->ob, DEG_OB_COMP_GEOMETRY, "Particle Instance Modifier");
+ }
}
-static void foreachObjectLink(
- ModifierData *md, Object *ob,
- ObjectWalkFunc walk, void *userData)
+static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
{
- ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *) md;
+ ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
- walk(userData, ob, &pimd->ob, IDWALK_CB_NOP);
+ walk(userData, ob, &pimd->ob, IDWALK_CB_NOP);
}
static bool particle_skip(ParticleInstanceModifierData *pimd, ParticleSystem *psys, int p)
{
- const bool between = (psys->part->childtype == PART_CHILD_FACES);
- ParticleData *pa;
- int totpart, randp, minp, maxp;
-
- if (p >= psys->totpart) {
- ChildParticle *cpa = psys->child + (p - psys->totpart);
- pa = psys->particles + (between ? cpa->pa[0] : cpa->parent);
- }
- else {
- pa = psys->particles + p;
- }
-
- if (pa) {
- if (pa->alive == PARS_UNBORN && (pimd->flag & eParticleInstanceFlag_Unborn) == 0) return true;
- if (pa->alive == PARS_ALIVE && (pimd->flag & eParticleInstanceFlag_Alive) == 0) return true;
- if (pa->alive == PARS_DEAD && (pimd->flag & eParticleInstanceFlag_Dead) == 0) return true;
- }
-
- if (pimd->particle_amount == 1.0f) {
- /* Early output, all particles are to be instanced. */
- return false;
- }
-
- /* Randomly skip particles based on desired amount of visible particles. */
-
- totpart = psys->totpart + psys->totchild;
-
- /* TODO make randomization optional? */
- randp = (int)(psys_frand(psys, 3578 + p) * totpart) % totpart;
-
- minp = (int)(totpart * pimd->particle_offset) % (totpart + 1);
- maxp = (int)(totpart * (pimd->particle_offset + pimd->particle_amount)) % (totpart + 1);
-
- if (maxp > minp) {
- return randp < minp || randp >= maxp;
- }
- else if (maxp < minp) {
- return randp < minp && randp >= maxp;
- }
- else {
- return true;
- }
-
- return false;
+ const bool between = (psys->part->childtype == PART_CHILD_FACES);
+ ParticleData *pa;
+ int totpart, randp, minp, maxp;
+
+ if (p >= psys->totpart) {
+ ChildParticle *cpa = psys->child + (p - psys->totpart);
+ pa = psys->particles + (between ? cpa->pa[0] : cpa->parent);
+ }
+ else {
+ pa = psys->particles + p;
+ }
+
+ if (pa) {
+ if (pa->alive == PARS_UNBORN && (pimd->flag & eParticleInstanceFlag_Unborn) == 0)
+ return true;
+ if (pa->alive == PARS_ALIVE && (pimd->flag & eParticleInstanceFlag_Alive) == 0)
+ return true;
+ if (pa->alive == PARS_DEAD && (pimd->flag & eParticleInstanceFlag_Dead) == 0)
+ return true;
+ }
+
+ if (pimd->particle_amount == 1.0f) {
+ /* Early output, all particles are to be instanced. */
+ return false;
+ }
+
+ /* Randomly skip particles based on desired amount of visible particles. */
+
+ totpart = psys->totpart + psys->totchild;
+
+ /* TODO make randomization optional? */
+ randp = (int)(psys_frand(psys, 3578 + p) * totpart) % totpart;
+
+ minp = (int)(totpart * pimd->particle_offset) % (totpart + 1);
+ maxp = (int)(totpart * (pimd->particle_offset + pimd->particle_amount)) % (totpart + 1);
+
+ if (maxp > minp) {
+ return randp < minp || randp >= maxp;
+ }
+ else if (maxp < minp) {
+ return randp < minp && randp >= maxp;
+ }
+ else {
+ return true;
+ }
+
+ return false;
}
static void store_float_in_vcol(MLoopCol *vcol, float float_value)
{
- const uchar value = unit_float_to_uchar_clamp(float_value);
- vcol->r = vcol->g = vcol->b = value;
- vcol->a = 1.0f;
+ const uchar value = unit_float_to_uchar_clamp(float_value);
+ vcol->r = vcol->g = vcol->b = value;
+ vcol->a = 1.0f;
}
-static Mesh *applyModifier(
- ModifierData *md, const ModifierEvalContext *ctx,
- Mesh *mesh)
+static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
- Mesh *result;
- ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *) md;
- struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- ParticleSimulationData sim;
- ParticleSystem *psys = NULL;
- ParticleData *pa = NULL;
- MPoly *mpoly, *orig_mpoly;
- MLoop *mloop, *orig_mloop;
- MVert *mvert, *orig_mvert;
- int totvert, totpoly, totloop, totedge;
- int maxvert, maxpoly, maxloop, maxedge, part_end = 0, part_start;
- int k, p, p_skip;
- short track = ctx->object->trackflag % 3, trackneg, axis = pimd->axis;
- float max_co = 0.0, min_co = 0.0, temp_co[3];
- float *size = NULL;
- float spacemat[4][4];
- const bool use_parents = pimd->flag & eParticleInstanceFlag_Parents;
- const bool use_children = pimd->flag & eParticleInstanceFlag_Children;
- bool between;
-
- trackneg = ((ctx->object->trackflag > 2) ? 1 : 0);
-
- if (pimd->ob == ctx->object) {
- pimd->ob = NULL;
- return mesh;
- }
-
- if (pimd->ob) {
- psys = BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1);
- if (psys == NULL || psys->totpart == 0)
- return mesh;
- }
- else {
- return mesh;
- }
-
- part_start = use_parents ? 0 : psys->totpart;
-
- part_end = 0;
- if (use_parents)
- part_end += psys->totpart;
- if (use_children)
- part_end += psys->totchild;
-
- if (part_end == 0)
- return mesh;
-
- sim.depsgraph = ctx->depsgraph;
- sim.scene = scene;
- sim.ob = pimd->ob;
- sim.psys = psys;
- sim.psmd = psys_get_modifier(pimd->ob, psys);
- between = (psys->part->childtype == PART_CHILD_FACES);
-
- if (pimd->flag & eParticleInstanceFlag_UseSize) {
- float *si;
- si = size = MEM_calloc_arrayN(part_end, sizeof(float), "particle size array");
-
- if (pimd->flag & eParticleInstanceFlag_Parents) {
- for (p = 0, pa = psys->particles; p < psys->totpart; p++, pa++, si++)
- *si = pa->size;
- }
-
- if (pimd->flag & eParticleInstanceFlag_Children) {
- ChildParticle *cpa = psys->child;
-
- for (p = 0; p < psys->totchild; p++, cpa++, si++) {
- *si = psys_get_child_size(psys, cpa, 0.0f, NULL);
- }
- }
- }
-
- switch (pimd->space) {
- case eParticleInstanceSpace_World:
- /* particle states are in world space already */
- unit_m4(spacemat);
- break;
- case eParticleInstanceSpace_Local:
- /* get particle states in the particle object's local space */
- invert_m4_m4(spacemat, pimd->ob->obmat);
- break;
- default:
- /* should not happen */
- BLI_assert(false);
- break;
- }
-
- totvert = mesh->totvert;
- totpoly = mesh->totpoly;
- totloop = mesh->totloop;
- totedge = mesh->totedge;
-
- /* count particles */
- maxvert = 0;
- maxpoly = 0;
- maxloop = 0;
- maxedge = 0;
-
- for (p = part_start; p < part_end; p++) {
- if (particle_skip(pimd, psys, p))
- continue;
-
- maxvert += totvert;
- maxpoly += totpoly;
- maxloop += totloop;
- maxedge += totedge;
- }
-
- psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
-
- if (psys->flag & (PSYS_HAIR_DONE | PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) {
- float min[3], max[3];
- INIT_MINMAX(min, max);
- BKE_mesh_minmax(mesh, min, max);
- min_co = min[track];
- max_co = max[track];
- }
-
- result = BKE_mesh_new_nomain_from_template(mesh, maxvert, maxedge, 0, maxloop, maxpoly);
-
- mvert = result->mvert;
- orig_mvert = mesh->mvert;
- mpoly = result->mpoly;
- orig_mpoly = mesh->mpoly;
- mloop = result->mloop;
- orig_mloop = mesh->mloop;
-
- MLoopCol *mloopcols_index = CustomData_get_layer_named(&result->ldata, CD_MLOOPCOL, pimd->index_layer_name);
- MLoopCol *mloopcols_value = CustomData_get_layer_named(&result->ldata, CD_MLOOPCOL, pimd->value_layer_name);
- int *vert_part_index = NULL;
- float *vert_part_value = NULL;
- if (mloopcols_index != NULL) {
- vert_part_index = MEM_calloc_arrayN(maxvert, sizeof(int), "vertex part index array");
- }
- if (mloopcols_value) {
- vert_part_value = MEM_calloc_arrayN(maxvert, sizeof(float), "vertex part value array");
- }
-
- for (p = part_start, p_skip = 0; p < part_end; p++) {
- float prev_dir[3];
- float frame[4]; /* frame orientation quaternion */
- float p_random = psys_frand(psys, 77091 + 283 * p);
-
- /* skip particle? */
- if (particle_skip(pimd, psys, p))
- continue;
-
- /* set vertices coordinates */
- for (k = 0; k < totvert; k++) {
- ParticleKey state;
- MVert *inMV;
- int vindex = p_skip * totvert + k;
- MVert *mv = mvert + vindex;
-
- inMV = orig_mvert + k;
- CustomData_copy_data(&mesh->vdata, &result->vdata, k, p_skip * totvert + k, 1);
- *mv = *inMV;
-
- if (vert_part_index != NULL) {
- vert_part_index[vindex] = p;
- }
- if (vert_part_value != NULL) {
- vert_part_value[vindex] = p_random;
- }
-
- /*change orientation based on object trackflag*/
- copy_v3_v3(temp_co, mv->co);
- mv->co[axis] = temp_co[track];
- mv->co[(axis + 1) % 3] = temp_co[(track + 1) % 3];
- mv->co[(axis + 2) % 3] = temp_co[(track + 2) % 3];
-
- /* get particle state */
- if ((psys->flag & (PSYS_HAIR_DONE | PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) &&
- (pimd->flag & eParticleInstanceFlag_Path))
- {
- float ran = 0.0f;
- if (pimd->random_position != 0.0f) {
- ran = pimd->random_position * BLI_hash_frand(psys->seed + p);
- }
-
- if (pimd->flag & eParticleInstanceFlag_KeepShape) {
- state.time = pimd->position * (1.0f - ran);
- }
- else {
- state.time = (mv->co[axis] - min_co) / (max_co - min_co) * pimd->position * (1.0f - ran);
-
- if (trackneg)
- state.time = 1.0f - state.time;
-
- mv->co[axis] = 0.0;
- }
-
- psys_get_particle_on_path(&sim, p, &state, 1);
-
- normalize_v3(state.vel);
-
- /* Incrementally Rotating Frame (Bishop Frame) */
- if (k == 0) {
- float hairmat[4][4];
- float mat[3][3];
-
- if (p < psys->totpart)
- pa = psys->particles + p;
- else {
- ChildParticle *cpa = psys->child + (p - psys->totpart);
- pa = psys->particles + (between ? cpa->pa[0] : cpa->parent);
- }
- psys_mat_hair_to_global(sim.ob, sim.psmd->mesh_final, sim.psys->part->from, pa, hairmat);
- copy_m3_m4(mat, hairmat);
- /* to quaternion */
- mat3_to_quat(frame, mat);
-
- if (pimd->rotation > 0.0f || pimd->random_rotation > 0.0f) {
- float angle = 2.0f * M_PI * (pimd->rotation + pimd->random_rotation * (psys_frand(psys, 19957323 + p) - 0.5f));
- float eul[3] = { 0.0f, 0.0f, angle };
- float rot[4];
-
- eul_to_quat(rot, eul);
- mul_qt_qtqt(frame, frame, rot);
- }
-
- /* note: direction is same as normal vector currently,
- * but best to keep this separate so the frame can be
- * rotated later if necessary
- */
- copy_v3_v3(prev_dir, state.vel);
- }
- else {
- float rot[4];
-
- /* incrementally rotate along bend direction */
- rotation_between_vecs_to_quat(rot, prev_dir, state.vel);
- mul_qt_qtqt(frame, rot, frame);
-
- copy_v3_v3(prev_dir, state.vel);
- }
-
- copy_qt_qt(state.rot, frame);
+ Mesh *result;
+ ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
+ struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
+ ParticleSimulationData sim;
+ ParticleSystem *psys = NULL;
+ ParticleData *pa = NULL;
+ MPoly *mpoly, *orig_mpoly;
+ MLoop *mloop, *orig_mloop;
+ MVert *mvert, *orig_mvert;
+ int totvert, totpoly, totloop, totedge;
+ int maxvert, maxpoly, maxloop, maxedge, part_end = 0, part_start;
+ int k, p, p_skip;
+ short track = ctx->object->trackflag % 3, trackneg, axis = pimd->axis;
+ float max_co = 0.0, min_co = 0.0, temp_co[3];
+ float *size = NULL;
+ float spacemat[4][4];
+ const bool use_parents = pimd->flag & eParticleInstanceFlag_Parents;
+ const bool use_children = pimd->flag & eParticleInstanceFlag_Children;
+ bool between;
+
+ trackneg = ((ctx->object->trackflag > 2) ? 1 : 0);
+
+ if (pimd->ob == ctx->object) {
+ pimd->ob = NULL;
+ return mesh;
+ }
+
+ if (pimd->ob) {
+ psys = BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1);
+ if (psys == NULL || psys->totpart == 0)
+ return mesh;
+ }
+ else {
+ return mesh;
+ }
+
+ part_start = use_parents ? 0 : psys->totpart;
+
+ part_end = 0;
+ if (use_parents)
+ part_end += psys->totpart;
+ if (use_children)
+ part_end += psys->totchild;
+
+ if (part_end == 0)
+ return mesh;
+
+ sim.depsgraph = ctx->depsgraph;
+ sim.scene = scene;
+ sim.ob = pimd->ob;
+ sim.psys = psys;
+ sim.psmd = psys_get_modifier(pimd->ob, psys);
+ between = (psys->part->childtype == PART_CHILD_FACES);
+
+ if (pimd->flag & eParticleInstanceFlag_UseSize) {
+ float *si;
+ si = size = MEM_calloc_arrayN(part_end, sizeof(float), "particle size array");
+
+ if (pimd->flag & eParticleInstanceFlag_Parents) {
+ for (p = 0, pa = psys->particles; p < psys->totpart; p++, pa++, si++)
+ *si = pa->size;
+ }
+
+ if (pimd->flag & eParticleInstanceFlag_Children) {
+ ChildParticle *cpa = psys->child;
+
+ for (p = 0; p < psys->totchild; p++, cpa++, si++) {
+ *si = psys_get_child_size(psys, cpa, 0.0f, NULL);
+ }
+ }
+ }
+
+ switch (pimd->space) {
+ case eParticleInstanceSpace_World:
+ /* particle states are in world space already */
+ unit_m4(spacemat);
+ break;
+ case eParticleInstanceSpace_Local:
+ /* get particle states in the particle object's local space */
+ invert_m4_m4(spacemat, pimd->ob->obmat);
+ break;
+ default:
+ /* should not happen */
+ BLI_assert(false);
+ break;
+ }
+
+ totvert = mesh->totvert;
+ totpoly = mesh->totpoly;
+ totloop = mesh->totloop;
+ totedge = mesh->totedge;
+
+ /* count particles */
+ maxvert = 0;
+ maxpoly = 0;
+ maxloop = 0;
+ maxedge = 0;
+
+ for (p = part_start; p < part_end; p++) {
+ if (particle_skip(pimd, psys, p))
+ continue;
+
+ maxvert += totvert;
+ maxpoly += totpoly;
+ maxloop += totloop;
+ maxedge += totedge;
+ }
+
+ psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
+
+ if (psys->flag & (PSYS_HAIR_DONE | PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) {
+ float min[3], max[3];
+ INIT_MINMAX(min, max);
+ BKE_mesh_minmax(mesh, min, max);
+ min_co = min[track];
+ max_co = max[track];
+ }
+
+ result = BKE_mesh_new_nomain_from_template(mesh, maxvert, maxedge, 0, maxloop, maxpoly);
+
+ mvert = result->mvert;
+ orig_mvert = mesh->mvert;
+ mpoly = result->mpoly;
+ orig_mpoly = mesh->mpoly;
+ mloop = result->mloop;
+ orig_mloop = mesh->mloop;
+
+ MLoopCol *mloopcols_index = CustomData_get_layer_named(
+ &result->ldata, CD_MLOOPCOL, pimd->index_layer_name);
+ MLoopCol *mloopcols_value = CustomData_get_layer_named(
+ &result->ldata, CD_MLOOPCOL, pimd->value_layer_name);
+ int *vert_part_index = NULL;
+ float *vert_part_value = NULL;
+ if (mloopcols_index != NULL) {
+ vert_part_index = MEM_calloc_arrayN(maxvert, sizeof(int), "vertex part index array");
+ }
+ if (mloopcols_value) {
+ vert_part_value = MEM_calloc_arrayN(maxvert, sizeof(float), "vertex part value array");
+ }
+
+ for (p = part_start, p_skip = 0; p < part_end; p++) {
+ float prev_dir[3];
+ float frame[4]; /* frame orientation quaternion */
+ float p_random = psys_frand(psys, 77091 + 283 * p);
+
+ /* skip particle? */
+ if (particle_skip(pimd, psys, p))
+ continue;
+
+ /* set vertices coordinates */
+ for (k = 0; k < totvert; k++) {
+ ParticleKey state;
+ MVert *inMV;
+ int vindex = p_skip * totvert + k;
+ MVert *mv = mvert + vindex;
+
+ inMV = orig_mvert + k;
+ CustomData_copy_data(&mesh->vdata, &result->vdata, k, p_skip * totvert + k, 1);
+ *mv = *inMV;
+
+ if (vert_part_index != NULL) {
+ vert_part_index[vindex] = p;
+ }
+ if (vert_part_value != NULL) {
+ vert_part_value[vindex] = p_random;
+ }
+
+ /*change orientation based on object trackflag*/
+ copy_v3_v3(temp_co, mv->co);
+ mv->co[axis] = temp_co[track];
+ mv->co[(axis + 1) % 3] = temp_co[(track + 1) % 3];
+ mv->co[(axis + 2) % 3] = temp_co[(track + 2) % 3];
+
+ /* get particle state */
+ if ((psys->flag & (PSYS_HAIR_DONE | PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) &&
+ (pimd->flag & eParticleInstanceFlag_Path)) {
+ float ran = 0.0f;
+ if (pimd->random_position != 0.0f) {
+ ran = pimd->random_position * BLI_hash_frand(psys->seed + p);
+ }
+
+ if (pimd->flag & eParticleInstanceFlag_KeepShape) {
+ state.time = pimd->position * (1.0f - ran);
+ }
+ else {
+ state.time = (mv->co[axis] - min_co) / (max_co - min_co) * pimd->position * (1.0f - ran);
+
+ if (trackneg)
+ state.time = 1.0f - state.time;
+
+ mv->co[axis] = 0.0;
+ }
+
+ psys_get_particle_on_path(&sim, p, &state, 1);
+
+ normalize_v3(state.vel);
+
+ /* Incrementally Rotating Frame (Bishop Frame) */
+ if (k == 0) {
+ float hairmat[4][4];
+ float mat[3][3];
+
+ if (p < psys->totpart)
+ pa = psys->particles + p;
+ else {
+ ChildParticle *cpa = psys->child + (p - psys->totpart);
+ pa = psys->particles + (between ? cpa->pa[0] : cpa->parent);
+ }
+ psys_mat_hair_to_global(sim.ob, sim.psmd->mesh_final, sim.psys->part->from, pa, hairmat);
+ copy_m3_m4(mat, hairmat);
+ /* to quaternion */
+ mat3_to_quat(frame, mat);
+
+ if (pimd->rotation > 0.0f || pimd->random_rotation > 0.0f) {
+ float angle = 2.0f * M_PI *
+ (pimd->rotation +
+ pimd->random_rotation * (psys_frand(psys, 19957323 + p) - 0.5f));
+ float eul[3] = {0.0f, 0.0f, angle};
+ float rot[4];
+
+ eul_to_quat(rot, eul);
+ mul_qt_qtqt(frame, frame, rot);
+ }
+
+ /* note: direction is same as normal vector currently,
+ * but best to keep this separate so the frame can be
+ * rotated later if necessary
+ */
+ copy_v3_v3(prev_dir, state.vel);
+ }
+ else {
+ float rot[4];
+
+ /* incrementally rotate along bend direction */
+ rotation_between_vecs_to_quat(rot, prev_dir, state.vel);
+ mul_qt_qtqt(frame, rot, frame);
+
+ copy_v3_v3(prev_dir, state.vel);
+ }
+
+ copy_qt_qt(state.rot, frame);
#if 0
- /* Absolute Frame (Frenet Frame) */
- if (state.vel[axis] < -0.9999f || state.vel[axis] > 0.9999f) {
- unit_qt(state.rot);
- }
- else {
- float cross[3];
- float temp[3] = {0.0f, 0.0f, 0.0f};
- temp[axis] = 1.0f;
-
- cross_v3_v3v3(cross, temp, state.vel);
-
- /* state.vel[axis] is the only component surviving from a dot product with the axis */
- axis_angle_to_quat(state.rot, cross, saacos(state.vel[axis]));
- }
+ /* Absolute Frame (Frenet Frame) */
+ if (state.vel[axis] < -0.9999f || state.vel[axis] > 0.9999f) {
+ unit_qt(state.rot);
+ }
+ else {
+ float cross[3];
+ float temp[3] = {0.0f, 0.0f, 0.0f};
+ temp[axis] = 1.0f;
+
+ cross_v3_v3v3(cross, temp, state.vel);
+
+ /* state.vel[axis] is the only component surviving from a dot product with the axis */
+ axis_angle_to_quat(state.rot, cross, saacos(state.vel[axis]));
+ }
#endif
- }
- else {
- state.time = -1.0;
- psys_get_particle_state(&sim, p, &state, 1);
- }
-
- mul_qt_v3(state.rot, mv->co);
- if (pimd->flag & eParticleInstanceFlag_UseSize)
- mul_v3_fl(mv->co, size[p]);
- add_v3_v3(mv->co, state.co);
-
- mul_m4_v3(spacemat, mv->co);
- }
-
- /* create edges and adjust edge vertex indices*/
- CustomData_copy_data(&mesh->edata, &result->edata, 0, p_skip * totedge, totedge);
- MEdge *me = &result->medge[p_skip * totedge];
- for (k = 0; k < totedge; k++, me++) {
- me->v1 += p_skip * totvert;
- me->v2 += p_skip * totvert;
- }
-
- /* create polys and loops */
- for (k = 0; k < totpoly; k++) {
-
- MPoly *inMP = orig_mpoly + k;
- MPoly *mp = mpoly + p_skip * totpoly + k;
-
- CustomData_copy_data(&mesh->pdata, &result->pdata, k, p_skip * totpoly + k, 1);
- *mp = *inMP;
- mp->loopstart += p_skip * totloop;
-
- {
- MLoop *inML = orig_mloop + inMP->loopstart;
- MLoop *ml = mloop + mp->loopstart;
- int j = mp->totloop;
-
- CustomData_copy_data(&mesh->ldata, &result->ldata, inMP->loopstart, mp->loopstart, j);
- for (; j; j--, ml++, inML++) {
- ml->v = inML->v + (p_skip * totvert);
- ml->e = inML->e + (p_skip * totedge);
- const int ml_index = (ml - mloop);
- if (mloopcols_index != NULL) {
- const int part_index = vert_part_index[ml->v];
- store_float_in_vcol(&mloopcols_index[ml_index], (float)part_index / (float)(psys->totpart - 1));
- }
- if (mloopcols_value != NULL) {
- const float part_value = vert_part_value[ml->v];
- store_float_in_vcol(&mloopcols_value[ml_index], part_value);
- }
- }
- }
- }
- p_skip++;
- }
-
- if (psys->lattice_deform_data) {
- end_latt_deform(psys->lattice_deform_data);
- psys->lattice_deform_data = NULL;
- }
-
- if (size)
- MEM_freeN(size);
-
- MEM_SAFE_FREE(vert_part_index);
- MEM_SAFE_FREE(vert_part_value);
-
- result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
-
- return result;
+ }
+ else {
+ state.time = -1.0;
+ psys_get_particle_state(&sim, p, &state, 1);
+ }
+
+ mul_qt_v3(state.rot, mv->co);
+ if (pimd->flag & eParticleInstanceFlag_UseSize)
+ mul_v3_fl(mv->co, size[p]);
+ add_v3_v3(mv->co, state.co);
+
+ mul_m4_v3(spacemat, mv->co);
+ }
+
+ /* create edges and adjust edge vertex indices*/
+ CustomData_copy_data(&mesh->edata, &result->edata, 0, p_skip * totedge, totedge);
+ MEdge *me = &result->medge[p_skip * totedge];
+ for (k = 0; k < totedge; k++, me++) {
+ me->v1 += p_skip * totvert;
+ me->v2 += p_skip * totvert;
+ }
+
+ /* create polys and loops */
+ for (k = 0; k < totpoly; k++) {
+
+ MPoly *inMP = orig_mpoly + k;
+ MPoly *mp = mpoly + p_skip * totpoly + k;
+
+ CustomData_copy_data(&mesh->pdata, &result->pdata, k, p_skip * totpoly + k, 1);
+ *mp = *inMP;
+ mp->loopstart += p_skip * totloop;
+
+ {
+ MLoop *inML = orig_mloop + inMP->loopstart;
+ MLoop *ml = mloop + mp->loopstart;
+ int j = mp->totloop;
+
+ CustomData_copy_data(&mesh->ldata, &result->ldata, inMP->loopstart, mp->loopstart, j);
+ for (; j; j--, ml++, inML++) {
+ ml->v = inML->v + (p_skip * totvert);
+ ml->e = inML->e + (p_skip * totedge);
+ const int ml_index = (ml - mloop);
+ if (mloopcols_index != NULL) {
+ const int part_index = vert_part_index[ml->v];
+ store_float_in_vcol(&mloopcols_index[ml_index],
+ (float)part_index / (float)(psys->totpart - 1));
+ }
+ if (mloopcols_value != NULL) {
+ const float part_value = vert_part_value[ml->v];
+ store_float_in_vcol(&mloopcols_value[ml_index], part_value);
+ }
+ }
+ }
+ }
+ p_skip++;
+ }
+
+ if (psys->lattice_deform_data) {
+ end_latt_deform(psys->lattice_deform_data);
+ psys->lattice_deform_data = NULL;
+ }
+
+ if (size)
+ MEM_freeN(size);
+
+ MEM_SAFE_FREE(vert_part_index);
+ MEM_SAFE_FREE(vert_part_value);
+
+ result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+
+ return result;
}
ModifierTypeInfo modifierType_ParticleInstance = {
- /* name */ "ParticleInstance",
- /* structName */ "ParticleInstanceModifierData",
- /* structSize */ sizeof(ParticleInstanceModifierData),
- /* type */ eModifierTypeType_Constructive,
- /* flags */ eModifierTypeFlag_AcceptsMesh |
- eModifierTypeFlag_SupportsMapping |
- eModifierTypeFlag_SupportsEditmode |
- eModifierTypeFlag_EnableInEditmode,
-
- /* copyData */ modifier_copyData_generic,
-
- /* deformVerts */ NULL,
- /* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
- /* deformMatricesEM */ NULL,
- /* applyModifier */ applyModifier,
-
- /* initData */ initData,
- /* requiredDataMask */ requiredDataMask,
- /* freeData */ NULL,
- /* isDisabled */ isDisabled,
- /* updateDepsgraph */ updateDepsgraph,
- /* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
- /* foreachObjectLink */ foreachObjectLink,
- /* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
- /* freeRuntimeData */ NULL,
+ /* name */ "ParticleInstance",
+ /* structName */ "ParticleInstanceModifierData",
+ /* structSize */ sizeof(ParticleInstanceModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
+ eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode,
+
+ /* copyData */ modifier_copyData_generic,
+
+ /* deformVerts */ NULL,
+ /* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
+ /* deformMatricesEM */ NULL,
+ /* applyModifier */ applyModifier,
+
+ /* initData */ initData,
+ /* requiredDataMask */ requiredDataMask,
+ /* freeData */ NULL,
+ /* isDisabled */ isDisabled,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* dependsOnNormals */ NULL,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ NULL,
+ /* foreachTexLink */ NULL,
+ /* freeRuntimeData */ NULL,
};