forked from bartvdbraak/blender
a) New unified effector system by Janne (jahka) + Me (genscher): particle and cloth/sb don't use different systems anymore. b) cloth wind corrected for new system c) Wind has noise option now d) @ Bjornmose: since the old factors are gone SB doesn't need to divide by 1000 etc. anymore. I didn't want to touch your code - you might like to take a look at it :)
This commit is contained in:
parent
a84d346939
commit
d5a890c078
@ -37,6 +37,7 @@ struct Effect;
|
|||||||
struct ListBase;
|
struct ListBase;
|
||||||
struct Particle;
|
struct Particle;
|
||||||
struct Group;
|
struct Group;
|
||||||
|
struct RNG;
|
||||||
|
|
||||||
typedef struct pEffectorCache {
|
typedef struct pEffectorCache {
|
||||||
struct pEffectorCache *next, *prev;
|
struct pEffectorCache *next, *prev;
|
||||||
@ -64,6 +65,11 @@ struct ListBase *pdInitEffectors(struct Object *obsrc, struct Group *group);
|
|||||||
void pdEndEffectors(struct ListBase *lb);
|
void pdEndEffectors(struct ListBase *lb);
|
||||||
void pdDoEffectors(struct ListBase *lb, float *opco, float *force, float *speed, float cur_time, float loc_time, unsigned int flags);
|
void pdDoEffectors(struct ListBase *lb, float *opco, float *force, float *speed, float cur_time, float loc_time, unsigned int flags);
|
||||||
|
|
||||||
|
/* required for particle_system.c */
|
||||||
|
void do_physical_effector(short type, float force_val, float distance, float falloff, float size, float damp, float *eff_velocity, float *vec_to_part, float *velocity, float *field, int planar, struct RNG *rng, float noise);
|
||||||
|
float effector_falloff(struct PartDeflect *pd, float *eff_velocity, float *vec_to_part);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -157,6 +157,13 @@ static void add_to_effectorcache(ListBase *lb, Object *ob, Object *obsrc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(pd->forcefield) {
|
else if(pd->forcefield) {
|
||||||
|
|
||||||
|
if(pd->forcefield == PFIELD_WIND)
|
||||||
|
{
|
||||||
|
pd->rng = rng_new(1);
|
||||||
|
rng_srandom(pd->rng, (unsigned int)(ceil(PIL_check_seconds_timer()))); // use better seed
|
||||||
|
}
|
||||||
|
|
||||||
ec= MEM_callocN(sizeof(pEffectorCache), "effector cache");
|
ec= MEM_callocN(sizeof(pEffectorCache), "effector cache");
|
||||||
ec->ob= ob;
|
ec->ob= ob;
|
||||||
BLI_addtail(lb, ec);
|
BLI_addtail(lb, ec);
|
||||||
@ -205,13 +212,189 @@ void pdEndEffectors(ListBase *lb)
|
|||||||
pEffectorCache *ec;
|
pEffectorCache *ec;
|
||||||
/* restore full copy */
|
/* restore full copy */
|
||||||
for(ec= lb->first; ec; ec= ec->next)
|
for(ec= lb->first; ec; ec= ec->next)
|
||||||
|
{
|
||||||
|
if(ec->ob->pd && (ec->ob->pd->forcefield == PFIELD_WIND))
|
||||||
|
rng_free(ec->ob->pd->rng);
|
||||||
|
|
||||||
*(ec->ob)= ec->obcopy;
|
*(ec->ob)= ec->obcopy;
|
||||||
|
}
|
||||||
|
|
||||||
BLI_freelistN(lb);
|
BLI_freelistN(lb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************/
|
||||||
|
/* Effectors */
|
||||||
|
/************************************************/
|
||||||
|
|
||||||
|
// noise function for wind e.g.
|
||||||
|
static float wind_func(struct RNG *rng, float strength)
|
||||||
|
{
|
||||||
|
int random = (rng_getInt(rng)+1) % 65535; // max 2357
|
||||||
|
float force = rng_getFloat(rng) + 1.0f;
|
||||||
|
float ret;
|
||||||
|
float sign = 0;
|
||||||
|
|
||||||
|
sign = (random > 32000.0) ? 1.0: -1.0; // dividing by 2 is not giving equal sign distribution
|
||||||
|
|
||||||
|
ret = sign*((float)random / force)*strength/65535.0f;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static float falloff_func(float fac, int usemin, float mindist, int usemax, float maxdist, float power)
|
||||||
|
{
|
||||||
|
if(!usemin)
|
||||||
|
mindist= 0.0f;
|
||||||
|
|
||||||
|
if(fac < mindist) {
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
else if(usemax) {
|
||||||
|
if(fac>maxdist || (maxdist-mindist)<=0.0f)
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
fac= (fac-mindist)/(maxdist-mindist);
|
||||||
|
return 1.0f - (float)pow((double)fac, (double)power);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return pow((double)1.0f+fac-mindist, (double)-power);
|
||||||
|
}
|
||||||
|
|
||||||
|
static float falloff_func_dist(PartDeflect *pd, float fac)
|
||||||
|
{
|
||||||
|
return falloff_func(fac, pd->flag&PFIELD_USEMIN, pd->mindist, pd->flag&PFIELD_USEMAX, pd->maxdist, pd->f_power);
|
||||||
|
}
|
||||||
|
|
||||||
|
static float falloff_func_rad(PartDeflect *pd, float fac)
|
||||||
|
{
|
||||||
|
return falloff_func(fac, pd->flag&PFIELD_USEMINR, pd->minrad, pd->flag&PFIELD_USEMAXR, pd->maxrad, pd->f_power_r);
|
||||||
|
}
|
||||||
|
|
||||||
|
float effector_falloff(PartDeflect *pd, float *eff_velocity, float *vec_to_part)
|
||||||
|
{
|
||||||
|
float eff_dir[3], temp[3];
|
||||||
|
float falloff=1.0, fac, r_fac;
|
||||||
|
|
||||||
|
VecCopyf(eff_dir,eff_velocity);
|
||||||
|
Normalize(eff_dir);
|
||||||
|
|
||||||
|
if(pd->flag & PFIELD_POSZ && Inpf(eff_dir,vec_to_part)<0.0f)
|
||||||
|
falloff=0.0f;
|
||||||
|
else switch(pd->falloff){
|
||||||
|
case PFIELD_FALL_SPHERE:
|
||||||
|
fac=VecLength(vec_to_part);
|
||||||
|
falloff= falloff_func_dist(pd, fac);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PFIELD_FALL_TUBE:
|
||||||
|
fac=Inpf(vec_to_part,eff_dir);
|
||||||
|
falloff= falloff_func_dist(pd, ABS(fac));
|
||||||
|
if(falloff == 0.0f)
|
||||||
|
break;
|
||||||
|
|
||||||
|
VECADDFAC(temp,vec_to_part,eff_dir,-fac);
|
||||||
|
r_fac=VecLength(temp);
|
||||||
|
falloff*= falloff_func_rad(pd, r_fac);
|
||||||
|
break;
|
||||||
|
case PFIELD_FALL_CONE:
|
||||||
|
fac=Inpf(vec_to_part,eff_dir);
|
||||||
|
falloff= falloff_func_dist(pd, ABS(fac));
|
||||||
|
if(falloff == 0.0f)
|
||||||
|
break;
|
||||||
|
|
||||||
|
r_fac=saacos(fac/VecLength(vec_to_part))*180.0f/(float)M_PI;
|
||||||
|
falloff*= falloff_func_rad(pd, r_fac);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return falloff;
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_physical_effector(short type, float force_val, float distance, float falloff, float size, float damp, float *eff_velocity, float *vec_to_part, float *velocity, float *field, int planar, struct RNG *rng, float noise)
|
||||||
|
{
|
||||||
|
float mag_vec[3]={0,0,0};
|
||||||
|
float temp[3], temp2[3];
|
||||||
|
float eff_vel[3];
|
||||||
|
float wind = 0;
|
||||||
|
|
||||||
|
VecCopyf(eff_vel,eff_velocity);
|
||||||
|
Normalize(eff_vel);
|
||||||
|
|
||||||
|
switch(type){
|
||||||
|
case PFIELD_WIND:
|
||||||
|
VECCOPY(mag_vec,eff_vel);
|
||||||
|
|
||||||
|
// add wind noise here
|
||||||
|
if(noise> 0.0f)
|
||||||
|
wind = wind_func(rng, noise);
|
||||||
|
|
||||||
|
VecMulf(mag_vec,(force_val+wind)*falloff);
|
||||||
|
VecAddf(field,field,mag_vec);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PFIELD_FORCE:
|
||||||
|
if(planar)
|
||||||
|
Projf(mag_vec,vec_to_part,eff_vel);
|
||||||
|
else
|
||||||
|
VecCopyf(mag_vec,vec_to_part);
|
||||||
|
|
||||||
|
VecMulf(mag_vec,force_val*falloff);
|
||||||
|
VecAddf(field,field,mag_vec);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PFIELD_VORTEX:
|
||||||
|
Crossf(mag_vec,eff_vel,vec_to_part);
|
||||||
|
Normalize(mag_vec);
|
||||||
|
|
||||||
|
VecMulf(mag_vec,force_val*distance*falloff);
|
||||||
|
VecAddf(field,field,mag_vec);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case PFIELD_MAGNET:
|
||||||
|
if(planar)
|
||||||
|
VecCopyf(temp,eff_vel);
|
||||||
|
else
|
||||||
|
/* magnetic field of a moving charge */
|
||||||
|
Crossf(temp,eff_vel,vec_to_part);
|
||||||
|
|
||||||
|
Crossf(temp2,velocity,temp);
|
||||||
|
VecAddf(mag_vec,mag_vec,temp2);
|
||||||
|
|
||||||
|
VecMulf(mag_vec,force_val*falloff);
|
||||||
|
VecAddf(field,field,mag_vec);
|
||||||
|
break;
|
||||||
|
case PFIELD_HARMONIC:
|
||||||
|
if(planar)
|
||||||
|
Projf(mag_vec,vec_to_part,eff_vel);
|
||||||
|
else
|
||||||
|
VecCopyf(mag_vec,vec_to_part);
|
||||||
|
|
||||||
|
VecMulf(mag_vec,force_val*falloff);
|
||||||
|
VecSubf(field,field,mag_vec);
|
||||||
|
|
||||||
|
VecCopyf(mag_vec,velocity);
|
||||||
|
/* 1.9 is an experimental value to get critical damping at damp=1.0 */
|
||||||
|
VecMulf(mag_vec,damp*1.9f*(float)sqrt(force_val));
|
||||||
|
VecSubf(field,field,mag_vec);
|
||||||
|
break;
|
||||||
|
case PFIELD_NUCLEAR:
|
||||||
|
/*pow here is root of cosine expression below*/
|
||||||
|
//rad=(float)pow(2.0,-1.0/power)*distance/size;
|
||||||
|
//VECCOPY(mag_vec,vec_to_part);
|
||||||
|
//Normalize(mag_vec);
|
||||||
|
//VecMulf(mag_vec,(float)cos(3.0*M_PI/2.0*(1.0-1.0/(pow(rad,power)+1.0)))/(rad+0.2f));
|
||||||
|
//VECADDFAC(field,field,mag_vec,force_val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* -------- pdDoEffectors() --------
|
/* -------- pdDoEffectors() --------
|
||||||
generic force/speed system, now used for particles and softbodies
|
generic force/speed system, now used for particles and softbodies
|
||||||
lb = listbase with objects that take part in effecting
|
lb = listbase with objects that take part in effecting
|
||||||
@ -244,13 +427,10 @@ void pdDoEffectors(ListBase *lb, float *opco, float *force, float *speed, float
|
|||||||
pEffectorCache *ec;
|
pEffectorCache *ec;
|
||||||
PartDeflect *pd;
|
PartDeflect *pd;
|
||||||
float vect_to_vert[3];
|
float vect_to_vert[3];
|
||||||
float f_force, force_vec[3];
|
|
||||||
float *obloc;
|
float *obloc;
|
||||||
float distance, force_val, ffall_val;
|
|
||||||
float guidecollect[3], guidedist= 0.0f;
|
|
||||||
int cur_frame;
|
|
||||||
|
|
||||||
guidecollect[0]= guidecollect[1]= guidecollect[2]=0.0f;
|
float distance, vec_to_part[3];
|
||||||
|
float falloff;
|
||||||
|
|
||||||
/* Cycle through collected objects, get total of (1/(gravity_strength * dist^gravity_power)) */
|
/* Cycle through collected objects, get total of (1/(gravity_strength * dist^gravity_power)) */
|
||||||
/* Check for min distance here? (yes would be cool to add that, ton) */
|
/* Check for min distance here? (yes would be cool to add that, ton) */
|
||||||
@ -261,178 +441,32 @@ void pdDoEffectors(ListBase *lb, float *opco, float *force, float *speed, float
|
|||||||
pd= ob->pd;
|
pd= ob->pd;
|
||||||
|
|
||||||
/* Get IPO force strength and fall off values here */
|
/* 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 = (int)cur_time;
|
|
||||||
where_is_object_time(ob,cur_time);
|
where_is_object_time(ob,cur_time);
|
||||||
G.scene->r.cfra = cur_frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* use center of object for distance calculus */
|
/* use center of object for distance calculus */
|
||||||
obloc= ob->obmat[3];
|
obloc= ob->obmat[3];
|
||||||
VECSUB(vect_to_vert, obloc, opco);
|
VECSUB(vect_to_vert, obloc, opco);
|
||||||
distance = VecLength(vect_to_vert);
|
distance = VecLength(vect_to_vert);
|
||||||
|
|
||||||
if((pd->flag & PFIELD_USEMAX) && distance>pd->maxdist && pd->forcefield != PFIELD_GUIDE)
|
VecSubf(vec_to_part, opco, ob->obmat[3]);
|
||||||
|
distance = VecLength(vec_to_part);
|
||||||
|
|
||||||
|
falloff=effector_falloff(pd,ob->obmat[2],vec_to_part);
|
||||||
|
|
||||||
|
if(falloff<=0.0f)
|
||||||
; /* don't do anything */
|
; /* don't do anything */
|
||||||
else if((pd->flag & PFIELD_USEMIN) && distance<pd->mindist && pd->forcefield != PFIELD_GUIDE)
|
|
||||||
; /* don't do anything */
|
|
||||||
else if(pd->forcefield == PFIELD_WIND) {
|
|
||||||
VECCOPY(force_vec, ob->obmat[2]);
|
|
||||||
|
|
||||||
/* wind works harder perpendicular to normal, would be nice for softbody later (ton) */
|
|
||||||
|
|
||||||
/* 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)));
|
|
||||||
/* this option for softbody only */
|
|
||||||
if(flags && PE_WIND_AS_SPEED){
|
|
||||||
speed[0] -= (force_vec[0] * f_force );
|
|
||||||
speed[1] -= (force_vec[1] * f_force );
|
|
||||||
speed[2] -= (force_vec[2] * f_force );
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
force[0] += force_vec[0]*f_force;
|
float field[3]={0,0,0}, tmp[3];
|
||||||
force[1] += force_vec[1]*f_force;
|
VECCOPY(field, force);
|
||||||
force[2] += force_vec[2]*f_force;
|
do_physical_effector(pd->forcefield,pd->f_strength,distance,
|
||||||
}
|
falloff,pd->f_dist,pd->f_damp,ob->obmat[2],vec_to_part,
|
||||||
}
|
speed,force,pd->flag&PFIELD_PLANAR, pd->rng, pd->f_noise);
|
||||||
else if(pd->forcefield == PFIELD_FORCE) {
|
|
||||||
|
|
||||||
/* only use center of object */
|
// for softbody backward compatibility
|
||||||
obloc= ob->obmat[3];
|
if(flags & PE_WIND_AS_SPEED){
|
||||||
|
VECSUB(tmp, force, field);
|
||||||
/* Now calculate the gravitational force */
|
VECSUB(speed, speed, tmp);
|
||||||
VECSUB(vect_to_vert, obloc, opco);
|
|
||||||
distance = VecLength(vect_to_vert);
|
|
||||||
|
|
||||||
/* 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.0/(1000.0 * (float)pow((double)distance, (double)ffall_val)));
|
|
||||||
force[0] += (vect_to_vert[0] * f_force );
|
|
||||||
force[1] += (vect_to_vert[1] * f_force );
|
|
||||||
force[2] += (vect_to_vert[2] * f_force );
|
|
||||||
}
|
|
||||||
else if(pd->forcefield == PFIELD_VORTEX) {
|
|
||||||
float vortexvec[3];
|
|
||||||
|
|
||||||
/* only use center of object */
|
|
||||||
obloc= ob->obmat[3];
|
|
||||||
|
|
||||||
/* Now calculate the vortex force */
|
|
||||||
VECSUB(vect_to_vert, obloc, opco);
|
|
||||||
distance = VecLength(vect_to_vert);
|
|
||||||
|
|
||||||
Crossf(force_vec, ob->obmat[2], vect_to_vert);
|
|
||||||
Normalize(force_vec);
|
|
||||||
|
|
||||||
/* 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.0/(100.0 * (float)pow((double)distance, (double)ffall_val)));
|
|
||||||
vortexvec[0]= -(force_vec[0] * f_force );
|
|
||||||
vortexvec[1]= -(force_vec[1] * f_force );
|
|
||||||
vortexvec[2]= -(force_vec[2] * f_force );
|
|
||||||
|
|
||||||
/* this option for softbody only */
|
|
||||||
if(flags &&PE_WIND_AS_SPEED) {
|
|
||||||
speed[0]+= vortexvec[0];
|
|
||||||
speed[1]+= vortexvec[1];
|
|
||||||
speed[2]+= vortexvec[2];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* since vortex alters the speed, we have to correct for the previous vortex result */
|
|
||||||
speed[0]+= vortexvec[0] - ec->oldspeed[0];
|
|
||||||
speed[1]+= vortexvec[1] - ec->oldspeed[1];
|
|
||||||
speed[2]+= vortexvec[2] - ec->oldspeed[2];
|
|
||||||
|
|
||||||
VECCOPY(ec->oldspeed, vortexvec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(pd->forcefield == PFIELD_GUIDE) {
|
|
||||||
float guidevec[4], guidedir[3];
|
|
||||||
float mindist= force_val; /* force_val is actually mindist in the UI */
|
|
||||||
|
|
||||||
distance= ec->guide_dist;
|
|
||||||
|
|
||||||
/* WARNING: bails out with continue here */
|
|
||||||
if((pd->flag & PFIELD_USEMAX) && distance>pd->maxdist) continue;
|
|
||||||
|
|
||||||
/* calculate contribution factor for this guide */
|
|
||||||
if(distance<=mindist) f_force= 1.0f;
|
|
||||||
else if(pd->flag & PFIELD_USEMAX) {
|
|
||||||
if(distance>pd->maxdist || mindist>=pd->maxdist) f_force= 0.0f;
|
|
||||||
else {
|
|
||||||
f_force= 1.0f - (distance-mindist)/(pd->maxdist - mindist);
|
|
||||||
if(ffall_val!=0.0f)
|
|
||||||
f_force = (float)pow(f_force, ffall_val+1.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
f_force= 1.0f/(1.0f + distance-mindist);
|
|
||||||
if(ffall_val!=0.0f)
|
|
||||||
f_force = (float)pow(f_force, ffall_val+1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* now derive path point from loc_time */
|
|
||||||
if(pd->flag & PFIELD_GUIDE_PATH_ADD)
|
|
||||||
where_on_path(ob, f_force*loc_time*ec->time_scale, guidevec, guidedir);
|
|
||||||
else
|
|
||||||
where_on_path(ob, loc_time*ec->time_scale, guidevec, guidedir);
|
|
||||||
|
|
||||||
VECSUB(guidedir, guidevec, ec->oldloc);
|
|
||||||
VECCOPY(ec->oldloc, guidevec);
|
|
||||||
|
|
||||||
Mat4Mul3Vecfl(ob->obmat, guidedir);
|
|
||||||
VecMulf(guidedir, ec->scale); /* correction for lifetime and speed */
|
|
||||||
|
|
||||||
/* we subtract the speed we gave it previous step */
|
|
||||||
VECCOPY(guidevec, guidedir);
|
|
||||||
VECSUB(guidedir, guidedir, ec->oldspeed);
|
|
||||||
VECCOPY(ec->oldspeed, guidevec);
|
|
||||||
|
|
||||||
/* if it fully contributes, we stop */
|
|
||||||
if(f_force==1.0) {
|
|
||||||
VECCOPY(guidecollect, guidedir);
|
|
||||||
guidedist= 1.0f;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if(guidedist<1.0f) {
|
|
||||||
VecMulf(guidedir, f_force);
|
|
||||||
VECADD(guidecollect, guidecollect, guidedir);
|
|
||||||
guidedist += f_force;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* all guides are accumulated here */
|
|
||||||
if(guidedist!=0.0f) {
|
|
||||||
if(guidedist!=1.0f) VecMulf(guidecollect, 1.0f/guidedist);
|
|
||||||
VECADD(speed, speed, guidecollect);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* for paf start to end, store all matrices for objects */
|
|
||||||
typedef struct pMatrixCache {
|
|
||||||
float obmat[4][4];
|
|
||||||
float imat[3][3];
|
|
||||||
} pMatrixCache;
|
|
||||||
|
|
||||||
/* for fluidsim win32 debug messages */
|
|
||||||
#if defined(WIN32) && (!(defined snprintf))
|
|
||||||
#define snprintf _snprintf
|
|
||||||
#endif
|
|
||||||
|
@ -1354,9 +1354,43 @@ DO_INLINE void cloth_apply_spring_force(ClothModifierData *clmd, ClothSpring *s,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void CalcFloat( float *v1, float *v2, float *v3, float *n)
|
||||||
|
{
|
||||||
|
float n1[3],n2[3];
|
||||||
|
|
||||||
|
n1[0]= v1[0]-v2[0];
|
||||||
|
n2[0]= v2[0]-v3[0];
|
||||||
|
n1[1]= v1[1]-v2[1];
|
||||||
|
n2[1]= v2[1]-v3[1];
|
||||||
|
n1[2]= v1[2]-v2[2];
|
||||||
|
n2[2]= v2[2]-v3[2];
|
||||||
|
n[0]= n1[1]*n2[2]-n1[2]*n2[1];
|
||||||
|
n[1]= n1[2]*n2[0]-n1[0]*n2[2];
|
||||||
|
n[2]= n1[0]*n2[1]-n1[1]*n2[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CalcFloat4( float *v1, float *v2, float *v3, float *v4, float *n)
|
||||||
|
{
|
||||||
|
/* real cross! */
|
||||||
|
float n1[3],n2[3];
|
||||||
|
|
||||||
|
n1[0]= v1[0]-v3[0];
|
||||||
|
n1[1]= v1[1]-v3[1];
|
||||||
|
n1[2]= v1[2]-v3[2];
|
||||||
|
|
||||||
|
n2[0]= v2[0]-v4[0];
|
||||||
|
n2[1]= v2[1]-v4[1];
|
||||||
|
n2[2]= v2[2]-v4[2];
|
||||||
|
|
||||||
|
n[0]= n1[1]*n2[2]-n1[2]*n2[1];
|
||||||
|
n[1]= n1[2]*n2[0]-n1[0]*n2[2];
|
||||||
|
n[2]= n1[0]*n2[1]-n1[1]*n2[0];
|
||||||
|
}
|
||||||
|
|
||||||
float calculateVertexWindForce(float wind[3], float vertexnormal[3])
|
float calculateVertexWindForce(float wind[3], float vertexnormal[3])
|
||||||
{
|
{
|
||||||
return fabs(INPR(wind, vertexnormal));
|
return (INPR(wind, vertexnormal));
|
||||||
}
|
}
|
||||||
|
|
||||||
void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time, fmatrix3x3 *M)
|
void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time, fmatrix3x3 *M)
|
||||||
@ -1368,11 +1402,9 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
|
|||||||
float gravity[3];
|
float gravity[3];
|
||||||
float tm2[3][3] = {{-spring_air,0,0}, {0,-spring_air,0},{0,0,-spring_air}};
|
float tm2[3][3] = {{-spring_air,0,0}, {0,-spring_air,0},{0,0,-spring_air}};
|
||||||
MFace *mfaces = cloth->mfaces;
|
MFace *mfaces = cloth->mfaces;
|
||||||
//ClothVertex *verts = cloth->verts;
|
|
||||||
float wind_normalized[3];
|
|
||||||
unsigned int numverts = cloth->numverts;
|
unsigned int numverts = cloth->numverts;
|
||||||
LinkNode *search = cloth->springs;
|
LinkNode *search = cloth->springs;
|
||||||
|
lfVector *winvec;
|
||||||
|
|
||||||
VECCOPY(gravity, clmd->sim_parms->gravity);
|
VECCOPY(gravity, clmd->sim_parms->gravity);
|
||||||
mul_fvector_S(gravity, gravity, 0.001f); /* scale gravity force */
|
mul_fvector_S(gravity, gravity, 0.001f); /* scale gravity force */
|
||||||
@ -1399,70 +1431,61 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
|
|||||||
/* handle external forces like wind */
|
/* handle external forces like wind */
|
||||||
if(effectors)
|
if(effectors)
|
||||||
{
|
{
|
||||||
|
// 0 = force, 1 = normalized force
|
||||||
|
winvec = create_lfvector(cloth->numverts);
|
||||||
|
|
||||||
|
if(!winvec)
|
||||||
|
printf("winvec: out of memory in implicit.c\n");
|
||||||
|
|
||||||
|
// precalculate wind forces
|
||||||
|
for(i = 0; i < cloth->numverts; i++)
|
||||||
|
{
|
||||||
|
float speed[3] = {0.0f, 0.0f,0.0f};
|
||||||
|
|
||||||
|
pdDoEffectors(effectors, lX[i], winvec[i], speed, (float)G.scene->r.cfra, 0.0f, 0);
|
||||||
|
}
|
||||||
|
|
||||||
for(i = 0; i < cloth->numfaces; i++)
|
for(i = 0; i < cloth->numfaces; i++)
|
||||||
{
|
{
|
||||||
float vertexnormal[3]={0,0,0};
|
float trinormal[3]={0,0,0}; // normalized triangle normal
|
||||||
float speed[3] = {0.0f, 0.0f,0.0f};
|
float triunnormal[3]={0,0,0}; // not-normalized-triangle normal
|
||||||
float force[3]= {0.0f, 0.0f, 0.0f};
|
float tmp[3]={0,0,0};
|
||||||
|
float factor = (mfaces[i].v4) ? 0.25 : 1.0 / 3.0;
|
||||||
|
factor *= 0.05;
|
||||||
|
|
||||||
|
// calculate face normal
|
||||||
if(mfaces[i].v4)
|
if(mfaces[i].v4)
|
||||||
CalcNormFloat4(lX[mfaces[i].v1],lX[mfaces[i].v2],lX[mfaces[i].v3],lX[mfaces[i].v4],vertexnormal);
|
CalcFloat4(lX[mfaces[i].v1],lX[mfaces[i].v2],lX[mfaces[i].v3],lX[mfaces[i].v4],triunnormal);
|
||||||
else
|
else
|
||||||
CalcNormFloat(lX[mfaces[i].v1],lX[mfaces[i].v2],lX[mfaces[i].v3],vertexnormal);
|
CalcFloat(lX[mfaces[i].v1],lX[mfaces[i].v2],lX[mfaces[i].v3],triunnormal);
|
||||||
|
|
||||||
pdDoEffectors(effectors, lX[mfaces[i].v1], force, speed, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
|
VECCOPY(trinormal, triunnormal);
|
||||||
VECCOPY(wind_normalized, speed);
|
Normalize(trinormal);
|
||||||
Normalize(wind_normalized);
|
|
||||||
VecMulf(wind_normalized, -calculateVertexWindForce(speed, vertexnormal));
|
|
||||||
|
|
||||||
|
// add wind from v1
|
||||||
|
VECCOPY(tmp, trinormal);
|
||||||
|
VecMulf(tmp, calculateVertexWindForce(winvec[mfaces[i].v1], triunnormal));
|
||||||
|
VECADDS(lF[mfaces[i].v1], lF[mfaces[i].v1], tmp, factor);
|
||||||
|
|
||||||
|
// add wind from v2
|
||||||
|
VECCOPY(tmp, trinormal);
|
||||||
|
VecMulf(tmp, calculateVertexWindForce(winvec[mfaces[i].v2], triunnormal));
|
||||||
|
VECADDS(lF[mfaces[i].v2], lF[mfaces[i].v2], tmp, factor);
|
||||||
|
|
||||||
|
// add wind from v3
|
||||||
|
VECCOPY(tmp, trinormal);
|
||||||
|
VecMulf(tmp, calculateVertexWindForce(winvec[mfaces[i].v3], triunnormal));
|
||||||
|
VECADDS(lF[mfaces[i].v3], lF[mfaces[i].v3], tmp, factor);
|
||||||
|
|
||||||
|
// add wind from v4
|
||||||
if(mfaces[i].v4)
|
if(mfaces[i].v4)
|
||||||
{
|
{
|
||||||
VECADDS(lF[mfaces[i].v1], lF[mfaces[i].v1], wind_normalized, 0.25);
|
VECCOPY(tmp, trinormal);
|
||||||
|
VecMulf(tmp, calculateVertexWindForce(winvec[mfaces[i].v4], triunnormal));
|
||||||
|
VECADDS(lF[mfaces[i].v4], lF[mfaces[i].v4], tmp, factor);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
VECADDS(lF[mfaces[i].v1], lF[mfaces[i].v1], wind_normalized, 1.0 / 3.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
speed[0] = speed[1] = speed[2] = 0.0;
|
|
||||||
pdDoEffectors(effectors, lX[mfaces[i].v2], force, speed, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
|
|
||||||
VECCOPY(wind_normalized, speed);
|
|
||||||
Normalize(wind_normalized);
|
|
||||||
VecMulf(wind_normalized, -calculateVertexWindForce(speed, vertexnormal));
|
|
||||||
if(mfaces[i].v4)
|
|
||||||
{
|
|
||||||
VECADDS(lF[mfaces[i].v2], lF[mfaces[i].v2], wind_normalized, 0.25);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
VECADDS(lF[mfaces[i].v2], lF[mfaces[i].v2], wind_normalized, 1.0 / 3.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
speed[0] = speed[1] = speed[2] = 0.0;
|
|
||||||
pdDoEffectors(effectors, lX[mfaces[i].v3], force, speed, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
|
|
||||||
VECCOPY(wind_normalized, speed);
|
|
||||||
Normalize(wind_normalized);
|
|
||||||
VecMulf(wind_normalized, -calculateVertexWindForce(speed, vertexnormal));
|
|
||||||
if(mfaces[i].v4)
|
|
||||||
{
|
|
||||||
VECADDS(lF[mfaces[i].v3], lF[mfaces[i].v3], wind_normalized, 0.25);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
VECADDS(lF[mfaces[i].v3], lF[mfaces[i].v3], wind_normalized, 1.0 / 3.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
speed[0] = speed[1] = speed[2] = 0.0;
|
|
||||||
if(mfaces[i].v4)
|
|
||||||
{
|
|
||||||
pdDoEffectors(effectors, lX[mfaces[i].v4], force, speed, (float)G.scene->r.cfra, 0.0f, PE_WIND_AS_SPEED);
|
|
||||||
VECCOPY(wind_normalized, speed);
|
|
||||||
Normalize(wind_normalized);
|
|
||||||
VecMulf(wind_normalized, -calculateVertexWindForce(speed, vertexnormal));
|
|
||||||
VECADDS(lF[mfaces[i].v4], lF[mfaces[i].v4], wind_normalized, 0.25);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
del_lfvector(winvec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate spring forces
|
// calculate spring forces
|
||||||
|
@ -2205,177 +2205,6 @@ static int get_particles_from_cache(Object *ob, ParticleSystem *psys, int cfra)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************/
|
|
||||||
/* Effectors */
|
|
||||||
/************************************************/
|
|
||||||
static float falloff_func(float fac, int usemin, float mindist, int usemax, float maxdist, float power)
|
|
||||||
{
|
|
||||||
if(!usemin)
|
|
||||||
mindist= 0.0f;
|
|
||||||
|
|
||||||
if(fac < mindist) {
|
|
||||||
return 1.0f;
|
|
||||||
}
|
|
||||||
else if(usemax) {
|
|
||||||
if(fac>maxdist || (maxdist-mindist)<=0.0f)
|
|
||||||
return 0.0f;
|
|
||||||
|
|
||||||
fac= (fac-mindist)/(maxdist-mindist);
|
|
||||||
return 1.0f - (float)pow((double)fac, (double)power);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return pow((double)1.0f+fac-mindist, (double)-power);
|
|
||||||
}
|
|
||||||
|
|
||||||
static float falloff_func_dist(PartDeflect *pd, float fac)
|
|
||||||
{
|
|
||||||
return falloff_func(fac, pd->flag&PFIELD_USEMIN, pd->mindist, pd->flag&PFIELD_USEMAX, pd->maxdist, pd->f_power);
|
|
||||||
}
|
|
||||||
|
|
||||||
static float falloff_func_rad(PartDeflect *pd, float fac)
|
|
||||||
{
|
|
||||||
return falloff_func(fac, pd->flag&PFIELD_USEMINR, pd->minrad, pd->flag&PFIELD_USEMAXR, pd->maxrad, pd->f_power_r);
|
|
||||||
}
|
|
||||||
|
|
||||||
static float effector_falloff(PartDeflect *pd, float *eff_velocity, float *vec_to_part)
|
|
||||||
{
|
|
||||||
float eff_dir[3], temp[3];
|
|
||||||
float falloff=1.0, fac, r_fac;
|
|
||||||
|
|
||||||
VecCopyf(eff_dir,eff_velocity);
|
|
||||||
Normalize(eff_dir);
|
|
||||||
|
|
||||||
if(pd->flag & PFIELD_POSZ && Inpf(eff_dir,vec_to_part)<0.0f)
|
|
||||||
falloff=0.0f;
|
|
||||||
else switch(pd->falloff){
|
|
||||||
case PFIELD_FALL_SPHERE:
|
|
||||||
fac=VecLength(vec_to_part);
|
|
||||||
falloff= falloff_func_dist(pd, fac);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PFIELD_FALL_TUBE:
|
|
||||||
fac=Inpf(vec_to_part,eff_dir);
|
|
||||||
falloff= falloff_func_dist(pd, ABS(fac));
|
|
||||||
if(falloff == 0.0f)
|
|
||||||
break;
|
|
||||||
|
|
||||||
VECADDFAC(temp,vec_to_part,eff_dir,-fac);
|
|
||||||
r_fac=VecLength(temp);
|
|
||||||
falloff*= falloff_func_rad(pd, r_fac);
|
|
||||||
break;
|
|
||||||
case PFIELD_FALL_CONE:
|
|
||||||
fac=Inpf(vec_to_part,eff_dir);
|
|
||||||
falloff= falloff_func_dist(pd, ABS(fac));
|
|
||||||
if(falloff == 0.0f)
|
|
||||||
break;
|
|
||||||
|
|
||||||
r_fac=saacos(fac/VecLength(vec_to_part))*180.0f/(float)M_PI;
|
|
||||||
falloff*= falloff_func_rad(pd, r_fac);
|
|
||||||
|
|
||||||
break;
|
|
||||||
// case PFIELD_FALL_INSIDE:
|
|
||||||
//for(i=0; i<totface; i++,mface++){
|
|
||||||
// VECCOPY(v1,mvert[mface->v1].co);
|
|
||||||
// VECCOPY(v2,mvert[mface->v2].co);
|
|
||||||
// VECCOPY(v3,mvert[mface->v3].co);
|
|
||||||
|
|
||||||
// if(AxialLineIntersectsTriangle(a,co1, co2, v2, v3, v1, &lambda)){
|
|
||||||
// if(from==PART_FROM_FACE)
|
|
||||||
// (pa+(int)(lambda*size[a])*a0mul)->flag &= ~PARS_UNEXIST;
|
|
||||||
// else /* store number of intersections */
|
|
||||||
// (pa+(int)(lambda*size[a])*a0mul)->loop++;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if(mface->v4){
|
|
||||||
// VECCOPY(v4,mvert[mface->v4].co);
|
|
||||||
|
|
||||||
// if(AxialLineIntersectsTriangle(a,co1, co2, v4, v1, v3, &lambda)){
|
|
||||||
// if(from==PART_FROM_FACE)
|
|
||||||
// (pa+(int)(lambda*size[a])*a0mul)->flag &= ~PARS_UNEXIST;
|
|
||||||
// else
|
|
||||||
// (pa+(int)(lambda*size[a])*a0mul)->loop++;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
// break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return falloff;
|
|
||||||
}
|
|
||||||
static void do_physical_effector(short type, float force_val, float distance, float falloff, float size, float damp,
|
|
||||||
float *eff_velocity, float *vec_to_part, float *velocity, float *field, int planar)
|
|
||||||
{
|
|
||||||
float mag_vec[3]={0,0,0};
|
|
||||||
float temp[3], temp2[3];
|
|
||||||
float eff_vel[3];
|
|
||||||
|
|
||||||
VecCopyf(eff_vel,eff_velocity);
|
|
||||||
Normalize(eff_vel);
|
|
||||||
|
|
||||||
switch(type){
|
|
||||||
case PFIELD_WIND:
|
|
||||||
VECCOPY(mag_vec,eff_vel);
|
|
||||||
|
|
||||||
VecMulf(mag_vec,force_val*falloff);
|
|
||||||
VecAddf(field,field,mag_vec);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PFIELD_FORCE:
|
|
||||||
if(planar)
|
|
||||||
Projf(mag_vec,vec_to_part,eff_vel);
|
|
||||||
else
|
|
||||||
VecCopyf(mag_vec,vec_to_part);
|
|
||||||
|
|
||||||
VecMulf(mag_vec,force_val*falloff);
|
|
||||||
VecAddf(field,field,mag_vec);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PFIELD_VORTEX:
|
|
||||||
Crossf(mag_vec,eff_vel,vec_to_part);
|
|
||||||
Normalize(mag_vec);
|
|
||||||
|
|
||||||
VecMulf(mag_vec,force_val*distance*falloff);
|
|
||||||
VecAddf(field,field,mag_vec);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case PFIELD_MAGNET:
|
|
||||||
if(planar)
|
|
||||||
VecCopyf(temp,eff_vel);
|
|
||||||
else
|
|
||||||
/* magnetic field of a moving charge */
|
|
||||||
Crossf(temp,eff_vel,vec_to_part);
|
|
||||||
|
|
||||||
Crossf(temp2,velocity,temp);
|
|
||||||
VecAddf(mag_vec,mag_vec,temp2);
|
|
||||||
|
|
||||||
VecMulf(mag_vec,force_val*falloff);
|
|
||||||
VecAddf(field,field,mag_vec);
|
|
||||||
break;
|
|
||||||
case PFIELD_HARMONIC:
|
|
||||||
if(planar)
|
|
||||||
Projf(mag_vec,vec_to_part,eff_vel);
|
|
||||||
else
|
|
||||||
VecCopyf(mag_vec,vec_to_part);
|
|
||||||
|
|
||||||
VecMulf(mag_vec,force_val*falloff);
|
|
||||||
VecSubf(field,field,mag_vec);
|
|
||||||
|
|
||||||
VecCopyf(mag_vec,velocity);
|
|
||||||
/* 1.9 is an experimental value to get critical damping at damp=1.0 */
|
|
||||||
VecMulf(mag_vec,damp*1.9f*(float)sqrt(force_val));
|
|
||||||
VecSubf(field,field,mag_vec);
|
|
||||||
break;
|
|
||||||
case PFIELD_NUCLEAR:
|
|
||||||
/*pow here is root of cosine expression below*/
|
|
||||||
//rad=(float)pow(2.0,-1.0/power)*distance/size;
|
|
||||||
//VECCOPY(mag_vec,vec_to_part);
|
|
||||||
//Normalize(mag_vec);
|
|
||||||
//VecMulf(mag_vec,(float)cos(3.0*M_PI/2.0*(1.0-1.0/(pow(rad,power)+1.0)))/(rad+0.2f));
|
|
||||||
//VECADDFAC(field,field,mag_vec,force_val);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static void do_texture_effector(Tex *tex, short mode, short is_2d, float nabla, short object, float *pa_co, float obmat[4][4], float force_val, float falloff, float *field)
|
static void do_texture_effector(Tex *tex, short mode, short is_2d, float nabla, short object, float *pa_co, float obmat[4][4], float force_val, float falloff, float *field)
|
||||||
{
|
{
|
||||||
TexResult result[4];
|
TexResult result[4];
|
||||||
@ -2788,7 +2617,7 @@ void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Object *ob, P
|
|||||||
} else {
|
} else {
|
||||||
do_physical_effector(pd->forcefield,pd->f_strength,distance,
|
do_physical_effector(pd->forcefield,pd->f_strength,distance,
|
||||||
falloff,pd->f_dist,pd->f_damp,eob->obmat[2],vec_to_part,
|
falloff,pd->f_dist,pd->f_damp,eob->obmat[2],vec_to_part,
|
||||||
pa->state.vel,force_field,pd->flag&PFIELD_PLANAR);
|
pa->state.vel,force_field,pd->flag&PFIELD_PLANAR, pd->rng, pd->f_noise);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(ec->type & PSYS_EC_PARTICLE){
|
if(ec->type & PSYS_EC_PARTICLE){
|
||||||
@ -2837,7 +2666,7 @@ void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Object *ob, P
|
|||||||
else
|
else
|
||||||
do_physical_effector(pd->forcefield,pd->f_strength,distance,
|
do_physical_effector(pd->forcefield,pd->f_strength,distance,
|
||||||
falloff,epart->size,pd->f_damp,estate.vel,vec_to_part,
|
falloff,epart->size,pd->f_damp,estate.vel,vec_to_part,
|
||||||
state->vel,force_field,0);
|
state->vel,force_field,0, pd->rng, pd->f_noise);
|
||||||
}
|
}
|
||||||
else if(pd->forcefield==PFIELD_HARMONIC && cfra-framestep <= epa->dietime && cfra>epa->dietime){
|
else if(pd->forcefield==PFIELD_HARMONIC && cfra-framestep <= epa->dietime && cfra>epa->dietime){
|
||||||
/* first step after key release */
|
/* first step after key release */
|
||||||
|
@ -44,6 +44,7 @@ struct RNG* rng_new (unsigned int seed);
|
|||||||
void rng_free (struct RNG* rng);
|
void rng_free (struct RNG* rng);
|
||||||
|
|
||||||
void rng_seed (struct RNG* rng, unsigned int seed);
|
void rng_seed (struct RNG* rng, unsigned int seed);
|
||||||
|
void rng_srandom(struct RNG *rng, unsigned int seed);
|
||||||
int rng_getInt (struct RNG* rng);
|
int rng_getInt (struct RNG* rng);
|
||||||
double rng_getDouble (struct RNG* rng);
|
double rng_getDouble (struct RNG* rng);
|
||||||
float rng_getFloat (struct RNG* rng);
|
float rng_getFloat (struct RNG* rng);
|
||||||
|
@ -81,6 +81,16 @@ void rng_seed(RNG *rng, unsigned int seed) {
|
|||||||
rng->X= (((r_uint64) seed)<<16) | LOWSEED;
|
rng->X= (((r_uint64) seed)<<16) | LOWSEED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rng_srandom(RNG *rng, unsigned int seed) {
|
||||||
|
extern unsigned char hash[]; // noise.c
|
||||||
|
|
||||||
|
rng_seed(rng, seed + hash[seed & 255]);
|
||||||
|
seed= rng_getInt(rng);
|
||||||
|
rng_seed(rng, seed + hash[seed & 255]);
|
||||||
|
seed= rng_getInt(rng);
|
||||||
|
rng_seed(rng, seed + hash[seed & 255]);
|
||||||
|
}
|
||||||
|
|
||||||
int rng_getInt(RNG *rng) {
|
int rng_getInt(RNG *rng) {
|
||||||
rng->X= (MULTIPLIER*rng->X + ADDEND)&MASK;
|
rng->X= (MULTIPLIER*rng->X + ADDEND)&MASK;
|
||||||
return (int) (rng->X>>17);
|
return (int) (rng->X>>17);
|
||||||
@ -132,13 +142,7 @@ void BLI_srand(unsigned int seed) {
|
|||||||
|
|
||||||
/* using hash table to create better seed */
|
/* using hash table to create better seed */
|
||||||
void BLI_srandom(unsigned int seed) {
|
void BLI_srandom(unsigned int seed) {
|
||||||
extern unsigned char hash[]; // noise.c
|
rng_srandom(&theBLI_rng, seed);
|
||||||
|
|
||||||
rng_seed(&theBLI_rng, seed + hash[seed & 255]);
|
|
||||||
seed= rng_getInt(&theBLI_rng);
|
|
||||||
rng_seed(&theBLI_rng, seed + hash[seed & 255]);
|
|
||||||
seed= rng_getInt(&theBLI_rng);
|
|
||||||
rng_seed(&theBLI_rng, seed + hash[seed & 255]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int BLI_rand(void) {
|
int BLI_rand(void) {
|
||||||
|
@ -7731,31 +7731,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
|||||||
idproperties_fix_group_lengths(main->particle);
|
idproperties_fix_group_lengths(main->particle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* only needed until old bad svn/RC1,2 files are saved with a > 17 version -dg */
|
|
||||||
if(main->versionfile == 245 && main->subversionfile < 17) {
|
|
||||||
ModifierData *md;
|
|
||||||
Object *ob;
|
|
||||||
|
|
||||||
for(ob = main->object.first; ob; ob= ob->id.next) {
|
|
||||||
for(md=ob->modifiers.first; md; ) {
|
|
||||||
if(md->type==eModifierType_Cloth) {
|
|
||||||
ModifierData *next;
|
|
||||||
MEM_freeN(((ClothModifierData *)md)->sim_parms);
|
|
||||||
MEM_freeN(((ClothModifierData *)md)->coll_parms);
|
|
||||||
MEM_freeN(((ClothModifierData *)md)->point_cache);
|
|
||||||
((ClothModifierData *)md)->sim_parms = NULL;
|
|
||||||
((ClothModifierData *)md)->coll_parms = NULL;
|
|
||||||
((ClothModifierData *)md)->point_cache = NULL;
|
|
||||||
next=md->next;
|
|
||||||
BLI_remlink(&ob->modifiers, md);
|
|
||||||
md = next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
md = md->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* sun/sky */
|
/* sun/sky */
|
||||||
if(main->versionfile < 246) {
|
if(main->versionfile < 246) {
|
||||||
Lamp *la;
|
Lamp *la;
|
||||||
@ -7782,6 +7757,14 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
|||||||
alphasort_version_246(fd, lib, me);
|
alphasort_version_246(fd, lib, me);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(main->versionfile <= 246 && main->subversionfile < 1){
|
||||||
|
Object *ob;
|
||||||
|
for(ob = main->object.first; ob; ob= ob->id.next) {
|
||||||
|
if(ob->pd && (ob->pd->forcefield == PFIELD_WIND))
|
||||||
|
ob->pd->f_noise = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
|
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
|
||||||
/* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
|
/* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
|
||||||
|
|
||||||
|
@ -67,6 +67,9 @@ typedef struct PartDeflect {
|
|||||||
float tex_nabla;
|
float tex_nabla;
|
||||||
short tex_mode, kink, kink_axis, rt2;
|
short tex_mode, kink, kink_axis, rt2;
|
||||||
struct Tex *tex; /* Texture of the texture effector */
|
struct Tex *tex; /* Texture of the texture effector */
|
||||||
|
struct RNG *rng; /* random noise generator for e.g. wind */
|
||||||
|
float f_noise; /* noise of force (currently used for wind) */
|
||||||
|
int pad;
|
||||||
} PartDeflect;
|
} PartDeflect;
|
||||||
|
|
||||||
typedef struct PointCache {
|
typedef struct PointCache {
|
||||||
|
@ -3411,6 +3411,8 @@ static void object_panel_fields(Object *ob)
|
|||||||
}
|
}
|
||||||
else if(pd->forcefield == PFIELD_HARMONIC)
|
else if(pd->forcefield == PFIELD_HARMONIC)
|
||||||
uiDefButF(block, NUM, B_FIELD_CHANGE, "Damp: ", 10,120,140,20, &pd->f_damp, 0, 10, 10, 0, "Damping of the harmonic force");
|
uiDefButF(block, NUM, B_FIELD_CHANGE, "Damp: ", 10,120,140,20, &pd->f_damp, 0, 10, 10, 0, "Damping of the harmonic force");
|
||||||
|
else if(pd->forcefield == PFIELD_WIND)
|
||||||
|
uiDefButF(block, NUM, B_FIELD_CHANGE, "Noise: ",10,120,140,20, &pd->f_noise, 0, 10, 100, 0, "Noise of the wind force");
|
||||||
}
|
}
|
||||||
uiBlockEndAlign(block);
|
uiBlockEndAlign(block);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user