From f09d6054100a17cc6129d035cf3634394f5e9377 Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Fri, 4 Sep 2009 23:06:15 +0000 Subject: Some particles cleanup & fixes: - Some big refresh issues with softbody & cloth point cache usage should now be fixed. - Removed sticky objects from particles (better stuff will come back when I get to updating reactor particles). - Some initial easy memory efficiency cleanup for ParticleData struct. The ultimate goal is to get particles less memory hungry -> more particles possible in single scene. - Wrong path timing clamping caused hair particles to seem disappeared when changing between normal<->hair particles. - "Calculate to current frame" in cache buttons baked instead of the intended function. - Boids particle data is now a bit better organized. --- source/blender/blenkernel/BKE_particle.h | 4 + source/blender/blenkernel/intern/boids.c | 198 ++++++----- source/blender/blenkernel/intern/cloth.c | 27 +- source/blender/blenkernel/intern/modifier.c | 6 +- source/blender/blenkernel/intern/object.c | 51 +-- source/blender/blenkernel/intern/particle.c | 140 ++++---- source/blender/blenkernel/intern/particle_system.c | 377 ++++++++++----------- source/blender/blenkernel/intern/pointcache.c | 10 +- source/blender/blenkernel/intern/softbody.c | 40 ++- source/blender/blenloader/intern/readfile.c | 9 - source/blender/blenloader/intern/writefile.c | 2 +- source/blender/editors/object/object_edit.c | 3 + source/blender/editors/physics/ed_pointcache.c | 2 +- source/blender/editors/physics/editparticle.c | 61 ++-- source/blender/editors/space_view3d/drawobject.c | 11 +- source/blender/makesdna/DNA_particle_types.h | 45 +-- source/blender/makesrna/intern/rna_particle.c | 42 +-- .../blender/render/intern/source/convertblender.c | 6 +- 18 files changed, 509 insertions(+), 525 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index e24114cd219..15896477a6a 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -59,6 +59,9 @@ struct SurfaceModifierData; struct BVHTreeRay; struct BVHTreeRayHit; +#define PARTICLE_P ParticleData *pa; int p +#define LOOP_PARTICLES for(p=0, pa=psys->particles; ptotpart; p++, pa++) + typedef struct ParticleEffectorCache { struct ParticleEffectorCache *next, *prev; struct Object *ob; @@ -207,6 +210,7 @@ void free_child_path_cache(struct ParticleSystem *psys); void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit); void free_hair(struct ParticleSystem *psys, int softbody); void free_keyed_keys(struct ParticleSystem *psys); +void psys_free_particles(struct ParticleSystem *psys); void psys_free(struct Object * ob, struct ParticleSystem * psys); void psys_free_children(struct ParticleSystem *psys); diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index 5c62e434cb6..18f065b59d9 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -74,6 +74,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, BoidSettings *boids = bbd->part->boids; ParticleEffectorCache *ec; Object *priority_ob = NULL; + BoidParticle *bpa = pa->boid; float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f}; float mul = (rule->type == eBoidRuleType_Avoid ? 1.0 : -1.0); float priority = 0.0f, len = 0.0f; @@ -81,7 +82,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, /* first find out goal/predator with highest priority */ /* if rule->ob specified use it */ - if(gabr->ob && (rule->type != eBoidRuleType_Goal || gabr->ob != pa->stick_ob)) { + if(gabr->ob && (rule->type != eBoidRuleType_Goal || gabr->ob != bpa->ground)) { PartDeflect *pd = gabr->ob->pd; float vec_to_part[3]; @@ -104,7 +105,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, PartDeflect *pd = eob->pd; /* skip current object */ - if(rule->type == eBoidRuleType_Goal && eob == pa->stick_ob) + if(rule->type == eBoidRuleType_Goal && eob == bpa->ground) continue; if(pd->forcefield == PFIELD_BOID && mul * pd->f_strength > 0.0f) { @@ -169,10 +170,10 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, VECCOPY(bbd->goal_nor, nor); } } - else if(rule->type == eBoidRuleType_Avoid && pa->boid->mode == eBoidMode_Climbing && + else if(rule->type == eBoidRuleType_Avoid && bpa->data.mode == eBoidMode_Climbing && priority > 2.0f * gabr->fear_factor) { /* detach from surface and try to fly away from danger */ - VECCOPY(vec_to_part, pa->r_ve); + VECCOPY(vec_to_part, bpa->gravity); VecMulf(vec_to_part, -1.0f); } @@ -205,6 +206,7 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues * KDTreeNearest *ptn = NULL; ParticleEffectorCache *ec; ParticleTarget *pt; + BoidParticle *bpa = pa->boid; float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f}; float co1[3], vel1[3], co2[3], vel2[3]; float len, t, inp, t_min = 2.0f; @@ -231,7 +233,7 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues * Object *eob = ec->ob; /* don't check with current ground object */ - if(eob == pa->stick_ob) + if(eob == bpa->ground) continue; col.md = ( CollisionModifierData * ) ( modifiers_findByType ( eob, eModifierType_Collision ) ); @@ -558,18 +560,19 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va } static int rule_average_speed(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, ParticleData *pa) { + BoidParticle *bpa = pa->boid; BoidRuleAverageSpeed *asbr = (BoidRuleAverageSpeed*)rule; float vec[3] = {0.0f, 0.0f, 0.0f}; if(asbr->wander > 0.0f) { /* abuse pa->r_ave for wandering */ - pa->r_ave[0] += asbr->wander * (-1.0f + 2.0f * BLI_frand()); - pa->r_ave[1] += asbr->wander * (-1.0f + 2.0f * BLI_frand()); - pa->r_ave[2] += asbr->wander * (-1.0f + 2.0f * BLI_frand()); + bpa->wander[0] += asbr->wander * (-1.0f + 2.0f * BLI_frand()); + bpa->wander[1] += asbr->wander * (-1.0f + 2.0f * BLI_frand()); + bpa->wander[2] += asbr->wander * (-1.0f + 2.0f * BLI_frand()); - Normalize(pa->r_ave); + Normalize(bpa->wander); - VECCOPY(vec, pa->r_ave); + VECCOPY(vec, bpa->wander); QuatMulVecf(pa->prev_state.rot, vec); @@ -615,6 +618,7 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti ParticleTarget *pt; ParticleData *epars; ParticleData *enemy_pa = NULL; + BoidParticle *bpa; /* friends & enemies */ float closest_enemy[3] = {0.0f,0.0f,0.0f}; float closest_dist = fbr->distance + 1.0f; @@ -624,8 +628,10 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti /* calculate own group strength */ int neighbors = BLI_kdtree_range_search(bbd->psys->tree, fbr->distance, pa->prev_state.co, NULL, &ptn); - for(n=0; npsys->particles[ptn[n].index].boid->health; + for(n=0; npsys->particles[ptn[n].index].boid; + health += bpa->data.health; + } f_strength += bbd->part->boids->strength * health; @@ -642,7 +648,8 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti health = 0.0f; for(n=0; nhealth; + bpa = epars[ptn[n].index].boid; + health += bpa->data.health; if(n==0 && pt->mode==PTARGET_MODE_ENEMY && ptn[n].dist < closest_dist) { VECCOPY(closest_enemy, ptn[n].co); @@ -674,7 +681,8 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti /* must face enemy to fight */ if(Inpf(pa->prev_state.ave, enemy_dir)>0.5f) { - enemy_pa->boid->health -= bbd->part->boids->strength * bbd->timestep * ((1.0f-bbd->part->boids->accuracy)*damage + bbd->part->boids->accuracy); + bpa = enemy_pa->boid; + bpa->data.health -= bbd->part->boids->strength * bbd->timestep * ((1.0f-bbd->part->boids->accuracy)*damage + bbd->part->boids->accuracy); } } else { @@ -683,7 +691,8 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti } /* check if boid doesn't want to fight */ - if(pa->boid->health/bbd->part->boids->health * bbd->part->boids->aggression < e_strength / f_strength) { + bpa = pa->boid; + if(bpa->data.health/bbd->part->boids->health * bbd->part->boids->aggression < e_strength / f_strength) { /* decide to flee */ if(closest_dist < fbr->flee_distance * fbr->distance) { VecMulf(bbd->wanted_co, -1.0f); @@ -721,18 +730,20 @@ static boid_rule_cb boid_rules[] = { static void set_boid_values(BoidValues *val, BoidSettings *boids, ParticleData *pa) { - if(ELEM(pa->boid->mode, eBoidMode_OnLand, eBoidMode_Climbing)) { - val->max_speed = boids->land_max_speed * pa->boid->health/boids->health; + BoidParticle *bpa = pa->boid; + + if(ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)) { + val->max_speed = boids->land_max_speed * bpa->data.health/boids->health; val->max_acc = boids->land_max_acc * val->max_speed; - val->max_ave = boids->land_max_ave * M_PI * pa->boid->health/boids->health; + val->max_ave = boids->land_max_ave * M_PI * bpa->data.health/boids->health; val->min_speed = 0.0f; /* no minimum speed on land */ val->personal_space = boids->land_personal_space; - val->jump_speed = boids->land_jump_speed * pa->boid->health/boids->health; + val->jump_speed = boids->land_jump_speed * bpa->data.health/boids->health; } else { - val->max_speed = boids->air_max_speed * pa->boid->health/boids->health; + val->max_speed = boids->air_max_speed * bpa->data.health/boids->health; val->max_acc = boids->air_max_acc * val->max_speed; - val->max_ave = boids->air_max_ave * M_PI * pa->boid->health/boids->health; + val->max_ave = boids->air_max_ave * M_PI * bpa->data.health/boids->health; val->min_speed = boids->air_min_speed * boids->air_max_speed; val->personal_space = boids->air_personal_space; val->jump_speed = 0.0f; /* no jumping in air */ @@ -740,11 +751,13 @@ static void set_boid_values(BoidValues *val, BoidSettings *boids, ParticleData * } static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *ground_co, float *ground_nor) { - if(pa->boid->mode == eBoidMode_Climbing) { + BoidParticle *bpa = pa->boid; + + if(bpa->data.mode == eBoidMode_Climbing) { SurfaceModifierData *surmd = NULL; float x[3], v[3]; - surmd = (SurfaceModifierData *)modifiers_findByType ( pa->stick_ob, eModifierType_Surface ); + surmd = (SurfaceModifierData *)modifiers_findByType ( bpa->ground, eModifierType_Surface ); /* take surface velocity into account */ effector_find_co(bbd->scene, pa->state.co, surmd, NULL, NULL, x, NULL, v, NULL); @@ -753,7 +766,7 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro /* get actual position on surface */ effector_find_co(bbd->scene, x, surmd, NULL, NULL, ground_co, ground_nor, NULL, NULL); - return pa->stick_ob; + return bpa->ground; } else { float zvec[3] = {0.0f, 0.0f, 2000.0f}; @@ -803,13 +816,15 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro } static int boid_rule_applies(ParticleData *pa, BoidSettings *boids, BoidRule *rule) { + BoidParticle *bpa = pa->boid; + if(rule==NULL) return 0; - if(ELEM(pa->boid->mode, eBoidMode_OnLand, eBoidMode_Climbing) && rule->flag & BOIDRULE_ON_LAND) + if(ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing) && rule->flag & BOIDRULE_ON_LAND) return 1; - if(pa->boid->mode==eBoidMode_InAir && rule->flag & BOIDRULE_IN_AIR) + if(bpa->data.mode==eBoidMode_InAir && rule->flag & BOIDRULE_IN_AIR) return 1; return 0; @@ -835,12 +850,13 @@ void boids_precalc_rules(ParticleSettings *part, float cfra) } static void boid_climb(BoidSettings *boids, ParticleData *pa, float *surface_co, float *surface_nor) { + BoidParticle *bpa = pa->boid; float nor[3], vel[3]; VECCOPY(nor, surface_nor); - /* gather apparent gravity to r_ve */ - VECADDFAC(pa->r_ve, pa->r_ve, surface_nor, -1.0); - Normalize(pa->r_ve); + /* gather apparent gravity */ + VECADDFAC(bpa->gravity, bpa->gravity, surface_nor, -1.0); + Normalize(bpa->gravity); /* raise boid it's size from surface */ VecMulf(nor, pa->size * boids->height); @@ -877,16 +893,17 @@ static int apply_boid_rule(BoidBrainData *bbd, BoidRule *rule, BoidValues *val, } static BoidState *get_boid_state(BoidSettings *boids, ParticleData *pa) { BoidState *state = boids->states.first; + BoidParticle *bpa = pa->boid; for(; state; state=state->next) { - if(state->id==pa->boid->state_id) + if(state->id==bpa->data.state_id) return state; } /* for some reason particle isn't at a valid state */ state = boids->states.first; if(state) - pa->boid->state_id = state->id; + bpa->data.state_id = state->id; return state; } @@ -902,9 +919,11 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) BoidSettings *boids = bbd->part->boids; BoidValues val; BoidState *state = get_boid_state(boids, pa); + BoidParticle *bpa = pa->boid; + int rand; //BoidCondition *cond; - if(pa->boid->health <= 0.0f) { + if(bpa->data.health <= 0.0f) { pa->alive = PARS_DYING; return; } @@ -922,7 +941,9 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) bbd->wanted_co[0]=bbd->wanted_co[1]=bbd->wanted_co[2]=bbd->wanted_speed=0.0f; /* create random seed for every particle & frame */ - BLI_srandom(bbd->psys->seed + p + (int)bbd->cfra + (int)(1000*pa->r_rot[0])); + BLI_srandom(bbd->psys->seed + p); + rand = BLI_rand(); + BLI_srandom((int)bbd->cfra + rand); set_boid_values(&val, bbd->part->boids, pa); @@ -939,7 +960,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) case eBoidRulesetType_Random: { /* use random rule for each particle (allways same for same particle though) */ - rule = BLI_findlink(&state->rules, (int)(1000.0f * pa->r_rot[1]) % BLI_countlist(&state->rules)); + rule = BLI_findlink(&state->rules, rand % BLI_countlist(&state->rules)); apply_boid_rule(bbd, rule, &val, pa, -1.0); } @@ -969,7 +990,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) } /* decide on jumping & liftoff */ - if(pa->boid->mode == eBoidMode_OnLand) { + if(bpa->data.mode == eBoidMode_OnLand) { /* fuzziness makes boids capable of misjudgement */ float mul = 1.0 + state->rule_fuzziness; @@ -983,7 +1004,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) Normalize2(cvel); if(Inp2f(cvel, dir) > 0.95 / mul) - pa->boid->mode = eBoidMode_Liftoff; + bpa->data.mode = eBoidMode_Liftoff; } else if(val.jump_speed > 0.0f) { float jump_v[3]; @@ -1036,7 +1057,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) if(jump) { VECCOPY(pa->prev_state.vel, jump_v); - pa->boid->mode = eBoidMode_Falling; + bpa->data.mode = eBoidMode_Falling; } } } @@ -1045,6 +1066,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) void boid_body(BoidBrainData *bbd, ParticleData *pa) { BoidSettings *boids = bbd->part->boids; + BoidParticle *bpa = pa->boid; BoidValues val; float acc[3] = {0.0f, 0.0f, 0.0f}, tan_acc[3], nor_acc[3]; float dvec[3], bvec[3]; @@ -1066,10 +1088,10 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) pa_mass*=pa->size; /* if boids can't fly they fall to the ground */ - if((boids->options & BOID_ALLOW_FLIGHT)==0 && ELEM(pa->boid->mode, eBoidMode_OnLand, eBoidMode_Climbing)==0 && bbd->part->acc[2] != 0.0f) - pa->boid->mode = eBoidMode_Falling; + if((boids->options & BOID_ALLOW_FLIGHT)==0 && ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)==0 && bbd->part->acc[2] != 0.0f) + bpa->data.mode = eBoidMode_Falling; - if(pa->boid->mode == eBoidMode_Falling) { + if(bpa->data.mode == eBoidMode_Falling) { /* Falling boids are only effected by gravity. */ acc[2] = bbd->part->acc[2]; } @@ -1079,14 +1101,14 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) float level = landing_level + 1.0f; float new_vel[3]; - if(pa->boid->mode == eBoidMode_Liftoff) { - pa->boid->mode = eBoidMode_InAir; - pa->stick_ob = boid_find_ground(bbd, pa, ground_co, ground_nor); + if(bpa->data.mode == eBoidMode_Liftoff) { + bpa->data.mode = eBoidMode_InAir; + bpa->ground = boid_find_ground(bbd, pa, ground_co, ground_nor); } - else if(pa->boid->mode == eBoidMode_InAir && boids->options & BOID_ALLOW_LAND) { + else if(bpa->data.mode == eBoidMode_InAir && boids->options & BOID_ALLOW_LAND) { /* auto-leveling & landing if close to ground */ - pa->stick_ob = boid_find_ground(bbd, pa, ground_co, ground_nor); + bpa->ground = boid_find_ground(bbd, pa, ground_co, ground_nor); /* level = how many particle sizes above ground */ level = (pa->prev_state.co[2] - ground_co[2])/(2.0f * pa->size) - 0.5; @@ -1097,7 +1119,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) if(level < 1.0f) { bbd->wanted_co[0] = bbd->wanted_co[1] = bbd->wanted_co[2] = 0.0f; bbd->wanted_speed = 0.0f; - pa->boid->mode = eBoidMode_Falling; + bpa->data.mode = eBoidMode_Falling; } else if(level < landing_level) { bbd->wanted_speed *= (level - 1.0f)/landing_level; @@ -1188,7 +1210,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) /* account for effectors */ do_effectors(p, pa, &pa->state, bbd->scene, bbd->ob, bbd->psys, pa->state.co, force, tvel, bbd->dfra, bbd->cfra); - if(ELEM(pa->boid->mode, eBoidMode_OnLand, eBoidMode_Climbing)) { + if(ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)) { float length = Normalize(force); length = MAX2(0.0f, length - boids->land_stick_force); @@ -1199,8 +1221,8 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) VecAddf(acc, acc, force); /* store smoothed acceleration for nice banking etc. */ - VECADDFAC(pa->boid->acc, pa->boid->acc, acc, dtime); - VecMulf(pa->boid->acc, 1.0f / (1.0f + dtime)); + VECADDFAC(bpa->data.acc, bpa->data.acc, acc, dtime); + VecMulf(bpa->data.acc, 1.0f / (1.0f + dtime)); /* integrate new location & velocity */ @@ -1218,32 +1240,32 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) VECADDFAC(pa->state.vel, pa->state.vel, acc, dtime); - if(pa->boid->mode != eBoidMode_InAir) - pa->stick_ob = boid_find_ground(bbd, pa, ground_co, ground_nor); + if(bpa->data.mode != eBoidMode_InAir) + bpa->ground = boid_find_ground(bbd, pa, ground_co, ground_nor); /* change modes, constrain movement & keep track of down vector */ - switch(pa->boid->mode) { + switch(bpa->data.mode) { case eBoidMode_InAir: { float grav[3] = {0.0f, 0.0f, bbd->part->acc[2] < 0.0f ? -1.0f : 0.0f}; /* don't take forward acceleration into account (better banking) */ - if(Inpf(pa->boid->acc, pa->state.vel) > 0.0f) { - Projf(dvec, pa->boid->acc, pa->state.vel); - VecSubf(dvec, pa->boid->acc, dvec); + if(Inpf(bpa->data.acc, pa->state.vel) > 0.0f) { + Projf(dvec, bpa->data.acc, pa->state.vel); + VecSubf(dvec, bpa->data.acc, dvec); } else { - VECCOPY(dvec, pa->boid->acc); + VECCOPY(dvec, bpa->data.acc); } - /* gather apparent gravity to r_ve */ - VECADDFAC(pa->r_ve, grav, dvec, -boids->banking); - Normalize(pa->r_ve); + /* gather apparent gravity */ + VECADDFAC(bpa->gravity, grav, dvec, -boids->banking); + Normalize(bpa->gravity); /* stick boid on goal when close enough */ if(bbd->goal_ob && boid_goal_signed_dist(pa->state.co, bbd->goal_co, bbd->goal_nor) <= pa->size * boids->height) { - pa->boid->mode = eBoidMode_Climbing; - pa->stick_ob = bbd->goal_ob; + bpa->data.mode = eBoidMode_Climbing; + bpa->ground = bbd->goal_ob; boid_find_ground(bbd, pa, ground_co, ground_nor); boid_climb(boids, pa, ground_co, ground_nor); } @@ -1251,7 +1273,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) else if(boids->options & BOID_ALLOW_LAND && pa->state.co[2] <= ground_co[2] + pa->size * boids->height) { pa->state.co[2] = ground_co[2] + pa->size * boids->height; pa->state.vel[2] = 0.0f; - pa->boid->mode = eBoidMode_OnLand; + bpa->data.mode = eBoidMode_OnLand; } break; } @@ -1259,15 +1281,15 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) { float grav[3] = {0.0f, 0.0f, bbd->part->acc[2] < 0.0f ? -1.0f : 0.0f}; - /* gather apparent gravity to r_ve */ - VECADDFAC(pa->r_ve, pa->r_ve, grav, dtime); - Normalize(pa->r_ve); + /* gather apparent gravity */ + VECADDFAC(bpa->gravity, bpa->gravity, grav, dtime); + Normalize(bpa->gravity); if(boids->options & BOID_ALLOW_LAND) { /* stick boid on goal when close enough */ if(bbd->goal_ob && boid_goal_signed_dist(pa->state.co, bbd->goal_co, bbd->goal_nor) <= pa->size * boids->height) { - pa->boid->mode = eBoidMode_Climbing; - pa->stick_ob = bbd->goal_ob; + bpa->data.mode = eBoidMode_Climbing; + bpa->ground = bbd->goal_ob; boid_find_ground(bbd, pa, ground_co, ground_nor); boid_climb(boids, pa, ground_co, ground_nor); } @@ -1275,14 +1297,14 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) else if(pa->state.co[2] <= ground_co[2] + 1.01 * pa->size * boids->height){ pa->state.co[2] = ground_co[2] + pa->size * boids->height; pa->state.vel[2] = 0.0f; - pa->boid->mode = eBoidMode_OnLand; + bpa->data.mode = eBoidMode_OnLand; } /* if we're falling, can fly and want to go upwards lets fly */ else if(boids->options & BOID_ALLOW_FLIGHT && bbd->wanted_co[2] > 0.0f) - pa->boid->mode = eBoidMode_InAir; + bpa->data.mode = eBoidMode_InAir; } else - pa->boid->mode = eBoidMode_InAir; + bpa->data.mode = eBoidMode_InAir; break; } case eBoidMode_Climbing: @@ -1308,14 +1330,14 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) { /* stick boid on goal when close enough */ if(bbd->goal_ob && boid_goal_signed_dist(pa->state.co, bbd->goal_co, bbd->goal_nor) <= pa->size * boids->height) { - pa->boid->mode = eBoidMode_Climbing; - pa->stick_ob = bbd->goal_ob; + bpa->data.mode = eBoidMode_Climbing; + bpa->ground = bbd->goal_ob; boid_find_ground(bbd, pa, ground_co, ground_nor); boid_climb(boids, pa, ground_co, ground_nor); } /* ground is too far away so boid falls */ else if(pa->state.co[2]-ground_co[2] > 1.1 * pa->size * boids->height) - pa->boid->mode = eBoidMode_Falling; + bpa->data.mode = eBoidMode_Falling; else { /* constrain to surface */ pa->state.co[2] = ground_co[2] + pa->size * boids->height; @@ -1329,17 +1351,17 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) VECCOPY(grav, ground_nor); VecMulf(grav, -1.0f); - Projf(dvec, pa->boid->acc, pa->state.vel); - VecSubf(dvec, pa->boid->acc, dvec); + Projf(dvec, bpa->data.acc, pa->state.vel); + VecSubf(dvec, bpa->data.acc, dvec); - /* gather apparent gravity to r_ve */ - VECADDFAC(pa->r_ve, grav, dvec, -boids->banking); - Normalize(pa->r_ve); + /* gather apparent gravity */ + VECADDFAC(bpa->gravity, grav, dvec, -boids->banking); + Normalize(bpa->gravity); } else { - /* gather negative surface normal to r_ve */ - VECADDFAC(pa->r_ve, pa->r_ve, ground_nor, -1.0f); - Normalize(pa->r_ve); + /* gather negative surface normal */ + VECADDFAC(bpa->gravity, bpa->gravity, ground_nor, -1.0f); + Normalize(bpa->gravity); } break; } @@ -1347,29 +1369,29 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) /* save direction to state.ave unless the boid is falling */ /* (boids can't effect their direction when falling) */ - if(pa->boid->mode!=eBoidMode_Falling && VecLength(pa->state.vel) > 0.1*pa->size) { + if(bpa->data.mode!=eBoidMode_Falling && VecLength(pa->state.vel) > 0.1*pa->size) { VECCOPY(pa->state.ave, pa->state.vel); Normalize(pa->state.ave); } /* apply damping */ - if(ELEM(pa->boid->mode, eBoidMode_OnLand, eBoidMode_Climbing)) + if(ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)) VecMulf(pa->state.vel, 1.0f - 0.2f*bbd->part->dampfac); /* calculate rotation matrix based on forward & down vectors */ - if(pa->boid->mode == eBoidMode_InAir) { + if(bpa->data.mode == eBoidMode_InAir) { VECCOPY(mat[0], pa->state.ave); - Projf(dvec, pa->r_ve, pa->state.ave); - VecSubf(mat[2], pa->r_ve, dvec); + Projf(dvec, bpa->gravity, pa->state.ave); + VecSubf(mat[2], bpa->gravity, dvec); Normalize(mat[2]); } else { - Projf(dvec, pa->state.ave, pa->r_ve); + Projf(dvec, pa->state.ave, bpa->gravity); VecSubf(mat[0], pa->state.ave, dvec); Normalize(mat[0]); - VECCOPY(mat[2], pa->r_ve); + VECCOPY(mat[2], bpa->gravity); } VecMulf(mat[2], -1.0f); Crossf(mat[1], mat[2], mat[0]); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index eafd9eb01fe..8be8df8e63b 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -496,23 +496,30 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, if(!do_init_cloth(ob, clmd, result, framenr)) return result; + if(framenr == startframe && cache->flag & PTCACHE_REDO_NEEDED) { + BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); + cache->simframe= framenr; + cache->flag &= ~PTCACHE_REDO_NEEDED; + return result; + } + /* try to read from cache */ cache_result = BKE_ptcache_read_cache(&pid, (float)framenr, scene->r.frs_sec); if(cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) { - cache->flag |= PTCACHE_SIMULATION_VALID; - cache->simframe= framenr; - implicit_set_positions(clmd); cloth_to_object (ob, clmd, result); + cache->simframe= framenr; + cache->flag |= PTCACHE_SIMULATION_VALID; + + if(cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED) + BKE_ptcache_write_cache(&pid, framenr); + return result; } else if(cache_result==PTCACHE_READ_OLD) { - BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_FREE); - implicit_set_positions(clmd); - cache->flag |= PTCACHE_SIMULATION_VALID; } else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) { @@ -524,12 +531,10 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob, } if(framenr == startframe) { - if(cache->flag & PTCACHE_REDO_NEEDED) { - BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); - do_init_cloth(ob, clmd, result, framenr); - } - cache->flag |= PTCACHE_SIMULATION_VALID; + implicit_set_positions(clmd); + cache->simframe= framenr; + cache->flag |= PTCACHE_SIMULATION_VALID; /* don't write cache on first frame, but on second frame write * cache for frame 1 and 2 */ diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 7a0eb882083..9c8c43cc8cb 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -6696,10 +6696,8 @@ static DerivedMesh * particleInstanceModifier_applyModifier( 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) { - /* just use some static collection of random numbers */ - /* TODO: use something else that's unique to each instanced object */ - pa = psys->particles + (i/totvert)%totpart; - ran = pimd->random_position * 0.5 * (1.0f + pa->r_ave[0]); + BLI_srandom(psys->seed + (i/totvert)%totpart); + ran = pimd->random_position * BLI_frand(); } if(pimd->flag & eParticleInstanceFlag_KeepShape) { diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 1cb0abfe21c..9a137bdb7e6 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -481,15 +481,15 @@ void unlink_object(Scene *scene, Object *ob) if(tpsys->part->dup_ob==ob) tpsys->part->dup_ob= NULL; - if(tpsys->part->flag&PART_STICKY) { + if(tpsys->part->phystype==PART_PHYS_BOIDS) { ParticleData *pa; + BoidParticle *bpa; int p; for(p=0,pa=tpsys->particles; ptotpart; p++,pa++) { - if(pa->stick_ob==ob) { - pa->stick_ob= 0; - pa->flag &= ~PARS_STICKY; - } + bpa = pa->boid; + if(bpa->ground == ob) + bpa->ground = NULL; } } if(tpsys->part->boids) { @@ -1082,19 +1082,35 @@ ParticleSystem *copy_particlesystem(ParticleSystem *psys) { ParticleSystem *psysn; ParticleData *pa; - int a; + int p; psysn= MEM_dupallocN(psys); psysn->particles= MEM_dupallocN(psys->particles); psysn->child= MEM_dupallocN(psys->child); - if(psysn->particles->keys) - psysn->particles->keys = MEM_dupallocN(psys->particles->keys); - for(a=0, pa=psysn->particles; atotpart; a++, pa++) { - if(pa->hair) - pa->hair= MEM_dupallocN(pa->hair); - if(a) - pa->keys= (pa-1)->keys + (pa-1)->totkey; + if(psys->part->type == PART_HAIR) { + for(p=0, pa=psysn->particles; ptotpart; p++, pa++) + pa->hair = MEM_dupallocN(pa->hair); + } + + if(psysn->particles->keys || psysn->particles->boid) { + ParticleKey *key = psysn->particles->keys; + BoidParticle *boid = psysn->particles->boid; + + if(key) + key = MEM_dupallocN(key); + + if(boid) + boid = MEM_dupallocN(boid); + + for(p=0, pa=psysn->particles; ptotpart; p++, pa++) { + if(boid) + pa->boid = boid++; + if(key) { + pa->keys = key; + key += pa->totkey; + } + } } if(psys->soft) { @@ -1102,14 +1118,7 @@ ParticleSystem *copy_particlesystem(ParticleSystem *psys) psysn->soft->particles = psysn; } - if(psys->particles->boid) { - psysn->particles->boid = MEM_dupallocN(psys->particles->boid); - for(a=1, pa=psysn->particles+1; atotpart; a++, pa++) - pa->boid = (pa-1)->boid + 1; - } - - if(psys->targets.first) - BLI_duplicatelist(&psysn->targets, &psys->targets); + BLI_duplicatelist(&psysn->targets, &psys->targets); psysn->pathcache= NULL; psysn->childcache= NULL; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 1ae3ec5dd50..81eb0b79c40 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -92,10 +92,10 @@ static void do_child_modifiers(Scene *scene, Object *ob, ParticleSystem *psys, P /* few helpers for countall etc. */ int count_particles(ParticleSystem *psys){ ParticleSettings *part=psys->part; - ParticleData *pa; - int tot=0,p; + PARTICLE_P; + int tot=0; - for(p=0,pa=psys->particles; ptotpart; p++,pa++){ + LOOP_PARTICLES { if(pa->alive == PARS_KILLED); else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0); else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0); @@ -106,10 +106,10 @@ int count_particles(ParticleSystem *psys){ } int count_particles_mod(ParticleSystem *psys, int totgr, int cur){ ParticleSettings *part=psys->part; - ParticleData *pa; - int tot=0,p; + PARTICLE_P; + int tot=0; - for(p=0,pa=psys->particles; ptotpart; p++,pa++){ + LOOP_PARTICLES { if(pa->alive == PARS_KILLED); else if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0); else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0); @@ -120,10 +120,10 @@ int count_particles_mod(ParticleSystem *psys, int totgr, int cur){ } int psys_count_keys(ParticleSystem *psys) { - ParticleData *pa; - int i, totpart=psys->totpart, totkey=0; + PARTICLE_P; + int totkey=0; - for(i=0, pa=psys->particles; itotkey; return totkey; @@ -368,13 +368,16 @@ void psys_free_settings(ParticleSettings *part) void free_hair(ParticleSystem *psys, int softbody) { - ParticleData *pa; - int i, totpart=psys->totpart; + PARTICLE_P; + + if(psys->part->type != PART_HAIR) + return; - for(i=0, pa=psys->particles; ihair) MEM_freeN(pa->hair); pa->hair = NULL; + pa->totkey = 0; } psys->flag &= ~PSYS_HAIR_DONE; @@ -386,13 +389,15 @@ void free_hair(ParticleSystem *psys, int softbody) } void free_keyed_keys(ParticleSystem *psys) { - ParticleData *pa; - int i; + PARTICLE_P; + + if(psys->part->type == PART_HAIR) + return; if(psys->particles && psys->particles->keys) { MEM_freeN(psys->particles->keys); - for(i=0, pa=psys->particles; itotpart; i++, pa++) { + LOOP_PARTICLES { if(pa->keys) { pa->keys= NULL; pa->totkey= 0; @@ -431,6 +436,29 @@ void psys_free_children(ParticleSystem *psys) free_child_path_cache(psys); } +void psys_free_particles(ParticleSystem *psys) +{ + PARTICLE_P; + + if(psys->particles) { + if(psys->part->type==PART_HAIR) { + LOOP_PARTICLES { + if(pa->hair) + MEM_freeN(pa->hair); + } + } + + if(psys->particles->keys) + MEM_freeN(psys->particles->keys); + + if(psys->particles->boid) + MEM_freeN(psys->particles->boid); + + MEM_freeN(psys->particles); + psys->particles= NULL; + psys->totpart= 0; + } +} /* free everything */ void psys_free(Object *ob, ParticleSystem * psys) { @@ -440,22 +468,11 @@ void psys_free(Object *ob, ParticleSystem * psys) psys_free_path_cache(psys, NULL); - free_hair(psys, 1); - - free_keyed_keys(psys); + psys_free_particles(psys); if(psys->edit && psys->free_edit) psys->free_edit(psys->edit); - if(psys->particles){ - if(psys->particles->boid) - MEM_freeN(psys->particles->boid); - - MEM_freeN(psys->particles); - psys->particles = 0; - psys->totpart = 0; - } - if(psys->child){ MEM_freeN(psys->child); psys->child = 0; @@ -485,14 +502,11 @@ void psys_free(Object *ob, ParticleSystem * psys) psys->part=0; } - if(psys->reactevents.first) - BLI_freelistN(&psys->reactevents); - BKE_ptcache_free_list(&psys->ptcaches); psys->pointcache = NULL; - if(psys->targets.first) - BLI_freelistN(&psys->targets); + BLI_freelistN(&psys->targets); + BLI_freelistN(&psys->reactevents); BLI_kdtree_free(psys->tree); @@ -1015,11 +1029,12 @@ static void init_particle_interpolation(Object *ob, ParticleSystem *psys, Partic pind->dietime = *((point->keys + point->totkey - 1)->time); } else if(pind->keyed) { - pind->kkey[0] = pa->keys; - pind->kkey[1] = pa->totkey > 1 ? pa->keys + 1 : NULL; + ParticleKey *key = pa->keys; + pind->kkey[0] = key; + pind->kkey[1] = pa->totkey > 1 ? key + 1 : NULL; - pind->birthtime = pa->keys->time; - pind->dietime = (pa->keys + pa->totkey - 1)->time; + pind->birthtime = key->time; + pind->dietime = (key + pa->totkey - 1)->time; } else if(pind->cache) { get_pointcache_keys_for_time(ob, pind->cache, -1, 0.0f, NULL, NULL); @@ -1028,17 +1043,18 @@ static void init_particle_interpolation(Object *ob, ParticleSystem *psys, Partic pind->dietime = pa ? pa->dietime : pind->cache->endframe; } else { - pind->hkey[0] = pa->hair; - pind->hkey[1] = pa->hair + 1; + HairKey *key = pa->hair; + pind->hkey[0] = key; + pind->hkey[1] = key + 1; - pind->birthtime = pa->hair->time; - pind->dietime = (pa->hair + pa->totkey - 1)->time; + pind->birthtime = key->time; + pind->dietime = (key + pa->totkey - 1)->time; } - if(pind->soft) { - pind->bp[0] = pind->soft->bpoint + pa->bpi; - pind->bp[1] = pind->soft->bpoint + pa->bpi + 1; - } + //if(pind->soft) { + // pind->bp[0] = pind->soft->bpoint + pa->bpi; + // pind->bp[1] = pind->soft->bpoint + pa->bpi + 1; + //} } static void edit_to_particle(ParticleKey *key, PTCacheEditKey *ekey) { @@ -2558,6 +2574,9 @@ void psys_cache_child_paths(Scene *scene, Object *ob, ParticleSystem *psys, floa ListBase threads; int i, totchild, totparent, totthread; + if(psys->flag & PSYS_GLOBAL_HAIR) + return; + pthreads= psys_threads_create(scene, ob, psys); if(!psys_threads_init_path(pthreads, scene, cfra, editupdate)) { @@ -2688,7 +2707,8 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra } if(!psys->totchild) { - pa_length = 1.0f - part->randlength * 0.5 * (1.0f + pa->r_ave[0]); + BLI_srandom(psys->seed + i); + pa_length = 1.0f - part->randlength * BLI_frand(); if(vg_length) pa_length *= psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_length); } @@ -2740,7 +2760,7 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra do_particle_interpolation(psys, i, pa, t, frs_sec, &pind, &result); /* keyed, baked and softbody are allready in global space */ - if(!keyed && !baked && !soft) { + if(!keyed && !baked && !soft && !(psys->flag & PSYS_GLOBAL_HAIR)) { Mat4MulVecfl(hairmat, result.co); } @@ -3574,6 +3594,8 @@ float psys_get_size(Object *ob, Material *ma, ParticleSystemModifierData *psmd, { ParticleTexture ptex; float size=1.0f; + + BLI_srandom(psys->seed + (pa - psys->particles) + 100); if(ma && part->from!=PART_FROM_PARTICLE){ ptex.size=size; @@ -3592,7 +3614,7 @@ float psys_get_size(Object *ob, Material *ma, ParticleSystemModifierData *psmd, size*=psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_size); if(part->randsize!=0.0) - size*= 1.0f - part->randsize*pa->sizemul; + size*= 1.0f - part->randsize * BLI_frand(); return size*part->size; } @@ -3759,13 +3781,6 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i if(pparticles + p; - - if(pa->alive==PARS_DEAD && part->flag & PART_STICKY && pa->flag & PARS_STICKY && pa->stick_ob){ - copy_particle_key(state,&pa->state,0); - key_from_object(pa->stick_ob,state); - return; - } - pind.keyed = keyed; pind.cache = cached ? psys->pointcache : NULL; pind.soft = NULL; @@ -3981,20 +3996,11 @@ int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psy return 0; /* currently not supported */ else if(psys->totchild && p>=psys->totpart){ ChildParticle *cpa=psys->child+p-psys->totpart; - ParticleKey *key1, skey; + ParticleKey *key1; float t = (cfra - pa->time + pa->loop * pa->lifetime) / pa->lifetime; pa = psys->particles + cpa->parent; - - if(pa->alive==PARS_DEAD && part->flag&PART_STICKY && pa->flag&PARS_STICKY && pa->stick_ob) { - key1 = &skey; - copy_particle_key(key1,&pa->state,0); - key_from_object(pa->stick_ob,key1); - } - else { - key1=&pa->state; - } - + key1=&pa->state; offset_child(cpa, key1, state, part->childflat, part->childrad); CLAMP(t,0.0,1.0); @@ -4051,10 +4057,6 @@ int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psy } } - if(pa->alive==PARS_DEAD && part->flag&PART_STICKY && pa->flag&PARS_STICKY && pa->stick_ob){ - key_from_object(pa->stick_ob,state); - } - if(psys->lattice) calc_latt_deform(psys->lattice, state->co,1.0f); } diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 0f72c1c5866..eb570ba287c 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -123,21 +123,11 @@ static int get_current_display_percentage(ParticleSystem *psys) void psys_reset(ParticleSystem *psys, int mode) { ParticleSettings *part= psys->part; - ParticleData *pa; - int i; + PARTICLE_P; if(ELEM(mode, PSYS_RESET_ALL, PSYS_RESET_DEPSGRAPH)) { if(mode == PSYS_RESET_ALL || !(part->type == PART_HAIR && (psys->edit && psys->edit->edited))) { - if(psys->particles) { - if(psys->particles->keys) - MEM_freeN(psys->particles->keys); - - for(i=0, pa=psys->particles; itotpart; i++, pa++) - if(pa->hair) MEM_freeN(pa->hair); - - MEM_freeN(psys->particles); - psys->particles= NULL; - } + psys_free_particles(psys); psys->totpart= 0; psys->totkeyed= 0; @@ -155,10 +145,7 @@ void psys_reset(ParticleSystem *psys, int mode) } else if(mode == PSYS_RESET_CACHE_MISS) { /* set all particles to be skipped */ - ParticleData *pa = psys->particles; - int p=0; - - for(; ptotpart; p++, pa++) + LOOP_PARTICLES pa->flag |= PARS_NO_DISP; } @@ -180,9 +167,10 @@ void psys_reset(ParticleSystem *psys, int mode) static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart) { - ParticleData *newpars = 0, *pa; - BoidData *newboids = 0; - int i, totpart, totsaved = 0; + ParticleData *newpars = NULL; + BoidParticle *newboids = NULL; + PARTICLE_P; + int totpart, totsaved = 0; if(new_totpart<0) { if(psys->part->distr==PART_DISTR_GRID && psys->part->from != PART_FROM_VERT) { @@ -195,47 +183,46 @@ static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart) else totpart=new_totpart; - if(totpart) { + if(totpart && totpart != psys->totpart) { newpars= MEM_callocN(totpart*sizeof(ParticleData), "particles"); + + if(psys->particles) { + totsaved=MIN2(psys->totpart,totpart); + /*save old pars*/ + if(totsaved) { + memcpy(newpars,psys->particles,totsaved*sizeof(ParticleData)); + + if(psys->particles->boid) + memcpy(newboids, psys->particles->boid, totsaved*sizeof(BoidParticle)); + } - if(psys->part->phystype == PART_PHYS_BOIDS) - newboids = MEM_callocN(totpart*sizeof(BoidData), "Boid Data"); - } - if(psys->particles) { - totsaved=MIN2(psys->totpart,totpart); - /*save old pars*/ - if(totsaved) { - memcpy(newpars,psys->particles,totsaved*sizeof(ParticleData)); - - if(newboids) - memcpy(newboids, psys->particles->boid, totsaved*sizeof(BoidData)); - } - - if(psys->particles->keys) - MEM_freeN(psys->particles->keys); + if(psys->particles->keys) + MEM_freeN(psys->particles->keys); - if(psys->particles->boid) - MEM_freeN(psys->particles->boid); + if(psys->particles->boid) + MEM_freeN(psys->particles->boid); - for(i=0, pa=newpars; ikeys) { - pa->keys= NULL; - pa->totkey= 0; + for(p=0, pa=newpars; pkeys) { + pa->keys= NULL; + pa->totkey= 0; + } } - } - for(i=totsaved, pa=psys->particles+totsaved; itotpart; i++, pa++) - if(pa->hair) MEM_freeN(pa->hair); + for(p=totsaved, pa=psys->particles+totsaved; ptotpart; p++, pa++) + if(pa->hair) MEM_freeN(pa->hair); - MEM_freeN(psys->particles); - } - psys->particles=newpars; + MEM_freeN(psys->particles); + } + + psys->particles=newpars; - if(newboids) { - pa = psys->particles; - pa->boid = newboids; - for(i=1, pa++; iboid = (pa-1)->boid + 1; + if(newboids) { + LOOP_PARTICLES + pa->boid = newboids++; + } + + psys->totpart=totpart; } if(psys->child) { @@ -243,8 +230,6 @@ static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart) psys->child=0; psys->totchild=0; } - - psys->totpart=totpart; } static int get_psys_child_number(struct Scene *scene, ParticleSystem *psys) @@ -291,8 +276,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys) each original elements can reference its derived elements */ Mesh *me= (Mesh*)ob->data; - ParticleData *pa= 0; - int p; + PARTICLE_P; /* CACHE LOCATIONS */ if(!dm->deformedOnly) { @@ -329,7 +313,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys) } /* cache the verts/faces! */ - for(p=0,pa=psys->particles; ptotpart; p++,pa++) { + LOOP_PARTICLES { if(psys->part->from == PART_FROM_VERT) { if(nodearray[pa->num]) pa->num_dmcache= GET_INT_FROM_POINTER(nodearray[pa->num]->link); @@ -349,7 +333,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys) * should know to use the num or num_dmcache, set the num_dmcache to * an invalid value, just incase */ - for(p=0,pa=psys->particles; ptotpart; p++,pa++) + LOOP_PARTICLES pa->num_dmcache = -1; } } @@ -1449,12 +1433,11 @@ static void distribute_particles_on_dm(DerivedMesh *finaldm, Scene *scene, Objec /* ready for future use, to emit particles without geometry */ static void distribute_particles_on_shape(Object *ob, ParticleSystem *psys, int from) { - ParticleData *pa; - int totpart=psys->totpart, p; + PARTICLE_P; fprintf(stderr,"Shape emission not yet possible!\n"); - for(p=0,pa=psys->particles; pfuv[0]=pa->fuv[1]=pa->fuv[2]=pa->fuv[3]= 0.0; pa->foffset= 0.0f; pa->num= -1; @@ -1476,12 +1459,11 @@ static void distribute_particles(Scene *scene, Object *ob, ParticleSystem *psys, distribute_particles_on_shape(ob,psys,from); if(distr_error){ - ParticleData *pa; - int totpart=psys->totpart, p; + PARTICLE_P; fprintf(stderr,"Particle distribution error!\n"); - for(p=0,pa=psys->particles; pfuv[0]=pa->fuv[1]=pa->fuv[2]=pa->fuv[3]= 0.0; pa->foffset= 0.0f; pa->num= -1; @@ -1576,7 +1558,7 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps Material *ma=0; //IpoCurve *icu=0; // XXX old animation system int totpart; - float rand,length; + float rand; part=psys->part; @@ -1631,40 +1613,8 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps pa->dietime= pa->time+pa->lifetime; - pa->sizemul= BLI_frand(); - - rand= BLI_frand(); - - /* while loops are to have a spherical distribution (avoid cubic distribution) */ - if(part->phystype != PART_PHYS_BOIDS) { - /* boids store gravity in r_ve, so skip here */ - length=2.0f; - while(length>1.0){ - pa->r_ve[0]=2.0f*(BLI_frand()-0.5f); - pa->r_ve[1]=2.0f*(BLI_frand()-0.5f); - pa->r_ve[2]=2.0f*(BLI_frand()-0.5f); - length=VecLength(pa->r_ve); - } - } - - length=2.0f; - while(length>1.0){ - pa->r_ave[0]=2.0f*(BLI_frand()-0.5f); - pa->r_ave[1]=2.0f*(BLI_frand()-0.5f); - pa->r_ave[2]=2.0f*(BLI_frand()-0.5f); - length=VecLength(pa->r_ave); - } - - pa->r_rot[0]=2.0f*(BLI_frand()-0.5f); - pa->r_rot[1]=2.0f*(BLI_frand()-0.5f); - pa->r_rot[2]=2.0f*(BLI_frand()-0.5f); - pa->r_rot[3]=2.0f*(BLI_frand()-0.5f); - - NormalQuat(pa->r_rot); - if(part->type!=PART_HAIR && part->distr!=PART_DISTR_GRID && part->from != PART_FROM_VERT){ - /* any unique random number will do (r_ave[0]) */ - if(ptex.exist < 0.5*(1.0+pa->r_ave[0])) + if(ptex.exist < BLI_frand()) pa->flag |= PARS_UNEXIST; else pa->flag &= ~PARS_UNEXIST; @@ -1678,10 +1628,9 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps static void initialize_all_particles(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd) { //IpoCurve *icu=0; // XXX old animation system - ParticleData *pa; - int p, totpart=psys->totpart; + PARTICLE_P; - for(p=0, pa=psys->particles; ppart->type != PART_FLUID) { @@ -1749,10 +1698,39 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic float fac, phasefac, nor[3]={0,0,0},loc[3],tloc[3],vel[3]={0.0,0.0,0.0},rot[4],q2[4]; float r_vel[3],r_ave[3],r_rot[4],p_vel[3]={0.0,0.0,0.0}; float x_vec[3]={1.0,0.0,0.0}, utan[3]={0.0,1.0,0.0}, vtan[3]={0.0,0.0,1.0}, rot_vec[3]={0.0,0.0,0.0}; - float q_phase[4]; + float q_phase[4], length, r_phase; part=psys->part; ptex.ivel=1.0; + + BLI_srandom(psys->seed + (pa - psys->particles)); + + /* we need to get every random even if they're not used so that they don't effect eachother */ + /* while loops are to have a spherical distribution (avoid cubic distribution) */ + length=2.0f; + while(length>1.0){ + r_vel[0]=2.0f*(BLI_frand()-0.5f); + r_vel[1]=2.0f*(BLI_frand()-0.5f); + r_vel[2]=2.0f*(BLI_frand()-0.5f); + length=VecLength(r_vel); + } + + length=2.0f; + while(length>1.0){ + r_ave[0]=2.0f*(BLI_frand()-0.5f); + r_ave[1]=2.0f*(BLI_frand()-0.5f); + r_ave[2]=2.0f*(BLI_frand()-0.5f); + length=VecLength(r_ave); + } + + r_rot[0]=2.0f*(BLI_frand()-0.5f); + r_rot[1]=2.0f*(BLI_frand()-0.5f); + r_rot[2]=2.0f*(BLI_frand()-0.5f); + r_rot[3]=2.0f*(BLI_frand()-0.5f); + + NormalQuat(r_rot); + + r_phase = BLI_frand(); if(part->from==PART_FROM_PARTICLE){ Object *tob; @@ -1763,29 +1741,26 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic if(tob==0) tob=ob; - tpsys=BLI_findlink(&tob->particlesystem,psys->target_psys-1); + tpsys=BLI_findlink(&tob->particlesystem, psys->target_psys-1); state.time = pa->time; if(pa->num == -1) memset(&state, 0, sizeof(state)); else psys_get_particle_state(scene, tob,tpsys,pa->num,&state,1); - psys_get_from_key(&state,loc,nor,rot,0); + psys_get_from_key(&state, loc, nor, rot, 0); - QuatMulVecf(rot,vtan); - QuatMulVecf(rot,utan); - VECCOPY(r_vel,pa->r_ve); - VECCOPY(r_rot,pa->r_rot); - VECCOPY(r_ave,pa->r_ave); + QuatMulVecf(rot, vtan); + QuatMulVecf(rot, utan); - VECCOPY(p_vel,state.vel); + VECCOPY(p_vel, state.vel); speed=Normalize(p_vel); - VecMulf(p_vel,Inpf(pa->r_ve,p_vel)); - VECSUB(p_vel,pa->r_ve,p_vel); + VecMulf(p_vel, Inpf(r_vel, p_vel)); + VECSUB(p_vel, r_vel, p_vel); Normalize(p_vel); - VecMulf(p_vel,speed); + VecMulf(p_vel, speed); - VECCOPY(pa->fuv,loc); /* abusing pa->fuv (not used for "from particle") for storing emit location */ + VECCOPY(pa->fuv, loc); /* abusing pa->fuv (not used for "from particle") for storing emit location */ } else{ /* get precise emitter matrix if particle is born */ @@ -1839,29 +1814,25 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic /* -velocity */ if(part->randfac!=0.0){ - VECADD(r_vel,tloc,pa->r_ve); - Mat4MulVecfl(ob->obmat,r_vel); - VECSUB(r_vel,r_vel,loc); + Mat4Mul3Vecfl(ob->obmat,r_vel); Normalize(r_vel); } /* -angular velocity */ if(part->avemode==PART_AVE_RAND){ - VECADD(r_ave,tloc,pa->r_ave); - Mat4MulVecfl(ob->obmat,r_ave); - VECSUB(r_ave,r_ave,loc); + Mat4Mul3Vecfl(ob->obmat,r_ave); Normalize(r_ave); } /* -rotation */ if(part->randrotfac != 0.0f){ - QUATCOPY(r_rot,pa->r_rot); Mat4ToQuat(ob->obmat,rot); QuatMul(r_rot,r_rot,rot); } } if(part->phystype==PART_PHYS_BOIDS) { + BoidParticle *bpa = pa->boid; float dvec[3], q[4], mat[3][3]; VECCOPY(pa->state.co,loc); @@ -1878,16 +1849,21 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic VECCOPY(pa->state.ave, nor); } /* and gravity in r_ve */ - pa->r_ve[0] = pa->r_ve[1] = 0.0f; - pa->r_ve[2] = -1.0f; + bpa->gravity[0] = bpa->gravity[1] = 0.0f; + bpa->gravity[2] = -1.0f; if(part->acc[2]!=0.0f) - pa->r_ve[2] = part->acc[2]; + bpa->gravity[2] = part->acc[2]; + + //pa->r_ve[0] = pa->r_ve[1] = 0.0f; + //pa->r_ve[2] = -1.0f; + //if(part->acc[2]!=0.0f) + // pa->r_ve[2] = part->acc[2]; /* calculate rotation matrix */ - Projf(dvec, pa->r_ve, pa->state.ave); + Projf(dvec, r_vel, pa->state.ave); VecSubf(mat[0], pa->state.ave, dvec); Normalize(mat[0]); - VECCOPY(mat[2], pa->r_ve); + VECCOPY(mat[2], r_vel); VecMulf(mat[2], -1.0f); Normalize(mat[2]); Crossf(mat[1], mat[2], mat[0]); @@ -1896,10 +1872,10 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic Mat3ToQuat_is_ok(mat, q); QuatCopy(pa->state.rot, q); - pa->boid->health = part->boids->health; - pa->boid->mode = eBoidMode_InAir; - pa->boid->state_id = ((BoidState*)part->boids->states.first)->id; - pa->boid->acc[0]=pa->boid->acc[1]=pa->boid->acc[2]=0.0f; + bpa->data.health = part->boids->health; + bpa->data.mode = eBoidMode_InAir; + bpa->data.state_id = ((BoidState*)part->boids->states.first)->id; + bpa->data.acc[0]=bpa->data.acc[1]=bpa->data.acc[2]=0.0f; } else { /* conversion done so now we apply new: */ @@ -1988,8 +1964,8 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic /* rotation phase */ phasefac = part->phasefac; - if(part->randphasefac != 0.0f) /* abuse r_ave[0] as a random number */ - phasefac += part->randphasefac * pa->r_ave[0]; + if(part->randphasefac != 0.0f) + phasefac += part->randphasefac * r_phase; VecRotToQuat(x_vec, phasefac*(float)M_PI, q_phase); /* combine base rotation & phase */ @@ -2027,8 +2003,7 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic pa->state.time = cfra; - pa->stick_ob = 0; - pa->flag &= ~PARS_STICKY; +// pa->flag &= ~PARS_STICKY; } static void reset_all_particles(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float dtime, float cfra, int from) { @@ -2094,8 +2069,9 @@ static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys) { ParticleSystem *kpsys = psys; ParticleTarget *pt; - ParticleData *pa; - int totpart = psys->totpart, i, k, totkeys = psys->totkeyed; + PARTICLE_P; + ParticleKey *key; + int totpart = psys->totpart, k, totkeys = psys->totkeyed; /* no proper targets so let's clear and bail out */ if(psys->totkeyed==0) { @@ -2107,12 +2083,12 @@ static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys) if(totpart && psys->particles->totkey != totkeys) { free_keyed_keys(psys); - psys->particles->keys = MEM_callocN(totpart*totkeys*sizeof(ParticleKey), "Keyed keys"); - psys->particles->totkey = totkeys; + key = MEM_callocN(totpart*totkeys*sizeof(ParticleKey), "Keyed keys"); - for(i=1, pa=psys->particles+1; ikeys = (pa-1)->keys + totkeys; + LOOP_PARTICLES { + pa->keys = key; pa->totkey = totkeys; + key += totkeys; } } @@ -2126,22 +2102,23 @@ static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys) else kpsys = BLI_findlink(&ob->particlesystem, pt->psys - 1); - for(i=0,pa=psys->particles; ikeys + k)->time = -1.0; /* use current time */ + LOOP_PARTICLES { + key = pa->keys + k; + key->time = -1.0; /* use current time */ - psys_get_particle_state(scene, pt->ob, kpsys, i%kpsys->totpart, pa->keys + k, 1); + psys_get_particle_state(scene, pt->ob, kpsys, p%kpsys->totpart, key, 1); if(psys->flag & PSYS_KEYED_TIMING){ - (pa->keys+k)->time = pa->time + pt->time; + key->time = pa->time + pt->time; if(pt->duration != 0.0f && k+1 < totkeys) { - copy_particle_key(pa->keys+k+1, pa->keys+k, 1); - (pa->keys+k+1)->time = pa->time + pt->time + pt->duration; + copy_particle_key(key+1, key, 1); + (key+1)->time = pa->time + pt->time + pt->duration; } } else if(totkeys > 1) - (pa->keys+k)->time = pa->time + (float)k / (float)(totkeys - 1) * pa->lifetime; + key->time = pa->time + (float)k / (float)(totkeys - 1) * pa->lifetime; else - pa->keys->time = pa->time; + key->time = pa->time; } if(psys->flag & PSYS_KEYED_TIMING && pt->duration!=0.0f) @@ -2296,16 +2273,15 @@ void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra static void update_particle_tree(ParticleSystem *psys) { if(psys) { - ParticleData *pa = psys->particles; - int p, totpart = psys->totpart; + PARTICLE_P; if(!psys->tree || psys->tree_frame != psys->cfra) { BLI_kdtree_free(psys->tree); - psys->tree = BLI_kdtree_new(totpart); + psys->tree = BLI_kdtree_new(psys->totpart); - for(p=0, pa=psys->particles; pflag & (PARS_NO_DISP+PARS_UNEXIST) || pa->alive != PARS_ALIVE) continue; @@ -2548,9 +2524,9 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa ListBase *lb=&psys->effectors; ParticleEffectorCache *ec; ParticleSettings *part=psys->part; - ParticleData *pa; + PARTICLE_P; + int totpart; float vec2[3],loc[3],*co=0; - int p,totpart; for(ec= lb->first; ec; ec= ec->next) { PartDeflect *pd= ec->ob->pd; @@ -2574,7 +2550,7 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa ec->distances=MEM_callocN(totpart*sizeof(float),"particle distances"); ec->locations=MEM_callocN(totpart*3*sizeof(float),"particle locations"); - for(p=0,pa=psys->particles; pfrom == PART_FROM_PARTICLE) { VECCOPY(loc, pa->fuv); } @@ -3253,9 +3229,10 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa /* override for boids */ if(part->phystype == PART_PHYS_BOIDS) { + BoidParticle *bpa = pa->boid; radius = pa->size; boid_z = pa->state.co[2]; - skip_ob = pa->stick_ob; + skip_ob = bpa->ground; } /* 10 iterations to catch multiple deflections */ @@ -3325,12 +3302,7 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa deflections=max_deflections; /* store for reactors */ - copy_particle_key(&reaction_state,&pa->state,0); - - if(part->flag & PART_STICKY){ - pa->stick_ob=ob; - pa->flag |= PARS_STICKY; - } + copy_particle_key(&reaction_state, &pa->state, 0); } else { float nor_vec[3], tan_vec[3], tan_vel[3], vel[3]; @@ -3418,7 +3390,8 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa VECADDFAC(co, co, col.nor, (through ? -0.0001f : 0.0001f)); if(part->phystype == PART_PHYS_BOIDS && part->boids->options & BOID_ALLOW_LAND) { - if(pa->boid->mode == eBoidMode_OnLand || co[2] <= boid_z) { + BoidParticle *bpa = pa->boid; + if(bpa->data.mode == eBoidMode_OnLand || co[2] <= boid_z) { co[2] = boid_z; vel[2] = 0.0f; } @@ -3460,10 +3433,9 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa /* Hair */ /************************************************/ static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra){ - ParticleData *pa; - HairKey *key; + HairKey *key, *root; + PARTICLE_P; int totpart; - int i; Mat4Invert(ob->imat,ob->obmat); @@ -3474,21 +3446,22 @@ static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSy totpart=psys->totpart; /* save new keys for elements if needed */ - for(i=0,pa=psys->particles; itotkey==0 || pa->hair==NULL) { pa->hair = MEM_callocN((psys->part->hair_step + 1) * sizeof(HairKey), "HairKeys"); pa->totkey = 0; } - key = pa->hair + pa->totkey; + key = root = pa->hair; + key += pa->totkey; /* convert from global to geometry space */ VecCopyf(key->co, pa->state.co); Mat4MulVecfl(ob->imat, key->co); if(pa->totkey) { - VECSUB(key->co, key->co, pa->hair->co); + VECSUB(key->co, key->co, root->co); psys_vec_rot_to_face(psmd->dm, pa, key->co); } @@ -3500,7 +3473,7 @@ static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSy /* root is always in the origin of hair space so we set it to be so after the last key is saved*/ if(pa->totkey == psys->part->hair_step + 1) - pa->hair->co[0] = pa->hair->co[1] = pa->hair->co[2] = 0.0f; + root->co[0] = root->co[1] = root->co[2] = 0.0f; } } /************************************************/ @@ -3510,14 +3483,14 @@ static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSy static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra, float *vg_vel, float *vg_tan, float *vg_rot, float *vg_size) { - ParticleData *pa; ParticleSettings *part=psys->part; KDTree *tree=0; IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system Material *ma=give_current_material(ob,part->omat); BoidBrainData bbd; + PARTICLE_P; float timestep; - int p, totpart; + int totpart; /* current time */ float ctime, ipotime; // XXX old animation system /* frame & time changes */ @@ -3546,7 +3519,7 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic if(part->type==PART_REACTOR) vg_size=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_SIZE); - for(p=0, pa=psys->particles; pflag & PARS_UNEXIST) continue; /* set correct ipo timing */ @@ -3615,7 +3588,7 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic } /* main loop: calculate physics for all particles */ - for(p=0, pa=psys->particles; pflag & (PARS_UNEXIST+PARS_NO_DISP)) continue; copy_particle_key(&pa->prev_state,&pa->state,1); @@ -3703,9 +3676,6 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic else{ pa->alive=PARS_DEAD; pa->state.time=pa->dietime; - - if(pa->flag&PARS_STICKY) - psys_key_to_object(pa->stick_ob,&pa->state,0); } } else @@ -3769,12 +3739,13 @@ static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModif static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra) { ParticleSettings *part = psys->part; - ParticleData *pa; - int p; - float disp = (float)get_current_display_percentage(psys)/50.0f-1.0f; + PARTICLE_P; + float disp = (float)get_current_display_percentage(psys)/100.0f; + + BLI_srandom(psys->seed); - for(p=0, pa=psys->particles; ptotpart; p++,pa++){ - if(pa->r_rot[0] > disp) + LOOP_PARTICLES { + if(BLI_frand() > disp) pa->flag |= PARS_NO_DISP; else pa->flag &= ~PARS_NO_DISP; @@ -3798,13 +3769,14 @@ static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra) { ParticleSettings *part=psys->part; - ParticleData *pa; ParticleKey state; IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system Material *ma=give_current_material(ob,part->omat); - int p; + PARTICLE_P; float disp, birthtime, dietime, *vg_size= NULL; // XXX ipotime=cfra + BLI_srandom(psys->seed); + if(part->from!=PART_FROM_PARTICLE) vg_size= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_SIZE); @@ -3817,9 +3789,9 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps precalc_effectors(scene, ob,psys,psmd,cfra); //} - disp= (float)get_current_display_percentage(psys)/50.0f-1.0f; + disp= (float)get_current_display_percentage(psys)/100.0f; - for(p=0, pa=psys->particles; ptotpart; p++,pa++){ + LOOP_PARTICLES { #if 0 // XXX old animation system if((part->flag&PART_ABS_TIME)==0 && part->ipo){ ipotime=100.0f*(cfra-pa->time)/pa->lifetime; @@ -3866,7 +3838,7 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps psys->lattice= NULL; } - if(pa->r_rot[0] > disp) + if(BLI_frand() > disp) pa->flag |= PARS_NO_DISP; else pa->flag &= ~PARS_NO_DISP; @@ -3919,8 +3891,8 @@ static void psys_changed_type(Object *ob, ParticleSystem *psys) else { free_hair(psys, 1); - CLAMP(part->path_start, part->sta, part->end + part->lifetime); - CLAMP(part->path_end, part->sta, part->end + part->lifetime); + CLAMP(part->path_start, 0.0f, MAX2(100.0f, part->end + part->lifetime)); + CLAMP(part->path_end, 0.0f, MAX2(100.0f, part->end + part->lifetime)); } psys->softflag= 0; @@ -3929,23 +3901,25 @@ static void psys_changed_type(Object *ob, ParticleSystem *psys) } void psys_check_boid_data(ParticleSystem *psys) { - ParticleData *pa = psys->particles; - int p = 1; + BoidParticle *bpa; + PARTICLE_P; + + pa = psys->particles; if(!pa) return; if(psys->part && psys->part->phystype==PART_PHYS_BOIDS) { if(!pa->boid) { - pa->boid = MEM_callocN(psys->totpart * sizeof(BoidData), "Boid Data"); + bpa = MEM_callocN(psys->totpart * sizeof(BoidParticle), "Boid Data"); - for(pa++; ptotpart; p++, pa++) - pa->boid = (pa-1)->boid + 1; + LOOP_PARTICLES + pa->boid = bpa++; } } else if(pa->boid){ MEM_freeN(pa->boid); - for(; ptotpart; p++, pa++) + LOOP_PARTICLES pa->boid = NULL; } } @@ -4093,10 +4067,10 @@ static void particles_fluid_step(Scene *scene, Object *ob, ParticleSystem *psys, static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra) { ParticleSettings *part; - ParticleData *pa; PointCache *cache; PTCacheID pid; - int totpart, oldtotpart, totchild, oldtotchild, p; + PARTICLE_P; + int totpart, oldtotpart, totchild, oldtotchild; float disp, *vg_vel= 0, *vg_tan= 0, *vg_rot= 0, *vg_size= 0; int init= 0, distr= 0, alloc= 0, usecache= 0, only_children_changed= 0; int framenr, framedelta, startframe, endframe; @@ -4239,7 +4213,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle } else if(result==PTCACHE_READ_OLD) { psys->cfra = (float)cache->simframe; - for(p=0, pa=psys->particles; ptime > psys->cfra) pa->alive = PARS_UNBORN; @@ -4278,10 +4252,11 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle } /* set particles to be not calculated TODO: can't work with pointcache */ - disp= (float)get_current_display_percentage(psys)/50.0f-1.0f; + disp= (float)get_current_display_percentage(psys)/100.0f; - for(p=0, pa=psys->particles; pr_rot[0] > disp) + BLI_srandom(psys->seed); + LOOP_PARTICLES { + if(BLI_frand() > disp) pa->flag |= PARS_NO_DISP; else pa->flag &= ~PARS_NO_DISP; diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 7a156f56d72..3e429749953 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -181,6 +181,7 @@ static int ptcache_write_particle(int index, void *psys_v, void **data) { ParticleSystem *psys= psys_v; ParticleData *pa = psys->particles + index; + BoidParticle *boid = (psys->part->phystype == PART_PHYS_BOIDS) ? pa->boid : NULL; float times[3] = {pa->time, pa->dietime, pa->lifetime}; if(data[BPHYS_DATA_INDEX]) { @@ -198,8 +199,8 @@ static int ptcache_write_particle(int index, void *psys_v, void **data) ptcache_data_from(data, BPHYS_DATA_SIZE, &pa->size); ptcache_data_from(data, BPHYS_DATA_TIMES, times); - if(pa->boid) - ptcache_data_from(data, BPHYS_DATA_TIMES, &pa->boid); + if(boid) + ptcache_data_from(data, BPHYS_DATA_BOIDS, &boid->data); return 1; } @@ -215,6 +216,7 @@ static void ptcache_read_particle(int index, void *psys_v, void **data, float fr { ParticleSystem *psys= psys_v; ParticleData *pa = psys->particles + index; + BoidParticle *boid = (psys->part->phystype == PART_PHYS_BOIDS) ? pa->boid : NULL; if(cfra > pa->state.time) memcpy(&pa->prev_state, &pa->state, sizeof(ParticleKey)); @@ -238,8 +240,8 @@ static void ptcache_read_particle(int index, void *psys_v, void **data, float fr pa->lifetime = times[2]; } - if(pa->boid) - ptcache_data_to(data, BPHYS_DATA_BOIDS, 0, &pa->boid); + if(boid) + ptcache_data_to(data, BPHYS_DATA_BOIDS, 0, &boid->data); /* determine velocity from previous location */ if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_VELOCITY]) { diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 40a28251495..fdbfe154fae 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -3623,9 +3623,9 @@ static void particles_to_softbody(Scene *scene, Object *ob) /* find first BodyPoint index for each particle */ if(psys->totpart > 0) { - psys->particles->bpi = 0; - for(a=1, pa=psys->particles+1; atotpart; a++, pa++) - pa->bpi = (pa-1)->bpi + (pa-1)->totkey; +// psys->particles->bpi = 0; +// for(a=1, pa=psys->particles+1; atotpart; a++, pa++) +// pa->bpi = (pa-1)->bpi + (pa-1)->totkey; } /* we always make body points */ @@ -4079,7 +4079,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i if(framenr < startframe) { cache->flag &= ~PTCACHE_SIMULATION_VALID; cache->simframe= 0; - cache->last_exact= 0; + //cache->last_exact= 0; return; } @@ -4141,20 +4141,29 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i pa= sb->particles->particles; } + if(framenr == startframe && cache->flag & PTCACHE_REDO_NEEDED) { + BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); + cache->simframe= framenr; + cache->flag &= ~PTCACHE_REDO_NEEDED; + return; + } + /* try to read from cache */ cache_result = BKE_ptcache_read_cache(&pid, framenr, scene->r.frs_sec); if(cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) { - cache->flag |= PTCACHE_SIMULATION_VALID; - cache->simframe= framenr; - if(sb->particles==0) softbody_to_object(ob, vertexCos, numVerts, sb->local); + cache->simframe= framenr; + cache->flag |= PTCACHE_SIMULATION_VALID; + + if(cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED) + BKE_ptcache_write_cache(&pid, framenr); + return; } else if(cache_result==PTCACHE_READ_OLD) { - BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_FREE); cache->flag |= PTCACHE_SIMULATION_VALID; } else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) { @@ -4166,16 +4175,11 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i } if(framenr == startframe) { - if(cache->flag & PTCACHE_REDO_NEEDED) { - softbody_update_positions(ob, sb, vertexCos, numVerts); - softbody_reset(ob, sb, vertexCos, numVerts); - cache->flag &= ~PTCACHE_REDO_NEEDED; - } /* first frame, no simulation to do, just set the positions */ softbody_update_positions(ob, sb, vertexCos, numVerts); - cache->flag |= PTCACHE_SIMULATION_VALID; cache->simframe= framenr; + cache->flag |= PTCACHE_SIMULATION_VALID; /* don't write cache on first frame, but on second frame write * cache for frame 1 and 2 */ @@ -4187,10 +4191,6 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i softbody_update_positions(ob, sb, vertexCos, numVerts); - /* do simulation */ - cache->flag |= PTCACHE_SIMULATION_VALID; - cache->simframe= framenr; - /* checking time: */ dtime = framedelta*timescale; @@ -4199,6 +4199,10 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i if(sb->particles==0) softbody_to_object(ob, vertexCos, numVerts, 0); + /* do simulation */ + cache->simframe= framenr; + cache->flag |= PTCACHE_SIMULATION_VALID; + BKE_ptcache_write_cache(&pid, framenr); } } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 5a628192af6..6a26a71ee3d 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3055,11 +3055,8 @@ static void direct_link_particlesettings(FileData *fd, ParticleSettings *part) static void lib_link_particlesystems(FileData *fd, Object *ob, ID *id, ListBase *particles) { ParticleSystem *psys, *psysnext; - int a; for(psys=particles->first; psys; psys=psysnext){ - ParticleData *pa; - psysnext= psys->next; psys->part = newlibadr_us(fd, id->lib, psys->part); @@ -3070,12 +3067,6 @@ static void lib_link_particlesystems(FileData *fd, Object *ob, ID *id, ListBase pt->ob=newlibadr(fd, id->lib, pt->ob); psys->target_ob = newlibadr(fd, id->lib, psys->target_ob); - - for(a=0,pa=psys->particles; atotpart; a++,pa++){ - pa->stick_ob=newlibadr(fd, id->lib, pa->stick_ob); - } - - } else { /* particle modifier must be removed before particle system */ diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 88c6f205d15..c4a94660932 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -653,7 +653,7 @@ static void write_particlesystems(WriteData *wd, ListBase *particles) } if(psys->particles->boid && psys->part->phystype == PART_PHYS_BOIDS) - writestruct(wd, DATA, "BoidData", psys->totpart, psys->particles->boid); + writestruct(wd, DATA, "BoidParticle", psys->totpart, psys->particles->boid); } pt = psys->targets.first; for(; pt; pt=pt->next) diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 0ae987f2308..a5d365cafd4 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -102,6 +102,7 @@ #include "BKE_object.h" #include "BKE_paint.h" #include "BKE_particle.h" +#include "BKE_pointcache.h" #include "BKE_property.h" #include "BKE_report.h" #include "BKE_sca.h" @@ -3883,6 +3884,8 @@ void ED_object_exit_editmode(bContext *C, int flag) /* for example; displist make is different in editmode */ scene->obedit= NULL; // XXX for context + BKE_ptcache_object_reset(scene, obedit, PTCACHE_RESET_DEPSGRAPH); + /* also flush ob recalc, doesn't take much overhead, but used for particles */ DAG_id_flush_update(&obedit->id, OB_RECALC_OB|OB_RECALC_DATA); diff --git a/source/blender/editors/physics/ed_pointcache.c b/source/blender/editors/physics/ed_pointcache.c index 22316290c7b..f2c7b64032f 100644 --- a/source/blender/editors/physics/ed_pointcache.c +++ b/source/blender/editors/physics/ed_pointcache.c @@ -226,7 +226,7 @@ void PTCACHE_OT_bake(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - RNA_def_boolean(ot->srna, "bake", 1, "Bake", ""); + RNA_def_boolean(ot->srna, "bake", 0, "Bake", ""); } void PTCACHE_OT_free_bake(wmOperatorType *ot) { diff --git a/source/blender/editors/physics/editparticle.c b/source/blender/editors/physics/editparticle.c index 3ddc143b5a3..bc48d8f4f55 100644 --- a/source/blender/editors/physics/editparticle.c +++ b/source/blender/editors/physics/editparticle.c @@ -102,8 +102,6 @@ static void PTCacheUndo_clear(PTCacheEdit *edit); #define LOOP_SELECTED_KEYS for(k=0, key=point->keys; ktotkey; k++, key++) if((key->flag & PEK_SELECT) && !(key->flag & PEK_HIDE)) #define LOOP_TAGGED_KEYS for(k=0, key=point->keys; ktotkey; k++, key++) if(key->flag & PEK_TAG) -#define LOOP_PARTICLES(i, pa) for(i=0, pa=psys->particles; itotpart; i++, pa++) - #define KEY_WCO (key->flag & PEK_USE_WCO ? key->world_co : key->co) /**************************** utilities *******************************/ @@ -642,12 +640,13 @@ static int count_selected_keys(Scene *scene, PTCacheEdit *edit) static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) { PTCacheEdit *edit; - ParticleData *pa; ParticleSystemModifierData *psmd; KDTree *tree; KDTreeNearest nearest; + HairKey *key; + PARTICLE_P; float mat[4][4], co[3]; - int i, index, totpart; + int index, totpart; edit= psys->edit; psmd= psys_get_modifier(ob, psys); @@ -656,11 +655,12 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) tree= BLI_kdtree_new(totpart); /* insert particles into kd tree */ - LOOP_PARTICLES(i, pa) { + LOOP_PARTICLES { + key = pa->hair; psys_mat_hair_to_orco(ob, psmd->dm, psys->part->from, pa, mat); - VECCOPY(co, pa->hair[0].co); + VECCOPY(co, key->co); Mat4MulVecfl(mat, co); - BLI_kdtree_insert(tree, i, co, NULL); + BLI_kdtree_insert(tree, p, co, NULL); } BLI_kdtree_balance(tree); @@ -669,27 +669,28 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) if(!edit->mirror_cache) edit->mirror_cache= MEM_callocN(sizeof(int)*totpart, "PE mirror cache"); - LOOP_PARTICLES(i, pa) { + LOOP_PARTICLES { + key = pa->hair; psys_mat_hair_to_orco(ob, psmd->dm, psys->part->from, pa, mat); - VECCOPY(co, pa->hair[0].co); + VECCOPY(co, key->co); Mat4MulVecfl(mat, co); co[0]= -co[0]; index= BLI_kdtree_find_nearest(tree, co, NULL, &nearest); /* this needs a custom threshold still, duplicated for editmode mirror */ - if(index != -1 && index != i && (nearest.dist <= 0.0002f)) - edit->mirror_cache[i]= index; + if(index != -1 && index != p && (nearest.dist <= 0.0002f)) + edit->mirror_cache[p]= index; else - edit->mirror_cache[i]= -1; + edit->mirror_cache[p]= -1; } /* make sure mirrors are in two directions */ - LOOP_PARTICLES(i, pa) { - if(edit->mirror_cache[i]) { - index= edit->mirror_cache[i]; - if(edit->mirror_cache[index] != i) - edit->mirror_cache[i]= -1; + LOOP_PARTICLES { + if(edit->mirror_cache[p]) { + index= edit->mirror_cache[p]; + if(edit->mirror_cache[index] != p) + edit->mirror_cache[p]= -1; } } @@ -1735,7 +1736,7 @@ static void rekey_particle(PEData *data, int pa_index) ParticleData *pa= psys->particles + pa_index; PTCacheEditPoint *point = edit->points + pa_index; ParticleKey state; - HairKey *key, *new_keys; + HairKey *key, *new_keys, *okey; PTCacheEditKey *ekey; float dval, sta, end; int k; @@ -1744,12 +1745,13 @@ static void rekey_particle(PEData *data, int pa_index) key= new_keys= MEM_callocN(data->totrekey * sizeof(HairKey),"Hair re-key keys"); + okey = pa->hair; /* root and tip stay the same */ - VECCOPY(key->co, pa->hair->co); - VECCOPY((key + data->totrekey - 1)->co, (pa->hair + pa->totkey - 1)->co); + VECCOPY(key->co, okey->co); + VECCOPY((key + data->totrekey - 1)->co, (okey + pa->totkey - 1)->co); - sta= key->time= pa->hair->time; - end= (key + data->totrekey - 1)->time= (pa->hair + pa->totkey - 1)->time; + sta= key->time= okey->time; + end= (key + data->totrekey - 1)->time= (okey + pa->totkey - 1)->time; dval= (end - sta) / (float)(data->totrekey - 1); /* interpolate new keys from old ones */ @@ -2034,9 +2036,11 @@ static void subdivide_particle(PEData *data, int pa_index) nkey= new_keys= MEM_callocN((pa->totkey+totnewkey)*(sizeof(HairKey)),"Hair subdivide keys"); nekey= new_ekeys= MEM_callocN((pa->totkey+totnewkey)*(sizeof(PTCacheEditKey)),"Hair subdivide edit keys"); - endtime= pa->hair[pa->totkey-1].time; + + key = pa->hair; + endtime= key[pa->totkey-1].time; - for(k=0, key=pa->hair, ekey=point->keys; ktotkey-1; k++, key++, ekey++) { + for(k=0, ekey=point->keys; ktotkey-1; k++, key++, ekey++) { memcpy(nkey,key,sizeof(HairKey)); memcpy(nekey,ekey,sizeof(PTCacheEditKey)); @@ -2461,7 +2465,6 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) *newpa= *pa; *newpoint= *point; if(pa->hair) newpa->hair= MEM_dupallocN(pa->hair); - if(pa->keys) newpa->keys= MEM_dupallocN(pa->keys); if(point->keys) newpoint->keys= MEM_dupallocN(point->keys); /* rotate weights according to vertex index rotation */ @@ -2966,7 +2969,7 @@ static void brush_add(PEData *data, short number) weight[w] /= totw; for(k=0; ktotaddkey; k++) { - hkey= pa->hair + k; + hkey= (HairKey*)pa->hair + k; hkey->time= pa->time + k * framestep; key[0].time= hkey->time/ 100.0f; @@ -2990,15 +2993,15 @@ static void brush_add(PEData *data, short number) if(k==0) VECSUB(co1, pa->state.co, key[0].co); - VECADD(pa->hair[k].co, key[0].co, co1); + VECADD(hkey->co, key[0].co, co1); - pa->hair[k].time= key[0].time; + hkey->time= key[0].time; } } else { for(k=0, hkey=pa->hair; ktotaddkey; k++, hkey++) { VECADDFAC(hkey->co, pa->state.co, pa->state.vel, k * framestep * timestep); - pa->hair[k].time += k * framestep; + hkey->time += k * framestep; } } for(k=0, hkey=pa->hair; ktotaddkey; k++, hkey++) { diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index e49616fc740..25ff1244254 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -3373,8 +3373,9 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv pa_birthtime=pa->time; pa_dietime = pa->dietime; pa_size=pa->size; - if(part->phystype==PART_PHYS_BOIDS) - pa_health = pa->boid->health; + if(part->phystype==PART_PHYS_BOIDS) { + pa_health = pa->boid->data.health; + } else pa_health = -1.0; @@ -3409,8 +3410,10 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv } #endif // XXX old animation system - r_tilt = 1.0f + pa->r_ave[0]; - r_length = 0.5f * (1.0f + pa->r_ave[1]); + BLI_srandom(psys->seed+a); + + r_tilt = 2.0f*(BLI_frand() - 0.5f); + r_length = BLI_frand(); } else{ ChildParticle *cpa= &psys->child[a-totpart]; diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 12c253a7cb8..d4dc3df0965 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -33,6 +33,7 @@ #define DNA_PARTICLE_TYPES_H #include "DNA_ID.h" +#include "DNA_boid_types.h" struct AnimData; @@ -52,6 +53,14 @@ typedef struct ParticleKey { /* when changed update size of struct to copy_parti float time; /* when this key happens */ } ParticleKey; +typedef struct BoidParticle { + struct Object *ground; + struct BoidData data; + float gravity[3]; + float wander[3]; + float rt; +} BoidParticle; + /* Child particles are created around or between parent particles */ typedef struct ChildParticle { int num, parent; /* num is face index on the final derived mesh */ @@ -69,42 +78,34 @@ typedef struct ParticleTarget { float time, duration; } ParticleTarget; -/* Everything that's non dynamic for a particle: */ typedef struct ParticleData { - struct Object *stick_ob;/* object that particle sticks to when dead */ - - ParticleKey state; /* normally current global coordinates or */ - /* in sticky object space if dead & sticky */ + ParticleKey state; /* current global coordinates */ ParticleKey prev_state; /* previous state */ - + HairKey *hair; /* hair vertices */ - ParticleKey *keys; /* keyed states */ + ParticleKey *keys; /* keyed keys */ - struct BoidData *boid; /* boids data */ + BoidParticle *boid; /* boids data */ - float r_rot[4]; /* random values */ - float r_ave[3],r_ve[3]; - - float fuv[4], foffset; /* coordinates on face/edge number "num" and depth along*/ - /* face normal for volume emission */ + int totkey; /* amount of hair or keyed keys*/ float time, lifetime; /* dietime is not nescessarily time+lifetime as */ float dietime; /* particles can die unnaturally (collision) */ - float size, sizemul; /* size and multiplier so that we can update size when ever */ - int num; /* index to vert/edge/face */ int num_dmcache; /* index to derived mesh data (face) to avoid slow lookups */ - int totkey; - int bpi; /* softbody body point start index */ + float fuv[4], foffset; /* coordinates on face/edge number "num" and depth along*/ + /* face normal for volume emission */ + + float size; /* size and multiplier so that we can update size when ever */ short flag; - short alive; /* the life state of a particle */ + short alive; /* the life state of a particle */ short loop; /* how many times particle life has looped */ - short rt2; + short rt; } ParticleData; typedef struct ParticleSettings { @@ -258,7 +259,7 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in #define PART_TRAND 128 #define PART_EDISTR 256 /* particle/face from face areas */ -#define PART_STICKY 512 /*collided particles can stick to collider*/ +//#define PART_STICKY 512 /*collided particles can stick to collider*/ #define PART_DIE_ON_COL (1<<12) #define PART_SIZE_DEFL (1<<13) /* swept sphere deflections */ #define PART_ROT_DYN (1<<14) /* dynamic rotation */ @@ -409,7 +410,7 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in /* psys->flag */ #define PSYS_CURRENT 1 -//#define PSYS_BAKING 2 +#define PSYS_GLOBAL_HAIR 2 //#define PSYS_BAKE_UI 4 #define PSYS_KEYED_TIMING 8 #define PSYS_ENABLED 16 /* deprecated */ @@ -426,7 +427,7 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in /* pars->flag */ #define PARS_UNEXIST 1 #define PARS_NO_DISP 2 -#define PARS_STICKY 4 +//#define PARS_STICKY 4 #define PARS_REKEY 8 /* pars->alive */ diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 2525209c3be..4a23605c717 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -643,12 +643,6 @@ static void rna_def_particle(BlenderRNA *brna) RNA_def_struct_sdna(srna, "ParticleData"); RNA_def_struct_ui_text(srna, "Particle", "Particle in a particle system."); - prop= RNA_def_property(srna, "stick_object", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "stick_ob"); - RNA_def_property_struct_type(prop, "Object"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Stick Object", "Object that particle sticks to when dead"); - /* Particle State & Previous State */ prop= RNA_def_property(srna, "location", PROP_FLOAT, PROP_TRANSLATION); RNA_def_property_float_sdna(prop, NULL, "state.co"); @@ -693,24 +687,6 @@ static void rna_def_particle(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "keys", "totkey"); RNA_def_property_struct_type(prop, "ParticleKey"); RNA_def_property_ui_text(prop, "Keyed States", ""); - - /* Random variables */ - - prop= RNA_def_property(srna, "random_rotation", PROP_FLOAT, PROP_QUATERNION); - RNA_def_property_float_sdna(prop, NULL, "r_rot"); -// RNA_def_property_range(prop, lowerLimitf, upperLimitf); - RNA_def_property_ui_text(prop, "Random Rotation", ""); - - prop= RNA_def_property(srna, "random_a_velocity", PROP_FLOAT, PROP_VELOCITY); - RNA_def_property_float_sdna(prop, NULL, "r_ave"); -// RNA_def_property_range(prop, lowerLimitf, upperLimitf); - RNA_def_property_ui_text(prop, "Random Angular Velocity", ""); - - prop= RNA_def_property(srna, "random_velocity", PROP_FLOAT, PROP_VELOCITY); - RNA_def_property_float_sdna(prop, NULL, "r_ve"); -// RNA_def_property_range(prop, lowerLimitf, upperLimitf); - RNA_def_property_ui_text(prop, "Random Velocity", ""); - // // float fuv[4], foffset; /* coordinates on face/edge number "num" and depth along*/ // /* face normal for volume emission */ @@ -733,18 +709,12 @@ static void rna_def_particle(BlenderRNA *brna) // RNA_def_property_range(prop, lowerLimitf, upperLimitf); RNA_def_property_ui_text(prop, "Size", ""); - prop= RNA_def_property(srna, "size_multiplier", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "sizemul"); -// RNA_def_property_range(prop, lowerLimitf, upperLimitf); - RNA_def_property_ui_text(prop, "Size Multiplier", ""); - // // int num; /* index to vert/edge/face */ // int num_dmcache; /* index to derived mesh data (face) to avoid slow lookups */ // int pad; // // int totkey; -// int bpi; /* softbody body point start index */ /* flag */ prop= RNA_def_property(srna, "unexist", PROP_BOOLEAN, PROP_NONE); @@ -755,10 +725,6 @@ static void rna_def_particle(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", PARS_NO_DISP); RNA_def_property_ui_text(prop, "no_disp", ""); - prop= RNA_def_property(srna, "sticky", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", PARS_STICKY); - RNA_def_property_ui_text(prop, "sticky", ""); - prop= RNA_def_property(srna, "rekey", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PARS_REKEY); RNA_def_property_ui_text(prop, "rekey", ""); @@ -942,13 +908,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); RNA_def_property_ui_text(prop, "Even Distribution", "Use even distribution from faces based on face areas or edge lengths."); RNA_def_property_update(prop, 0, "rna_Particle_reset"); - - prop= RNA_def_property(srna, "sticky", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_STICKY); - RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); - RNA_def_property_ui_text(prop, "Sticky", "Particles stick to collided objects if they die in the collision."); - RNA_def_property_update(prop, 0, "rna_Particle_reset"); - + prop= RNA_def_property(srna, "die_on_collision", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_DIE_ON_COL); RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE); diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index cf6246e3641..df99d5f2843 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -1743,8 +1743,10 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem pa_size = pa->size; - r_tilt = 1.0f + pa->r_ave[0]; - r_length = 0.5f * (1.0f + pa->r_ave[1]); + BLI_srandom(psys->seed+a); + + r_tilt = 2.0f*(BLI_frand() - 0.5f); + r_length = BLI_frand(); if(path_nbr) { cache = psys->pathcache[a]; -- cgit v1.2.3