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:
Diffstat (limited to 'source/blender/blenkernel/intern/effect.c')
-rw-r--r--source/blender/blenkernel/intern/effect.c122
1 files changed, 69 insertions, 53 deletions
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 6fe6b708f58..d811b5c0fbb 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -380,11 +380,18 @@ static int linetriangle(float p1[3], float p2[3], float v0[3], float v1[3], floa
return 1;
}
-static void get_effector(float opco[], float force[], float speed[], float cur_time, unsigned int par_layer)
+/* -------- pdDoEffector() --------
+ generic force/speed system, now used for particles and softbodies
+ opco = global coord, as input
+ force = force accumulator
+ speed = speed accumulator
+ cur_time = in frames
+ par_layer = layer the caller is in
+
+*/
+void pdDoEffector(float *opco, float *force, float *speed, float cur_time, unsigned int par_layer)
{
/*
- Particle effector field code
-
Modifies the force on a particle according to its
relation with the effector object
Different kind of effectors include:
@@ -397,46 +404,75 @@ static void get_effector(float opco[], float force[], float speed[], float cur_t
*/
Object *ob;
Base *base;
+ PartDeflect *pd;
float vect_to_vert[3];
float force_vec[3];
float f_force, distance;
- float obloc[3];
+ float *obloc;
float force_val, ffall_val;
short cur_frame;
/* Cycle through objects, get total of (1/(gravity_strength * dist^gravity_power)) */
- /* Check for min distance here? */
- base = G.scene->base.first;
- while (base) {
- if(base->lay & par_layer) {
+ /* Check for min distance here? (yes would be cool to add that, ton) */
+
+ for(base = G.scene->base.first; base; base= base->next) {
+ if( (base->lay & par_layer) && base->object->pd) {
ob= base->object;
- if(ob->pd && ob->pd->forcefield == PFIELD_FORCE) {
-
- /* Need to set r.cfra for paths (investigate, ton) */
+ pd= ob->pd;
+
+ /* checking if to continue or not */
+ if(pd->forcefield==0) continue;
+
+ /* Get IPO force strength and fall off values here */
+ if (has_ipo_code(ob->ipo, OB_PD_FSTR))
+ force_val = IPO_GetFloatValue(ob->ipo, OB_PD_FSTR, cur_time);
+ else
+ force_val = pd->f_strength;
+
+ if (has_ipo_code(ob->ipo, OB_PD_FFALL))
+ ffall_val = IPO_GetFloatValue(ob->ipo, OB_PD_FFALL, cur_time);
+ else
+ ffall_val = pd->f_power;
+
+
+ /* Need to set r.cfra for paths (investigate, ton) (uses ob->ctime now, ton) */
+ if(ob->ctime!=cur_time) {
cur_frame = G.scene->r.cfra;
G.scene->r.cfra = (short)cur_time;
where_is_object_time(ob, cur_time);
G.scene->r.cfra = cur_frame;
+ }
+
+ /* use center of object for distance calculus */
+ obloc= ob->obmat[3];
+ VECSUB(vect_to_vert, obloc, opco);
+ distance = VecLength(vect_to_vert);
+
+ if((pd->flag & PFIELD_USEMAX) && distance>pd->maxdist)
+ ; /* don't do anything */
+ else if(pd->forcefield == PFIELD_WIND) {
+ VECCOPY(force_vec, ob->obmat[2]);
- /* only use center of object */
- obloc[0] = ob->obmat[3][0];
- obloc[1] = ob->obmat[3][1];
- obloc[2] = ob->obmat[3][2];
+ /* wind works harder perpendicular to normal, would be nice for softbody later (ton) */
- /* Get IPO force strength and fall off values here */
- if (has_ipo_code(ob->ipo, OB_PD_FSTR))
- force_val = IPO_GetFloatValue(ob->ipo, OB_PD_FSTR, cur_time);
- else
- force_val = ob->pd->f_strength;
-
- if (has_ipo_code(ob->ipo, OB_PD_FFALL))
- ffall_val = IPO_GetFloatValue(ob->ipo, OB_PD_FFALL, cur_time);
- else
- ffall_val = ob->pd->f_power;
+ /* Limit minimum distance to vertex so that */
+ /* the force is not too big */
+ if (distance < 0.001) distance = 0.001f;
+ f_force = (force_val)*(1/(1000 * (float)pow((double)distance, (double)ffall_val)));
+
+ force[0] += force_vec[0]*f_force;
+ force[1] += force_vec[1]*f_force;
+ force[2] += force_vec[2]*f_force;
+
+ }
+ else if(pd->forcefield == PFIELD_FORCE) {
+
+ /* only use center of object */
+ obloc= ob->obmat[3];
/* Now calculate the gravitational force */
VECSUB(vect_to_vert, obloc, opco);
- distance = Normalise(vect_to_vert);
+ distance = VecLength(vect_to_vert);
/* Limit minimum distance to vertex so that */
/* the force is not too big */
@@ -447,33 +483,14 @@ static void get_effector(float opco[], float force[], float speed[], float cur_t
force[2] += (vect_to_vert[2] * f_force );
}
- else if(ob->pd && ob->pd->forcefield == PFIELD_VORTEX) {
- /* Need to set r.cfra for paths (investigate, ton) */
- cur_frame = G.scene->r.cfra;
- G.scene->r.cfra = (short)cur_time;
- where_is_object_time(ob, cur_time);
- G.scene->r.cfra = cur_frame;
-
- /* only use center of object */
- obloc[0] = ob->obmat[3][0];
- obloc[1] = ob->obmat[3][1];
- obloc[2] = ob->obmat[3][2];
-
- /* Get IPO force strength and fall off values here */
- if (has_ipo_code(ob->ipo, OB_PD_FSTR))
- force_val = IPO_GetFloatValue(ob->ipo, OB_PD_FSTR, cur_time);
- else
- force_val = ob->pd->f_strength;
+ else if(pd->forcefield == PFIELD_VORTEX) {
- if (has_ipo_code(ob->ipo, OB_PD_FFALL))
- ffall_val = IPO_GetFloatValue(ob->ipo, OB_PD_FFALL, cur_time);
- else
- ffall_val = ob->pd->f_power;
+ /* only use center of object */
+ obloc= ob->obmat[3];
/* Now calculate the vortex force */
VECSUB(vect_to_vert, obloc, opco);
-
- distance = Normalise(vect_to_vert);
+ distance = VecLength(vect_to_vert);
Crossf(force_vec, ob->obmat[2], vect_to_vert);
Normalise(force_vec);
@@ -488,7 +505,6 @@ static void get_effector(float opco[], float force[], float speed[], float cur_t
}
}
- base = base->next;
}
}
@@ -513,7 +529,7 @@ static void cache_object_vertices(Object *ob)
}
}
-static int get_deflection(float opco[3], float npco[3], float opno[3],
+int pdDoDeflection(float opco[3], float npco[3], float opno[3],
float npno[3], float life, float force[3], int def_depth,
float cur_time, unsigned int par_layer, int *last_object,
int *last_face, int *same_face)
@@ -875,7 +891,7 @@ void make_particle_keys(int depth, int nr, PartEff *paf, Particle *part, float *
/* Check force field */
cur_time = pa->time;
- get_effector(opco, new_force, new_speed, cur_time, par_layer);
+ pdDoEffector(opco, new_force, new_speed, cur_time, par_layer);
/* new location */
pa->co[0]= opa->co[0] + deltalife * (opa->no[0] + new_speed[0] + 0.5f*new_force[0]);
@@ -910,7 +926,7 @@ void make_particle_keys(int depth, int nr, PartEff *paf, Particle *part, float *
/* Bail out if we've done the calculation 10 times - this seems ok */
/* for most scenes I've tested */
while (finish_defs) {
- deflected = get_deflection(opco, npco, opno, npno, life, new_force,
+ deflected = pdDoDeflection(opco, npco, opno, npno, life, new_force,
def_count, cur_time, par_layer,
&last_ob, &last_fc, &same_fc);
if (deflected) {