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:
authorLukas Tönne <lukas.toenne@gmail.com>2014-02-14 15:54:42 +0400
committerLukas Tönne <lukas.toenne@gmail.com>2014-02-14 15:58:43 +0400
commit30c9fe19a31f6f92be4de2abacb9fd96179a9a04 (patch)
tree98334e36b5bc88b731eafa463055bad8768d46d3 /source/blender/blenkernel/intern/effect.c
parent32b45cb4a7adeae637e02c3a8da87e28844e587f (diff)
Fix for crash caused by effectors doing precalculation //during// DAG
updates. This file crashes on loading with NULL pointer access to curve_cache: {F77132} The pdInitEffectors function was amalgamating the simple collection of effector objects with an automatic precalculation for curve guides and the like. This precalculation requires object data that may not be available until the DAG has finished. Since for DAG dependencies only the list of effectors is required, added an argument to disable precalculation when collecting effectors.
Diffstat (limited to 'source/blender/blenkernel/intern/effect.c')
-rw-r--r--source/blender/blenkernel/intern/effect.c98
1 files changed, 55 insertions, 43 deletions
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index a8124c0f9c0..fc18a204526 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -166,45 +166,6 @@ void free_partdeflect(PartDeflect *pd)
MEM_freeN(pd);
}
-static void precalculate_effector(EffectorCache *eff)
-{
- unsigned int cfra = (unsigned int)(eff->scene->r.cfra >= 0 ? eff->scene->r.cfra : -eff->scene->r.cfra);
- if (!eff->pd->rng)
- eff->pd->rng = BLI_rng_new(eff->pd->seed + cfra);
- else
- BLI_rng_srandom(eff->pd->rng, eff->pd->seed + cfra);
-
- if (eff->pd->forcefield == PFIELD_GUIDE && eff->ob->type==OB_CURVE) {
- Curve *cu= eff->ob->data;
- if (cu->flag & CU_PATH) {
- if (eff->ob->curve_cache == NULL || eff->ob->curve_cache->path==NULL || eff->ob->curve_cache->path->data==NULL)
- BKE_displist_make_curveTypes(eff->scene, eff->ob, 0);
-
- if (eff->ob->curve_cache->path && eff->ob->curve_cache->path->data) {
- where_on_path(eff->ob, 0.0, eff->guide_loc, eff->guide_dir, NULL, &eff->guide_radius, NULL);
- mul_m4_v3(eff->ob->obmat, eff->guide_loc);
- mul_mat3_m4_v3(eff->ob->obmat, eff->guide_dir);
- }
- }
- }
- else if (eff->pd->shape == PFIELD_SHAPE_SURFACE) {
- eff->surmd = (SurfaceModifierData *)modifiers_findByType( eff->ob, eModifierType_Surface );
- if (eff->ob->type == OB_CURVE)
- eff->flag |= PE_USE_NORMAL_DATA;
- }
- else if (eff->psys)
- psys_update_particle_tree(eff->psys, eff->scene->r.cfra);
-
- /* Store object velocity */
- if (eff->ob) {
- float old_vel[3];
-
- BKE_object_where_is_calc_time(eff->scene, eff->ob, cfra - 1.0f);
- copy_v3_v3(old_vel, eff->ob->obmat[3]);
- BKE_object_where_is_calc_time(eff->scene, eff->ob, cfra);
- sub_v3_v3v3(eff->velocity, eff->ob->obmat[3], old_vel);
- }
-}
static EffectorCache *new_effector_cache(Scene *scene, Object *ob, ParticleSystem *psys, PartDeflect *pd)
{
EffectorCache *eff = MEM_callocN(sizeof(EffectorCache), "EffectorCache");
@@ -213,9 +174,6 @@ static EffectorCache *new_effector_cache(Scene *scene, Object *ob, ParticleSyste
eff->psys = psys;
eff->pd = pd;
eff->frame = -1;
-
- precalculate_effector(eff);
-
return eff;
}
static void add_object_to_effectors(ListBase **effectors, Scene *scene, EffectorWeights *weights, Object *ob, Object *ob_src)
@@ -264,7 +222,8 @@ static void add_particles_to_effectors(ListBase **effectors, Scene *scene, Effec
}
/* returns ListBase handle with objects taking part in the effecting */
-ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src, EffectorWeights *weights)
+ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src,
+ EffectorWeights *weights, bool precalc)
{
Base *base;
unsigned int layer= ob_src->lay;
@@ -302,6 +261,10 @@ ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src
}
}
}
+
+ if (precalc)
+ pdPrecalculateEffectors(effectors);
+
return effectors;
}
@@ -321,6 +284,55 @@ void pdEndEffectors(ListBase **effectors)
}
}
+static void precalculate_effector(EffectorCache *eff)
+{
+ unsigned int cfra = (unsigned int)(eff->scene->r.cfra >= 0 ? eff->scene->r.cfra : -eff->scene->r.cfra);
+ if (!eff->pd->rng)
+ eff->pd->rng = BLI_rng_new(eff->pd->seed + cfra);
+ else
+ BLI_rng_srandom(eff->pd->rng, eff->pd->seed + cfra);
+
+ if (eff->pd->forcefield == PFIELD_GUIDE && eff->ob->type==OB_CURVE) {
+ Curve *cu= eff->ob->data;
+ if (cu->flag & CU_PATH) {
+ if (eff->ob->curve_cache == NULL || eff->ob->curve_cache->path==NULL || eff->ob->curve_cache->path->data==NULL)
+ BKE_displist_make_curveTypes(eff->scene, eff->ob, 0);
+
+ if (eff->ob->curve_cache->path && eff->ob->curve_cache->path->data) {
+ where_on_path(eff->ob, 0.0, eff->guide_loc, eff->guide_dir, NULL, &eff->guide_radius, NULL);
+ mul_m4_v3(eff->ob->obmat, eff->guide_loc);
+ mul_mat3_m4_v3(eff->ob->obmat, eff->guide_dir);
+ }
+ }
+ }
+ else if (eff->pd->shape == PFIELD_SHAPE_SURFACE) {
+ eff->surmd = (SurfaceModifierData *)modifiers_findByType( eff->ob, eModifierType_Surface );
+ if (eff->ob->type == OB_CURVE)
+ eff->flag |= PE_USE_NORMAL_DATA;
+ }
+ else if (eff->psys)
+ psys_update_particle_tree(eff->psys, eff->scene->r.cfra);
+
+ /* Store object velocity */
+ if (eff->ob) {
+ float old_vel[3];
+
+ BKE_object_where_is_calc_time(eff->scene, eff->ob, cfra - 1.0f);
+ copy_v3_v3(old_vel, eff->ob->obmat[3]);
+ BKE_object_where_is_calc_time(eff->scene, eff->ob, cfra);
+ sub_v3_v3v3(eff->velocity, eff->ob->obmat[3], old_vel);
+ }
+}
+
+void pdPrecalculateEffectors(ListBase *effectors)
+{
+ if (effectors) {
+ EffectorCache *eff = effectors->first;
+ for (; eff; eff=eff->next)
+ precalculate_effector(eff);
+ }
+}
+
void pd_point_from_particle(ParticleSimulationData *sim, ParticleData *pa, ParticleKey *state, EffectedPoint *point)
{