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.
This commit is contained in:
@@ -396,7 +396,6 @@ class PARTICLE_PT_physics(ParticleButtonsPanel):
|
||||
if part.physics_type=='NEWTON':
|
||||
sub.itemR(part, "size_deflect")
|
||||
sub.itemR(part, "die_on_collision")
|
||||
sub.itemR(part, "sticky")
|
||||
elif part.physics_type=='KEYED' or part.physics_type=='BOIDS':
|
||||
if part.physics_type=='BOIDS':
|
||||
layout.itemL(text="Relations:")
|
||||
|
||||
@@ -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; p<psys->totpart; 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);
|
||||
|
||||
|
||||
@@ -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; n<neighbors; n++)
|
||||
health += bbd->psys->particles[ptn[n].index].boid->health;
|
||||
for(n=0; n<neighbors; n++) {
|
||||
bpa = bbd->psys->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; n<neighbors; n++) {
|
||||
health += epars[ptn[n].index].boid->health;
|
||||
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]);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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; p<tpsys->totpart; 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; a<psysn->totpart; 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; p<psysn->totpart; 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; p<psysn->totpart; 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; a<psysn->totpart; 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;
|
||||
|
||||
@@ -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; p<psys->totpart; 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; p<psys->totpart; 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; i<totpart; i++, pa++)
|
||||
LOOP_PARTICLES
|
||||
totkey += pa->totkey;
|
||||
|
||||
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;
|
||||
|
||||
for(i=0, pa=psys->particles; i<totpart; i++, pa++) {
|
||||
if(psys->part->type != PART_HAIR)
|
||||
return;
|
||||
|
||||
LOOP_PARTICLES {
|
||||
if(pa->hair)
|
||||
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; i<psys->totpart; 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(p<totpart){
|
||||
pa = psys->particles + 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);
|
||||
}
|
||||
|
||||
@@ -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; i<psys->totpart; 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(; p<psys->totpart; 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->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->boid)
|
||||
MEM_freeN(psys->particles->boid);
|
||||
|
||||
for(i=0, pa=newpars; i<totsaved; i++, pa++) {
|
||||
if(pa->keys) {
|
||||
pa->keys= NULL;
|
||||
pa->totkey= 0;
|
||||
if(psys->particles->boid)
|
||||
memcpy(newboids, psys->particles->boid, totsaved*sizeof(BoidParticle));
|
||||
}
|
||||
|
||||
if(psys->particles->keys)
|
||||
MEM_freeN(psys->particles->keys);
|
||||
|
||||
if(psys->particles->boid)
|
||||
MEM_freeN(psys->particles->boid);
|
||||
|
||||
for(p=0, pa=newpars; p<totsaved; p++, pa++) {
|
||||
if(pa->keys) {
|
||||
pa->keys= NULL;
|
||||
pa->totkey= 0;
|
||||
}
|
||||
}
|
||||
|
||||
for(p=totsaved, pa=psys->particles+totsaved; p<psys->totpart; p++, pa++)
|
||||
if(pa->hair) MEM_freeN(pa->hair);
|
||||
|
||||
MEM_freeN(psys->particles);
|
||||
}
|
||||
|
||||
psys->particles=newpars;
|
||||
|
||||
for(i=totsaved, pa=psys->particles+totsaved; i<psys->totpart; i++, pa++)
|
||||
if(pa->hair) MEM_freeN(pa->hair);
|
||||
|
||||
MEM_freeN(psys->particles);
|
||||
}
|
||||
psys->particles=newpars;
|
||||
|
||||
if(newboids) {
|
||||
pa = psys->particles;
|
||||
pa->boid = newboids;
|
||||
for(i=1, pa++; i<totpart; i++,pa++)
|
||||
pa->boid = (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; p<psys->totpart; 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; p<psys->totpart; 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; p<totpart; p++,pa++){
|
||||
LOOP_PARTICLES {
|
||||
pa->fuv[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; p<totpart; p++,pa++){
|
||||
LOOP_PARTICLES {
|
||||
pa->fuv[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; p<totpart; p++, pa++)
|
||||
LOOP_PARTICLES
|
||||
initialize_particle(pa,p,ob,psys,psmd);
|
||||
|
||||
if(psys->part->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; i<totpart; i++,pa++){
|
||||
pa->keys = (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; i<totpart; i++, pa++) {
|
||||
(pa->keys + 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; p<totpart; p++,pa++){
|
||||
LOOP_PARTICLES {
|
||||
if(pa->flag & (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; p<totpart; p++, pa++){
|
||||
LOOP_PARTICLES {
|
||||
if(part->from == 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; i<totpart; i++,pa++) {
|
||||
LOOP_PARTICLES {
|
||||
/* first time alloc */
|
||||
if(pa->totkey==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; p<totpart; p++,pa++){
|
||||
LOOP_PARTICLES {
|
||||
if(pa->flag & 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; p<totpart; p++,pa++){
|
||||
LOOP_PARTICLES {
|
||||
if(pa->flag & (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;
|
||||
|
||||
for(p=0, pa=psys->particles; p<psys->totpart; p++,pa++){
|
||||
if(pa->r_rot[0] > disp)
|
||||
BLI_srandom(psys->seed);
|
||||
|
||||
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; p<psys->totpart; 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++; p<psys->totpart; p++, pa++)
|
||||
pa->boid = (pa-1)->boid + 1;
|
||||
LOOP_PARTICLES
|
||||
pa->boid = bpa++;
|
||||
}
|
||||
}
|
||||
else if(pa->boid){
|
||||
MEM_freeN(pa->boid);
|
||||
for(; p<psys->totpart; 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; p<totpart; p++, pa++) {
|
||||
LOOP_PARTICLES {
|
||||
/* update alive status */
|
||||
if(pa->time > 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; p<totpart; p++,pa++){
|
||||
if(pa->r_rot[0] > disp)
|
||||
BLI_srandom(psys->seed);
|
||||
LOOP_PARTICLES {
|
||||
if(BLI_frand() > disp)
|
||||
pa->flag |= PARS_NO_DISP;
|
||||
else
|
||||
pa->flag &= ~PARS_NO_DISP;
|
||||
|
||||
@@ -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]) {
|
||||
|
||||
@@ -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; a<psys->totpart; a++, pa++)
|
||||
pa->bpi = (pa-1)->bpi + (pa-1)->totkey;
|
||||
// psys->particles->bpi = 0;
|
||||
// for(a=1, pa=psys->particles+1; a<psys->totpart; 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; a<psys->totpart; a++,pa++){
|
||||
pa->stick_ob=newlibadr(fd, id->lib, pa->stick_ob);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
/* particle modifier must be removed before particle system */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -102,8 +102,6 @@ static void PTCacheUndo_clear(PTCacheEdit *edit);
|
||||
#define LOOP_SELECTED_KEYS for(k=0, key=point->keys; k<point->totkey; k++, key++) if((key->flag & PEK_SELECT) && !(key->flag & PEK_HIDE))
|
||||
#define LOOP_TAGGED_KEYS for(k=0, key=point->keys; k<point->totkey; k++, key++) if(key->flag & PEK_TAG)
|
||||
|
||||
#define LOOP_PARTICLES(i, pa) for(i=0, pa=psys->particles; i<psys->totpart; 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; k<pa->totkey-1; k++, key++, ekey++) {
|
||||
for(k=0, ekey=point->keys; k<pa->totkey-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; k<pset->totaddkey; 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; k<pset->totaddkey; 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; k<pset->totaddkey; k++, hkey++) {
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
Reference in New Issue
Block a user