Particles cleanup, optimizations and some small new stuff.
New stuff - Bending springs for hair dynamics. Code cleanup & optimization - Disabled reactor particles temporarily for cleanup, it's a clumsy system that will be replaced with something better. - Removed child seams, something better will come here too :) - Normal particle drawing data is now saved between redraws if the particles don't move between redraws. * For example rotating the 3d view is now realtime even with 1M particles. - Many random values for particles now come from a lookup table making things much faster. - Most accessed small point cache functions are now much faster as macros. - Lot's of general code cleanup. - Nothing big should have changed so if something doesn't work like it used to it's probably just a typo somewhere :)
This commit is contained in:
@@ -255,6 +255,7 @@ class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel):
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(cloth, "pin_stiffness", text="Stiffness")
|
||||
sub.itemR(cloth, "mass")
|
||||
sub.itemR(cloth, "bending_stiffness", text="Bending")
|
||||
col.itemL(text="Damping:")
|
||||
sub = col.column(align=True)
|
||||
sub.itemR(cloth, "spring_damping", text="Spring")
|
||||
|
||||
@@ -35,9 +35,7 @@
|
||||
#include "DNA_boid_types.h"
|
||||
|
||||
typedef struct BoidBrainData {
|
||||
Scene *scene;
|
||||
struct Object *ob;
|
||||
struct ParticleSystem *psys;
|
||||
struct ParticleSimulationData *sim;
|
||||
struct ParticleSettings *part;
|
||||
float timestep, cfra, dfra;
|
||||
float wanted_co[3], wanted_speed;
|
||||
|
||||
@@ -61,6 +61,23 @@ struct BVHTreeRayHit;
|
||||
|
||||
#define PARTICLE_P ParticleData *pa; int p
|
||||
#define LOOP_PARTICLES for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++)
|
||||
#define LOOP_EXISTING_PARTICLES for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++) if(!(pa->flag & PARS_UNEXIST))
|
||||
#define LOOP_SHOWN_PARTICLES for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++) if(!(pa->flag & (PARS_UNEXIST|PARS_NO_DISP)))
|
||||
|
||||
#define PSYS_FRAND_COUNT 1024
|
||||
#define PSYS_FRAND(seed) psys->frand[(seed) % PSYS_FRAND_COUNT]
|
||||
|
||||
/* fast but sure way to get the modifier*/
|
||||
#define PARTICLE_PSMD ParticleSystemModifierData *psmd = sim->psmd ? sim->psmd : psys_get_modifier(sim->ob, sim->psys)
|
||||
|
||||
/* common stuff that many particle functions need */
|
||||
typedef struct ParticleSimulationData {
|
||||
struct Scene *scene;
|
||||
struct Object *ob;
|
||||
struct ParticleSystem *psys;
|
||||
struct ParticleSystemModifierData *psmd;
|
||||
float timestep;
|
||||
} ParticleSimulationData;
|
||||
|
||||
typedef struct ParticleEffectorCache {
|
||||
struct ParticleEffectorCache *next, *prev;
|
||||
@@ -118,11 +135,8 @@ typedef struct ParticleCacheKey{
|
||||
|
||||
typedef struct ParticleThreadContext {
|
||||
/* shared */
|
||||
struct Scene *scene;
|
||||
struct Object *ob;
|
||||
struct ParticleSimulationData sim;
|
||||
struct DerivedMesh *dm;
|
||||
struct ParticleSystemModifierData *psmd;
|
||||
struct ParticleSystem *psys;
|
||||
struct Material *ma;
|
||||
|
||||
/* distribution */
|
||||
@@ -166,8 +180,7 @@ typedef struct ParticleBillboardData
|
||||
int lock, num;
|
||||
int totnum;
|
||||
short align, uv_split, anim, split_offset;
|
||||
}
|
||||
ParticleBillboardData;
|
||||
} ParticleBillboardData;
|
||||
|
||||
/* container for moving data between deflet_particle and particle_intersect_face */
|
||||
typedef struct ParticleCollision
|
||||
@@ -179,40 +192,40 @@ typedef struct ParticleCollision
|
||||
float co1[3], co2[3]; // ray start and end points
|
||||
float ray_len; // original length of co2-co1, needed for collision time evaluation
|
||||
float t; // time of previous collision, needed for substracting face velocity
|
||||
}
|
||||
ParticleCollision;
|
||||
} ParticleCollision;
|
||||
|
||||
typedef struct ParticleDrawData {
|
||||
float *vdata, *vd; /* vertice data */
|
||||
float *ndata, *nd; /* normal data */
|
||||
float *cdata, *cd; /* color data */
|
||||
float *vedata, *ved; /* velocity data */
|
||||
float *ma_r, *ma_g, *ma_b;
|
||||
int tot_vec_size, flag;
|
||||
int totpoint, totve;
|
||||
} ParticleDrawData;
|
||||
|
||||
#define PARTICLE_DRAW_DATA_UPDATED 1
|
||||
|
||||
/* ----------- functions needed outside particlesystem ---------------- */
|
||||
/* particle.c */
|
||||
int count_particles(struct ParticleSystem *psys);
|
||||
int count_particles_mod(struct ParticleSystem *psys, int totgr, int cur);
|
||||
int psys_count_keys(struct ParticleSystem *psys);
|
||||
char *psys_menu_string(struct Object *ob, int for_sb);
|
||||
|
||||
struct ParticleSystem *psys_get_current(struct Object *ob);
|
||||
/* for rna */
|
||||
short psys_get_current_num(struct Object *ob);
|
||||
void psys_set_current_num(Object *ob, int index);
|
||||
struct Object *psys_find_object(struct Scene *scene, struct ParticleSystem *psys);
|
||||
//struct ParticleSystem *psys_get(struct Object *ob, int index);
|
||||
struct ParticleData *psys_get_selected_particle(struct ParticleSystem *psys, int *index);
|
||||
struct ParticleKey *psys_get_selected_key(struct ParticleSystem *psys, int pa_index, int *key_index);
|
||||
void psys_change_act(void *ob_v, void *act_v);
|
||||
struct Object *psys_get_lattice(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys);
|
||||
void psys_disable_all(struct Object *ob);
|
||||
void psys_enable_all(struct Object *ob);
|
||||
int psys_ob_has_hair(struct Object *ob);
|
||||
|
||||
struct Object *psys_get_lattice(struct ParticleSimulationData *sim);
|
||||
|
||||
int psys_in_edit_mode(struct Scene *scene, struct ParticleSystem *psys);
|
||||
int psys_check_enabled(struct Object *ob, struct ParticleSystem *psys);
|
||||
|
||||
void psys_free_boid_rules(struct ListBase *list);
|
||||
/* free */
|
||||
void psys_free_settings(struct ParticleSettings *part);
|
||||
void free_child_path_cache(struct ParticleSystem *psys);
|
||||
void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit);
|
||||
void free_hair(struct Object *ob, struct ParticleSystem *psys, int dynamics);
|
||||
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);
|
||||
|
||||
void psys_render_set(struct Object *ob, struct ParticleSystem *psys, float viewmat[][4], float winmat[][4], int winx, int winy, int timeoffset);
|
||||
void psys_render_restore(struct Object *ob, struct ParticleSystem *psys);
|
||||
@@ -234,45 +247,38 @@ struct ParticleSettings *psys_copy_settings(struct ParticleSettings *part);
|
||||
void psys_flush_particle_settings(struct Scene *scene, struct ParticleSettings *part, int recalc);
|
||||
void make_local_particlesettings(struct ParticleSettings *part);
|
||||
|
||||
struct LinkNode *psys_using_settings(struct Scene *scene, struct ParticleSettings *part, int flush_update);
|
||||
void psys_reset(struct ParticleSystem *psys, int mode);
|
||||
|
||||
void psys_find_parents(struct Object *ob, struct ParticleSystemModifierData *psmd, struct ParticleSystem *psys);
|
||||
void psys_find_parents(struct ParticleSimulationData *sim);
|
||||
|
||||
void psys_cache_paths(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, float cfra);
|
||||
void psys_cache_paths(struct ParticleSimulationData *sim, float cfra);
|
||||
void psys_cache_edit_paths(struct Scene *scene, struct Object *ob, struct PTCacheEdit *edit, float cfra);
|
||||
void psys_cache_child_paths(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, float cfra, int editupdate);
|
||||
void psys_cache_child_paths(struct ParticleSimulationData *sim, float cfra, int editupdate);
|
||||
int do_guide(struct Scene *scene, struct ParticleKey *state, int pa_num, float time, struct ListBase *lb);
|
||||
float psys_get_size(struct Object *ob, struct Material *ma, struct ParticleSystemModifierData *psmd, struct IpoCurve *icu_size, struct ParticleSystem *psys, struct ParticleSettings *part, struct ParticleData *pa, float *vg_size);
|
||||
float psys_get_timestep(struct ParticleSettings *part);
|
||||
float psys_get_timestep(struct ParticleSimulationData *sim);
|
||||
float psys_get_child_time(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *birthtime, float *dietime);
|
||||
float psys_get_child_size(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *pa_time);
|
||||
void psys_get_particle_on_path(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, int pa_num, struct ParticleKey *state, int vel);
|
||||
int psys_get_particle_state(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, int p, struct ParticleKey *state, int always);
|
||||
void psys_get_particle_on_path(struct ParticleSimulationData *sim, int pa_num, struct ParticleKey *state, int vel);
|
||||
int psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct ParticleKey *state, int always);
|
||||
|
||||
/* for anim.c */
|
||||
void psys_get_dupli_texture(struct Object *ob, struct ParticleSettings *part, struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, float *uv, float *orco);
|
||||
void psys_get_dupli_path_transform(struct Object *ob, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, struct ParticleCacheKey *cache, float mat[][4], float *scale);
|
||||
void psys_get_dupli_path_transform(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ChildParticle *cpa, struct ParticleCacheKey *cache, float mat[][4], float *scale);
|
||||
|
||||
ParticleThread *psys_threads_create(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys);
|
||||
int psys_threads_init_distribution(ParticleThread *threads, struct Scene *scene, struct DerivedMesh *dm, int from);
|
||||
int psys_threads_init_path(ParticleThread *threads, struct Scene *scene, float cfra, int editupdate);
|
||||
ParticleThread *psys_threads_create(struct ParticleSimulationData *sim);
|
||||
void psys_threads_free(ParticleThread *threads);
|
||||
|
||||
void psys_thread_distribute_particle(ParticleThread *thread, struct ParticleData *pa, struct ChildParticle *cpa, int p);
|
||||
void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, ParticleCacheKey *keys, int i);
|
||||
|
||||
void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3], float zvec[3], float center[3]);
|
||||
|
||||
/* particle_system.c */
|
||||
struct ParticleSystem *psys_get_target_system(struct Object *ob, struct ParticleTarget *pt);
|
||||
void psys_count_keyed_targets(struct Object *ob, struct ParticleSystem *psys);
|
||||
void psys_get_reactor_target(struct Object *ob, struct ParticleSystem *psys, struct Object **target_ob, struct ParticleSystem **target_psys);
|
||||
void psys_count_keyed_targets(struct ParticleSimulationData *sim);
|
||||
//void psys_get_reactor_target(struct ParticleSimulationData *sim, struct Object **target_ob, struct ParticleSystem **target_psys);
|
||||
|
||||
void psys_init_effectors(struct Scene *scene, struct Object *obsrc, struct Group *group, struct ParticleSystem *psys);
|
||||
void psys_end_effectors(struct ParticleSystem *psys);
|
||||
int psys_update_effectors(ParticleSimulationData *sim, float cfra, int precalc);
|
||||
|
||||
void psys_make_temp_pointcache(struct Object *ob, struct ParticleSystem *psys);
|
||||
void psys_end_temp_pointcache(struct ParticleSystem *psys);
|
||||
void psys_get_pointcache_start_end(struct Scene *scene, struct ParticleSystem *psys, int *sfra, int *efra);
|
||||
void psys_get_pointcache_start_end(struct Scene *scene, ParticleSystem *psys, int *sfra, int *efra);
|
||||
|
||||
void psys_check_boid_data(struct ParticleSystem *psys);
|
||||
|
||||
@@ -280,39 +286,45 @@ void particle_system_update(struct Scene *scene, struct Object *ob, struct Parti
|
||||
|
||||
/* ----------- functions needed only inside particlesystem ------------ */
|
||||
/* particle.c */
|
||||
void psys_disable_all(struct Object *ob);
|
||||
void psys_enable_all(struct Object *ob);
|
||||
|
||||
void free_hair(struct Object *ob, struct ParticleSystem *psys, int dynamics);
|
||||
void free_keyed_keys(struct ParticleSystem *psys);
|
||||
void psys_free_particles(struct ParticleSystem *psys);
|
||||
void psys_free_children(struct ParticleSystem *psys);
|
||||
|
||||
void psys_interpolate_particle(short type, struct ParticleKey keys[4], float dt, struct ParticleKey *result, int velocity);
|
||||
void psys_key_to_object(struct Object *ob, struct ParticleKey *key, float imat[][4]);
|
||||
//void psys_key_to_geometry(struct DerivedMesh *dm, struct ParticleData *pa, struct ParticleKey *key);
|
||||
//void psys_key_from_geometry(struct DerivedMesh *dm, struct ParticleData *pa, struct ParticleKey *key);
|
||||
//void psys_face_mat(struct DerivedMesh *dm, struct ParticleData *pa, float mat[][4]);
|
||||
void psys_vec_rot_to_face(struct DerivedMesh *dm, struct ParticleData *pa, float *vec);
|
||||
//void psys_vec_rot_from_face(struct DerivedMesh *dm, struct ParticleData *pa, float *vec);
|
||||
void psys_mat_hair_to_object(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]);
|
||||
void psys_mat_hair_to_global(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]);
|
||||
void psys_mat_hair_to_orco(struct Object *ob, struct DerivedMesh *dm, short from, struct ParticleData *pa, float hairmat[][4]);
|
||||
|
||||
void psys_free_pdd(struct ParticleSystem *psys);
|
||||
|
||||
float *psys_cache_vgroup(struct DerivedMesh *dm, struct ParticleSystem *psys, int vgroup);
|
||||
void psys_get_texture(struct Object *ob, struct Material *ma, struct ParticleSystemModifierData *psmd, struct ParticleSystem *psys, struct ParticleData *pa, struct ParticleTexture *ptex, int event);
|
||||
void psys_get_texture(struct ParticleSimulationData *sim, struct Material *ma, struct ParticleData *pa, struct ParticleTexture *ptex, int event);
|
||||
void psys_interpolate_face(struct MVert *mvert, struct MFace *mface, struct MTFace *tface, float (*orcodata)[3], float *uv, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor);
|
||||
float psys_particle_value_from_verts(struct DerivedMesh *dm, short from, struct ParticleData *pa, float *values);
|
||||
float psys_interpolate_value_from_verts(struct DerivedMesh *dm, short from, int index, float *fw, float *values);
|
||||
void psys_get_from_key(struct ParticleKey *key, float *loc, float *vel, float *rot, float *time);
|
||||
|
||||
/* only in edisparticle.c*/
|
||||
int psys_intersect_dm(struct Scene *scene, struct Object *ob, struct DerivedMesh *dm, float *vert_cos, float *co1, float* co2, float *min_d, int *min_face, float *min_uv, float *face_minmax, float *pa_minmax, float radius, float *ipoint);
|
||||
/* BLI_bvhtree_ray_cast callback */
|
||||
void particle_intersect_face(void *userdata, int index, const struct BVHTreeRay *ray, struct BVHTreeRayHit *hit);
|
||||
void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int index_dmcache, float *fw, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor);
|
||||
|
||||
/* particle_system.c */
|
||||
void initialize_particle(struct ParticleData *pa, int p, struct Object *ob, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd);
|
||||
void initialize_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, int p);
|
||||
|
||||
int effector_find_co(struct Scene *scene, float *pco, struct SurfaceModifierData *sur, struct Object *ob, struct PartDeflect *pd, float *co, float *nor, float *vel, int *index);
|
||||
void do_effectors(int pa_no, struct ParticleData *pa, struct ParticleKey *state, struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, float *texco, float *force_field, float *vel,float framestep, float cfra);
|
||||
void do_effectors(struct ParticleSimulationData *sim, int pa_no, struct ParticleData *pa, struct ParticleKey *state, float *texco, float *force_field, float *vel,float framestep, float cfra);
|
||||
void psys_end_effectors(struct ParticleSystem *psys);
|
||||
|
||||
void psys_calc_dmcache(struct Object *ob, struct DerivedMesh *dm, struct ParticleSystem *psys);
|
||||
int psys_particle_dm_face_lookup(struct Object *ob, struct DerivedMesh *dm, int index, float *fw, struct LinkNode *node);
|
||||
|
||||
void reset_particle(struct Scene *scene, struct ParticleData *pa, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd, struct Object *ob,
|
||||
float dtime, float cfra, float *vg_vel, float *vg_tan, float *vg_rot);
|
||||
void reset_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, float dtime, float cfra);
|
||||
|
||||
|
||||
/* psys_reset */
|
||||
|
||||
@@ -766,12 +766,12 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
|
||||
GroupObject *go;
|
||||
Object *ob=0, **oblist=0, obcopy, *obcopylist=0;
|
||||
DupliObject *dob;
|
||||
ParticleSimulationData sim = {scene, par, psys, psys_get_modifier(par, psys)};
|
||||
ParticleSettings *part;
|
||||
ParticleData *pa;
|
||||
ChildParticle *cpa=0;
|
||||
ParticleKey state;
|
||||
ParticleCacheKey *cache;
|
||||
ParticleSystemModifierData *psmd;
|
||||
float ctime, pa_time, scale = 1.0f;
|
||||
float tmat[4][4], mat[4][4], pamat[4][4], size=0.0;
|
||||
float (*obmat)[4], (*oldobmat)[4];
|
||||
@@ -784,7 +784,6 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
|
||||
if(level>MAX_DUPLI_RECUR) return;
|
||||
|
||||
part=psys->part;
|
||||
psmd= psys_get_modifier(par, psys);
|
||||
|
||||
if(part==0)
|
||||
return;
|
||||
@@ -816,7 +815,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
|
||||
totpart = psys->totcached;
|
||||
}
|
||||
|
||||
psys->lattice = psys_get_lattice(scene, par, psys);
|
||||
psys->lattice = psys_get_lattice(&sim);
|
||||
|
||||
/* gather list of objects or single object */
|
||||
if(part->ren_as==PART_DRAW_GR) {
|
||||
@@ -887,11 +886,11 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
|
||||
/* hair we handle separate and compute transform based on hair keys */
|
||||
if(a < totpart) {
|
||||
cache = psys->pathcache[a];
|
||||
psys_get_dupli_path_transform(par, psys, psmd, pa, 0, cache, pamat, &scale);
|
||||
psys_get_dupli_path_transform(&sim, pa, 0, cache, pamat, &scale);
|
||||
}
|
||||
else {
|
||||
cache = psys->childcache[a-totpart];
|
||||
psys_get_dupli_path_transform(par, psys, psmd, 0, cpa, cache, pamat, &scale);
|
||||
psys_get_dupli_path_transform(&sim, 0, cpa, cache, pamat, &scale);
|
||||
}
|
||||
|
||||
VECCOPY(pamat[3], cache->co);
|
||||
@@ -901,7 +900,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
|
||||
else {
|
||||
/* first key */
|
||||
state.time = ctime;
|
||||
if(psys_get_particle_state(scene, par, psys, a, &state, 0) == 0)
|
||||
if(psys_get_particle_state(&sim, a, &state, 0) == 0)
|
||||
continue;
|
||||
|
||||
QuatToMat4(state.rot, pamat);
|
||||
@@ -921,7 +920,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
|
||||
dob= new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS, animated);
|
||||
Mat4CpyMat4(dob->omat, obcopylist[b].obmat);
|
||||
if(G.rendering)
|
||||
psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco);
|
||||
psys_get_dupli_texture(par, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -940,7 +939,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
|
||||
dob= new_dupli_object(lb, ob, mat, ob->lay, counter, OB_DUPLIPARTS, animated);
|
||||
Mat4CpyMat4(dob->omat, oldobmat);
|
||||
if(G.rendering)
|
||||
psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco);
|
||||
psys_get_dupli_texture(par, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
|
||||
float vec_to_part[3];
|
||||
|
||||
if(pd && pd->forcefield == PFIELD_BOID) {
|
||||
effector_find_co(bbd->scene, pa->prev_state.co, NULL, gabr->ob, pd, loc, vec, NULL, NULL);
|
||||
effector_find_co(bbd->sim->scene, pa->prev_state.co, NULL, gabr->ob, pd, loc, vec, NULL, NULL);
|
||||
|
||||
VecSubf(vec_to_part, pa->prev_state.co, loc);
|
||||
|
||||
@@ -99,7 +99,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
|
||||
priority = 1.0;
|
||||
priority_ob = gabr->ob;
|
||||
}
|
||||
else for(ec=bbd->psys->effectors.first; ec; ec=ec->next) {
|
||||
else for(ec=bbd->sim->psys->effectors.first; ec; ec=ec->next) {
|
||||
if(ec->type & PSYS_EC_EFFECTOR) {
|
||||
Object *eob = ec->ob;
|
||||
PartDeflect *pd = eob->pd;
|
||||
@@ -111,7 +111,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
|
||||
if(pd->forcefield == PFIELD_BOID && mul * pd->f_strength > 0.0f) {
|
||||
float vec_to_part[3], temp;
|
||||
|
||||
effector_find_co(bbd->scene, pa->prev_state.co, NULL, eob, pd, loc, vec, NULL, NULL);
|
||||
effector_find_co(bbd->sim->scene, pa->prev_state.co, NULL, eob, pd, loc, vec, NULL, NULL);
|
||||
|
||||
VecSubf(vec_to_part, pa->prev_state.co, loc);
|
||||
|
||||
@@ -147,7 +147,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
|
||||
|
||||
if(gabr->options & BRULE_GOAL_AVOID_PREDICT) {
|
||||
/* estimate future location of target */
|
||||
surface = (float)effector_find_co(bbd->scene, pa->prev_state.co, NULL, eob, pd, loc, nor, vec, NULL);
|
||||
surface = (float)effector_find_co(bbd->sim->scene, pa->prev_state.co, NULL, eob, pd, loc, nor, vec, NULL);
|
||||
|
||||
VecSubf(vec_to_part, pa->prev_state.co, loc);
|
||||
len = Normalize(vec_to_part);
|
||||
@@ -157,7 +157,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val,
|
||||
VecSubf(vec_to_part, pa->prev_state.co, loc);
|
||||
}
|
||||
else {
|
||||
surface = (float)effector_find_co(bbd->scene, pa->prev_state.co, NULL, eob, pd, loc, nor, NULL, NULL);
|
||||
surface = (float)effector_find_co(bbd->sim->scene, pa->prev_state.co, NULL, eob, pd, loc, nor, NULL, NULL);
|
||||
|
||||
VecSubf(vec_to_part, pa->prev_state.co, loc);
|
||||
len = VecLength(vec_to_part);
|
||||
@@ -228,7 +228,7 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
|
||||
hit.dist = col.ray_len = VecLength(ray_dir);
|
||||
|
||||
/* find out closest deflector object */
|
||||
for(ec=bbd->psys->effectors.first; ec; ec=ec->next) {
|
||||
for(ec=bbd->sim->psys->effectors.first; ec; ec=ec->next) {
|
||||
if(ec->type & PSYS_EC_DEFLECT) {
|
||||
Object *eob = ec->ob;
|
||||
|
||||
@@ -261,12 +261,12 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
|
||||
//check boids in own system
|
||||
if(acbr->options & BRULE_ACOLL_WITH_BOIDS)
|
||||
{
|
||||
neighbors = BLI_kdtree_range_search(bbd->psys->tree, acbr->look_ahead * VecLength(pa->prev_state.vel), pa->prev_state.co, pa->prev_state.ave, &ptn);
|
||||
neighbors = BLI_kdtree_range_search(bbd->sim->psys->tree, acbr->look_ahead * VecLength(pa->prev_state.vel), pa->prev_state.co, pa->prev_state.ave, &ptn);
|
||||
if(neighbors > 1) for(n=1; n<neighbors; n++) {
|
||||
VECCOPY(co1, pa->prev_state.co);
|
||||
VECCOPY(vel1, pa->prev_state.vel);
|
||||
VECCOPY(co2, (bbd->psys->particles + ptn[n].index)->prev_state.co);
|
||||
VECCOPY(vel2, (bbd->psys->particles + ptn[n].index)->prev_state.vel);
|
||||
VECCOPY(co2, (bbd->sim->psys->particles + ptn[n].index)->prev_state.co);
|
||||
VECCOPY(vel2, (bbd->sim->psys->particles + ptn[n].index)->prev_state.vel);
|
||||
|
||||
VecSubf(loc, co1, co2);
|
||||
|
||||
@@ -303,8 +303,8 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues *
|
||||
if(ptn){ MEM_freeN(ptn); ptn=NULL; }
|
||||
|
||||
/* check boids in other systems */
|
||||
for(pt=bbd->psys->targets.first; pt; pt=pt->next) {
|
||||
ParticleSystem *epsys = psys_get_target_system(bbd->ob, pt);
|
||||
for(pt=bbd->sim->psys->targets.first; pt; pt=pt->next) {
|
||||
ParticleSystem *epsys = psys_get_target_system(bbd->sim->ob, pt);
|
||||
|
||||
if(epsys) {
|
||||
neighbors = BLI_kdtree_range_search(epsys->tree, acbr->look_ahead * VecLength(pa->prev_state.vel), pa->prev_state.co, pa->prev_state.ave, &ptn);
|
||||
@@ -362,11 +362,11 @@ static int rule_separate(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Pa
|
||||
ParticleTarget *pt;
|
||||
float len = 2.0f * val->personal_space * pa->size + 1.0f;
|
||||
float vec[3] = {0.0f, 0.0f, 0.0f};
|
||||
int neighbors = BLI_kdtree_range_search(bbd->psys->tree, 2.0f * val->personal_space * pa->size, pa->prev_state.co, NULL, &ptn);
|
||||
int neighbors = BLI_kdtree_range_search(bbd->sim->psys->tree, 2.0f * val->personal_space * pa->size, pa->prev_state.co, NULL, &ptn);
|
||||
int ret = 0;
|
||||
|
||||
if(neighbors > 1 && ptn[1].dist!=0.0f) {
|
||||
VecSubf(vec, pa->prev_state.co, bbd->psys->particles[ptn[1].index].state.co);
|
||||
VecSubf(vec, pa->prev_state.co, bbd->sim->psys->particles[ptn[1].index].state.co);
|
||||
VecMulf(vec, (2.0f * val->personal_space * pa->size - ptn[1].dist) / ptn[1].dist);
|
||||
VecAddf(bbd->wanted_co, bbd->wanted_co, vec);
|
||||
bbd->wanted_speed = val->max_speed;
|
||||
@@ -376,8 +376,8 @@ static int rule_separate(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Pa
|
||||
if(ptn){ MEM_freeN(ptn); ptn=NULL; }
|
||||
|
||||
/* check other boid systems */
|
||||
for(pt=bbd->psys->targets.first; pt; pt=pt->next) {
|
||||
ParticleSystem *epsys = psys_get_target_system(bbd->ob, pt);
|
||||
for(pt=bbd->sim->psys->targets.first; pt; pt=pt->next) {
|
||||
ParticleSystem *epsys = psys_get_target_system(bbd->sim->ob, pt);
|
||||
|
||||
if(epsys) {
|
||||
neighbors = BLI_kdtree_range_search(epsys->tree, 2.0f * val->personal_space * pa->size, pa->prev_state.co, NULL, &ptn);
|
||||
@@ -400,14 +400,14 @@ static int rule_flock(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti
|
||||
{
|
||||
KDTreeNearest ptn[11];
|
||||
float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
|
||||
int neighbors = BLI_kdtree_find_n_nearest(bbd->psys->tree, 11, pa->state.co, pa->prev_state.ave, ptn);
|
||||
int neighbors = BLI_kdtree_find_n_nearest(bbd->sim->psys->tree, 11, pa->state.co, pa->prev_state.ave, ptn);
|
||||
int n;
|
||||
int ret = 0;
|
||||
|
||||
if(neighbors > 1) {
|
||||
for(n=1; n<neighbors; n++) {
|
||||
VecAddf(loc, loc, bbd->psys->particles[ptn[n].index].prev_state.co);
|
||||
VecAddf(vec, vec, bbd->psys->particles[ptn[n].index].prev_state.vel);
|
||||
VecAddf(loc, loc, bbd->sim->psys->particles[ptn[n].index].prev_state.co);
|
||||
VecAddf(vec, vec, bbd->sim->psys->particles[ptn[n].index].prev_state.vel);
|
||||
}
|
||||
|
||||
VecMulf(loc, 1.0f/((float)neighbors - 1.0f));
|
||||
@@ -429,8 +429,8 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va
|
||||
BoidRuleFollowLeader *flbr = (BoidRuleFollowLeader*) rule;
|
||||
float vec[3] = {0.0f, 0.0f, 0.0f}, loc[3] = {0.0f, 0.0f, 0.0f};
|
||||
float mul, len;
|
||||
int n = (flbr->queue_size <= 1) ? bbd->psys->totpart : flbr->queue_size;
|
||||
int i, ret = 0, p = pa - bbd->psys->particles;
|
||||
int n = (flbr->queue_size <= 1) ? bbd->sim->psys->totpart : flbr->queue_size;
|
||||
int i, ret = 0, p = pa - bbd->sim->psys->particles;
|
||||
|
||||
if(flbr->ob) {
|
||||
float vec2[3], t;
|
||||
@@ -475,8 +475,8 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va
|
||||
|
||||
/* not blocking so try to follow leader */
|
||||
if(p && flbr->options & BRULE_LEADER_IN_LINE) {
|
||||
VECCOPY(vec, bbd->psys->particles[p-1].prev_state.vel);
|
||||
VECCOPY(loc, bbd->psys->particles[p-1].prev_state.co);
|
||||
VECCOPY(vec, bbd->sim->psys->particles[p-1].prev_state.vel);
|
||||
VECCOPY(loc, bbd->sim->psys->particles[p-1].prev_state.co);
|
||||
}
|
||||
else {
|
||||
VECCOPY(loc, flbr->oloc);
|
||||
@@ -496,10 +496,10 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va
|
||||
float vec2[3], t, t_min = 3.0f;
|
||||
|
||||
/* first check we're not blocking any leaders */
|
||||
for(i = 0; i< bbd->psys->totpart; i+=n){
|
||||
VECCOPY(vec, bbd->psys->particles[i].prev_state.vel);
|
||||
for(i = 0; i< bbd->sim->psys->totpart; i+=n){
|
||||
VECCOPY(vec, bbd->sim->psys->particles[i].prev_state.vel);
|
||||
|
||||
VecSubf(loc, pa->prev_state.co, bbd->psys->particles[i].prev_state.co);
|
||||
VecSubf(loc, pa->prev_state.co, bbd->sim->psys->particles[i].prev_state.co);
|
||||
|
||||
mul = Inpf(vec, vec);
|
||||
|
||||
@@ -539,12 +539,12 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va
|
||||
|
||||
/* not blocking so try to follow leader */
|
||||
if(flbr->options & BRULE_LEADER_IN_LINE) {
|
||||
VECCOPY(vec, bbd->psys->particles[p-1].prev_state.vel);
|
||||
VECCOPY(loc, bbd->psys->particles[p-1].prev_state.co);
|
||||
VECCOPY(vec, bbd->sim->psys->particles[p-1].prev_state.vel);
|
||||
VECCOPY(loc, bbd->sim->psys->particles[p-1].prev_state.co);
|
||||
}
|
||||
else {
|
||||
VECCOPY(vec, bbd->psys->particles[p - p%n].prev_state.vel);
|
||||
VECCOPY(loc, bbd->psys->particles[p - p%n].prev_state.co);
|
||||
VECCOPY(vec, bbd->sim->psys->particles[p - p%n].prev_state.vel);
|
||||
VECCOPY(loc, bbd->sim->psys->particles[p - p%n].prev_state.co);
|
||||
}
|
||||
|
||||
/* fac is seconds behind leader */
|
||||
@@ -584,7 +584,7 @@ static int rule_average_speed(BoidRule *rule, BoidBrainData *bbd, BoidValues *va
|
||||
|
||||
/* leveling */
|
||||
if(asbr->level > 0.0f) {
|
||||
Projf(vec, bbd->wanted_co, bbd->psys->part->acc);
|
||||
Projf(vec, bbd->wanted_co, bbd->sim->psys->part->acc);
|
||||
VecMulf(vec, asbr->level);
|
||||
VecSubf(bbd->wanted_co, bbd->wanted_co, vec);
|
||||
}
|
||||
@@ -601,7 +601,7 @@ static int rule_average_speed(BoidRule *rule, BoidBrainData *bbd, BoidValues *va
|
||||
|
||||
/* leveling */
|
||||
if(asbr->level > 0.0f) {
|
||||
Projf(vec, bbd->wanted_co, bbd->psys->part->acc);
|
||||
Projf(vec, bbd->wanted_co, bbd->sim->psys->part->acc);
|
||||
VecMulf(vec, asbr->level);
|
||||
VecSubf(bbd->wanted_co, bbd->wanted_co, vec);
|
||||
}
|
||||
@@ -627,9 +627,9 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti
|
||||
int n, ret = 0;
|
||||
|
||||
/* calculate own group strength */
|
||||
int neighbors = BLI_kdtree_range_search(bbd->psys->tree, fbr->distance, pa->prev_state.co, NULL, &ptn);
|
||||
int neighbors = BLI_kdtree_range_search(bbd->sim->psys->tree, fbr->distance, pa->prev_state.co, NULL, &ptn);
|
||||
for(n=0; n<neighbors; n++) {
|
||||
bpa = bbd->psys->particles[ptn[n].index].boid;
|
||||
bpa = bbd->sim->psys->particles[ptn[n].index].boid;
|
||||
health += bpa->data.health;
|
||||
}
|
||||
|
||||
@@ -638,8 +638,8 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti
|
||||
if(ptn){ MEM_freeN(ptn); ptn=NULL; }
|
||||
|
||||
/* add other friendlies and calculate enemy strength and find closest enemy */
|
||||
for(pt=bbd->psys->targets.first; pt; pt=pt->next) {
|
||||
ParticleSystem *epsys = psys_get_target_system(bbd->ob, pt);
|
||||
for(pt=bbd->sim->psys->targets.first; pt; pt=pt->next) {
|
||||
ParticleSystem *epsys = psys_get_target_system(bbd->sim->ob, pt);
|
||||
if(epsys) {
|
||||
epars = epsys->particles;
|
||||
|
||||
@@ -760,11 +760,11 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro
|
||||
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);
|
||||
effector_find_co(bbd->sim->scene, pa->state.co, surmd, NULL, NULL, x, NULL, v, NULL);
|
||||
VecAddf(x, x, v);
|
||||
|
||||
/* get actual position on surface */
|
||||
effector_find_co(bbd->scene, x, surmd, NULL, NULL, ground_co, ground_nor, NULL, NULL);
|
||||
effector_find_co(bbd->sim->scene, x, surmd, NULL, NULL, ground_co, ground_nor, NULL, NULL);
|
||||
|
||||
return bpa->ground;
|
||||
}
|
||||
@@ -785,7 +785,7 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro
|
||||
hit.dist = col.ray_len = VecLength(ray_dir);
|
||||
|
||||
/* find out upmost deflector object */
|
||||
for(ec=bbd->psys->effectors.first; ec; ec=ec->next) {
|
||||
for(ec=bbd->sim->psys->effectors.first; ec; ec=ec->next) {
|
||||
if(ec->type & PSYS_EC_DEFLECT) {
|
||||
Object *eob = ec->ob;
|
||||
|
||||
@@ -941,7 +941,7 @@ 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);
|
||||
BLI_srandom(bbd->sim->psys->seed + p);
|
||||
rand = BLI_rand();
|
||||
BLI_srandom((int)bbd->cfra + rand);
|
||||
|
||||
@@ -1077,7 +1077,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
|
||||
float ground_co[3] = {0.0f, 0.0f, 0.0f}, ground_nor[3] = {0.0f, 0.0f, 1.0f};
|
||||
float force[3] = {0.0f, 0.0f, 0.0f}, tvel[3] = {0.0f, 0.0f, 1.0f};
|
||||
float pa_mass=bbd->part->mass, dtime=bbd->dfra*bbd->timestep;
|
||||
int p = pa - bbd->psys->particles;
|
||||
int p = pa - bbd->sim->psys->particles;
|
||||
|
||||
set_boid_values(&val, boids, pa);
|
||||
|
||||
@@ -1208,7 +1208,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);
|
||||
do_effectors(bbd->sim, p, pa, &pa->state, pa->state.co, force, tvel, bbd->dfra, bbd->cfra);
|
||||
|
||||
if(ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)) {
|
||||
float length = Normalize(force);
|
||||
|
||||
@@ -1160,25 +1160,66 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
|
||||
BLI_linklist_prepend ( &cloth->springs, spring );
|
||||
}
|
||||
|
||||
// bending springs
|
||||
search2 = cloth->springs;
|
||||
for ( i = struct_springs; i < struct_springs+shear_springs; i++ )
|
||||
{
|
||||
if ( !search2 )
|
||||
break;
|
||||
if(numfaces) {
|
||||
// bending springs
|
||||
search2 = cloth->springs;
|
||||
for ( i = struct_springs; i < struct_springs+shear_springs; i++ )
|
||||
{
|
||||
if ( !search2 )
|
||||
break;
|
||||
|
||||
tspring2 = search2->link;
|
||||
search = edgelist[tspring2->kl];
|
||||
while ( search )
|
||||
tspring2 = search2->link;
|
||||
search = edgelist[tspring2->kl];
|
||||
while ( search )
|
||||
{
|
||||
tspring = search->link;
|
||||
index2 = ( ( tspring->ij==tspring2->kl ) ? ( tspring->kl ) : ( tspring->ij ) );
|
||||
|
||||
// check for existing spring
|
||||
// check also if startpoint is equal to endpoint
|
||||
if ( !BLI_edgehash_haskey ( edgehash, MIN2(tspring2->ij, index2), MAX2(tspring2->ij, index2) )
|
||||
&& ( index2!=tspring2->ij ) )
|
||||
{
|
||||
spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
|
||||
|
||||
if(!spring)
|
||||
{
|
||||
cloth_free_errorsprings(cloth, edgehash, edgelist);
|
||||
return 0;
|
||||
}
|
||||
|
||||
spring->ij = MIN2(tspring2->ij, index2);
|
||||
spring->kl = MAX2(tspring2->ij, index2);
|
||||
VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
|
||||
spring->restlen = sqrt ( INPR ( temp, temp ) );
|
||||
spring->type = CLOTH_SPRING_TYPE_BENDING;
|
||||
spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0;
|
||||
BLI_edgehash_insert ( edgehash, spring->ij, spring->kl, NULL );
|
||||
bend_springs++;
|
||||
|
||||
BLI_linklist_prepend ( &cloth->springs, spring );
|
||||
}
|
||||
search = search->next;
|
||||
}
|
||||
search2 = search2->next;
|
||||
}
|
||||
}
|
||||
else if(struct_springs > 2) {
|
||||
/* bending springs for hair strands */
|
||||
/* The current algorightm only goes through the edges in order of the mesh edges list */
|
||||
/* and makes springs between the outer vert of edges sharing a vertice. This works just */
|
||||
/* fine for hair, but not for user generated string meshes. This could/should be later */
|
||||
/* extended to work with non-ordered edges so that it can be used for general "rope */
|
||||
/* dynamics" without the need for the vertices or edges to be ordered through the length*/
|
||||
/* of the strands. -jahka */
|
||||
search = cloth->springs;
|
||||
search2 = search->next;
|
||||
while(search && search2)
|
||||
{
|
||||
tspring = search->link;
|
||||
index2 = ( ( tspring->ij==tspring2->kl ) ? ( tspring->kl ) : ( tspring->ij ) );
|
||||
|
||||
// check for existing spring
|
||||
// check also if startpoint is equal to endpoint
|
||||
if ( !BLI_edgehash_haskey ( edgehash, MIN2(tspring2->ij, index2), MAX2(tspring2->ij, index2) )
|
||||
&& ( index2!=tspring2->ij ) )
|
||||
{
|
||||
tspring2 = search2->link;
|
||||
|
||||
if(tspring->ij == tspring2->kl) {
|
||||
spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
|
||||
|
||||
if(!spring)
|
||||
@@ -1187,20 +1228,20 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
|
||||
return 0;
|
||||
}
|
||||
|
||||
spring->ij = MIN2(tspring2->ij, index2);
|
||||
spring->kl = MAX2(tspring2->ij, index2);
|
||||
spring->ij = tspring2->ij;
|
||||
spring->kl = tspring->kl;
|
||||
VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
|
||||
spring->restlen = sqrt ( INPR ( temp, temp ) );
|
||||
spring->type = CLOTH_SPRING_TYPE_BENDING;
|
||||
spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0;
|
||||
BLI_edgehash_insert ( edgehash, spring->ij, spring->kl, NULL );
|
||||
bend_springs++;
|
||||
|
||||
BLI_linklist_prepend ( &cloth->springs, spring );
|
||||
}
|
||||
|
||||
search = search->next;
|
||||
search2 = search2->next;
|
||||
}
|
||||
search2 = search2->next;
|
||||
}
|
||||
|
||||
/* insert other near springs in edgehash AFTER bending springs are calculated (for selfcolls) */
|
||||
|
||||
@@ -560,6 +560,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
|
||||
for(; psys; psys=psys->next) {
|
||||
BoidRule *rule = NULL;
|
||||
BoidState *state = NULL;
|
||||
ParticleSimulationData sim = {scene, ob, psys, NULL};
|
||||
ParticleSettings *part= psys->part;
|
||||
|
||||
dag_add_relation(dag, node, node, DAG_RL_OB_DATA, "Particle-Object Relation");
|
||||
@@ -592,8 +593,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
|
||||
}
|
||||
}
|
||||
|
||||
psys_end_effectors(psys);
|
||||
psys_init_effectors(scene, ob, psys->part->eff_group, psys);
|
||||
psys_update_effectors(&sim, 0.0, 0);
|
||||
|
||||
for(nec= psys->effectors.first; nec; nec= nec->next) {
|
||||
Object *ob1= nec->ob;
|
||||
|
||||
@@ -6601,6 +6601,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
|
||||
{
|
||||
DerivedMesh *dm = derivedData, *result;
|
||||
ParticleInstanceModifierData *pimd= (ParticleInstanceModifierData*) md;
|
||||
ParticleSimulationData sim;
|
||||
ParticleSystem * psys=0;
|
||||
ParticleData *pa=0, *pars=0;
|
||||
MFace *mface, *orig_mface;
|
||||
@@ -6635,6 +6636,11 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
|
||||
if(totpart==0)
|
||||
return derivedData;
|
||||
|
||||
sim.scene = md->scene;
|
||||
sim.ob = pimd->ob;
|
||||
sim.psys = psys;
|
||||
sim.psmd = psys_get_modifier(pimd->ob, psys);
|
||||
|
||||
if(pimd->flag & eParticleInstanceFlag_UseSize) {
|
||||
int p;
|
||||
float *si;
|
||||
@@ -6662,7 +6668,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
|
||||
maxvert=totvert*totpart;
|
||||
maxface=totface*totpart;
|
||||
|
||||
psys->lattice=psys_get_lattice(md->scene, ob, psys);
|
||||
psys->lattice=psys_get_lattice(&sim);
|
||||
|
||||
if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED){
|
||||
|
||||
@@ -6712,7 +6718,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
|
||||
mv->co[axis] = 0.0;
|
||||
}
|
||||
|
||||
psys_get_particle_on_path(md->scene, pimd->ob, psys,first_particle + i/totvert, &state,1);
|
||||
psys_get_particle_on_path(&sim, first_particle + i/totvert, &state,1);
|
||||
|
||||
Normalize(state.vel);
|
||||
|
||||
@@ -6734,7 +6740,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
|
||||
}
|
||||
else{
|
||||
state.time=-1.0;
|
||||
psys_get_particle_state(md->scene, pimd->ob, psys, first_particle + i/totvert, &state,1);
|
||||
psys_get_particle_state(&sim, first_particle + i/totvert, &state,1);
|
||||
}
|
||||
|
||||
QuatMulVecf(state.rot,mv->co);
|
||||
@@ -7416,6 +7422,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
|
||||
DerivedMesh *explode, *dm=to_explode;
|
||||
MFace *mf=0;
|
||||
ParticleSettings *part=psmd->psys->part;
|
||||
ParticleSimulationData sim = {scene, ob, psmd->psys, psmd};
|
||||
ParticleData *pa=NULL, *pars=psmd->psys->particles;
|
||||
ParticleKey state;
|
||||
EdgeHash *vertpahash;
|
||||
@@ -7431,7 +7438,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
|
||||
totvert= dm->getNumVerts(dm);
|
||||
totpart= psmd->psys->totpart;
|
||||
|
||||
timestep= psys_get_timestep(part);
|
||||
timestep= psys_get_timestep(&sim);
|
||||
|
||||
//if(part->flag & PART_GLOB_TIME)
|
||||
cfra=bsystem_time(scene, 0,(float)scene->r.cfra,0.0);
|
||||
@@ -7474,7 +7481,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
|
||||
/* getting back to object space */
|
||||
Mat4Invert(imat,ob->obmat);
|
||||
|
||||
psmd->psys->lattice = psys_get_lattice(scene, ob, psmd->psys);
|
||||
psmd->psys->lattice = psys_get_lattice(&sim);
|
||||
|
||||
/* duplicate & displace vertices */
|
||||
ehi= BLI_edgehashIterator_new(vertpahash);
|
||||
@@ -7502,7 +7509,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
|
||||
Mat4MulVecfl(ob->obmat,loc0);
|
||||
|
||||
state.time=cfra;
|
||||
psys_get_particle_state(scene, ob, psmd->psys, i, &state,1);
|
||||
psys_get_particle_state(&sim, i, &state, 1);
|
||||
|
||||
vertco=CDDM_get_vert(explode,v)->co;
|
||||
|
||||
@@ -7591,7 +7598,7 @@ static DerivedMesh * explodeModifier_applyModifier(
|
||||
{
|
||||
DerivedMesh *dm = derivedData;
|
||||
ExplodeModifierData *emd= (ExplodeModifierData*) md;
|
||||
ParticleSystemModifierData *psmd=explodeModifier_findPrecedingParticlesystem(ob,md);;
|
||||
ParticleSystemModifierData *psmd=explodeModifier_findPrecedingParticlesystem(ob,md);
|
||||
|
||||
if(psmd){
|
||||
ParticleSystem * psys=psmd->psys;
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_DerivedMesh.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_softbody.h"
|
||||
#include "BKE_cloth.h"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_library.h"
|
||||
@@ -85,7 +85,7 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index,
|
||||
float *fuv, float *orco, ParticleTexture *ptex, int event);
|
||||
static void get_child_modifier_parameters(ParticleSettings *part, ParticleThreadContext *ctx,
|
||||
ChildParticle *cpa, short cpa_from, int cpa_num, float *cpa_fuv, float *orco, ParticleTexture *ptex);
|
||||
static void do_child_modifiers(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSettings *part,
|
||||
static void do_child_modifiers(ParticleSimulationData *sim,
|
||||
ParticleTexture *ptex, ParticleKey *par, float *par_rot, ChildParticle *cpa,
|
||||
float *orco, float mat[4][4], ParticleKey *state, float t);
|
||||
|
||||
@@ -95,11 +95,10 @@ int count_particles(ParticleSystem *psys){
|
||||
PARTICLE_P;
|
||||
int tot=0;
|
||||
|
||||
LOOP_PARTICLES {
|
||||
LOOP_SHOWN_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);
|
||||
else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP));
|
||||
else tot++;
|
||||
}
|
||||
return tot;
|
||||
@@ -109,55 +108,14 @@ int count_particles_mod(ParticleSystem *psys, int totgr, int cur){
|
||||
PARTICLE_P;
|
||||
int tot=0;
|
||||
|
||||
LOOP_PARTICLES {
|
||||
LOOP_SHOWN_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);
|
||||
else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP));
|
||||
else if(p%totgr==cur) tot++;
|
||||
}
|
||||
return tot;
|
||||
}
|
||||
int psys_count_keys(ParticleSystem *psys)
|
||||
{
|
||||
PARTICLE_P;
|
||||
int totkey=0;
|
||||
|
||||
LOOP_PARTICLES
|
||||
totkey += pa->totkey;
|
||||
|
||||
return totkey;
|
||||
}
|
||||
/* remember to free the pointer returned from this! */
|
||||
char *psys_menu_string(Object *ob, int for_sb)
|
||||
{
|
||||
ParticleSystem *psys;
|
||||
DynStr *ds;
|
||||
char *str, num[6];
|
||||
int i;
|
||||
|
||||
ds = BLI_dynstr_new();
|
||||
|
||||
if(for_sb)
|
||||
BLI_dynstr_append(ds, "|Object%x-1");
|
||||
|
||||
for(i=0,psys=ob->particlesystem.first; psys; i++,psys=psys->next){
|
||||
|
||||
BLI_dynstr_append(ds, "|");
|
||||
sprintf(num,"%i. ",i+1);
|
||||
BLI_dynstr_append(ds, num);
|
||||
BLI_dynstr_append(ds, psys->part->id.name+2);
|
||||
sprintf(num,"%%x%i",i+1);
|
||||
BLI_dynstr_append(ds, num);
|
||||
}
|
||||
|
||||
str = BLI_dynstr_get_cstring(ds);
|
||||
|
||||
BLI_dynstr_free(ds);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/* we allocate path cache memory in chunks instead of a big continguous
|
||||
* chunk, windows' memory allocater fails to find big blocks of memory often */
|
||||
|
||||
@@ -257,30 +215,13 @@ Object *psys_find_object(Scene *scene, ParticleSystem *psys)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
/* change object's active particle system */
|
||||
void psys_change_act(void *ob_v, void *act_v)
|
||||
{
|
||||
Object *ob = ob_v;
|
||||
ParticleSystem *npsys, *psys;
|
||||
short act = *((short*)act_v)-1;
|
||||
|
||||
if(act>=0){
|
||||
npsys=BLI_findlink(&ob->particlesystem,act);
|
||||
psys=psys_get_current(ob);
|
||||
|
||||
if(psys)
|
||||
psys->flag &= ~PSYS_CURRENT;
|
||||
if(npsys)
|
||||
npsys->flag |= PSYS_CURRENT;
|
||||
}
|
||||
}
|
||||
Object *psys_get_lattice(Scene *scene, Object *ob, ParticleSystem *psys)
|
||||
Object *psys_get_lattice(ParticleSimulationData *sim)
|
||||
{
|
||||
Object *lattice=0;
|
||||
|
||||
if(psys_in_edit_mode(scene, psys)==0){
|
||||
if(psys_in_edit_mode(sim->scene, sim->psys)==0){
|
||||
|
||||
ModifierData *md = (ModifierData*)psys_get_modifier(ob,psys);
|
||||
ModifierData *md = (ModifierData*)psys_get_modifier(sim->ob, sim->psys);
|
||||
|
||||
for(; md; md=md->next){
|
||||
if(md->type==eModifierType_Lattice){
|
||||
@@ -309,20 +250,20 @@ void psys_enable_all(Object *ob)
|
||||
for(; psys; psys=psys->next)
|
||||
psys->flag &= ~PSYS_DISABLED;
|
||||
}
|
||||
int psys_ob_has_hair(Object *ob)
|
||||
{
|
||||
ParticleSystem *psys = ob->particlesystem.first;
|
||||
|
||||
for(; psys; psys=psys->next)
|
||||
if(psys->part->type == PART_HAIR)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
int psys_in_edit_mode(Scene *scene, ParticleSystem *psys)
|
||||
{
|
||||
return (scene->basact && (scene->basact->object->mode & OB_MODE_PARTICLE_EDIT) && psys==psys_get_current((scene->basact)->object) && (psys->edit || psys->pointcache->edit));
|
||||
}
|
||||
static void psys_create_frand(ParticleSystem *psys)
|
||||
{
|
||||
int i;
|
||||
float *rand = psys->frand = MEM_callocN(PSYS_FRAND_COUNT * sizeof(float), "particle randoms");
|
||||
|
||||
BLI_srandom(psys->seed);
|
||||
|
||||
for(i=0; i<1024; i++, rand++)
|
||||
*rand = BLI_frand();
|
||||
}
|
||||
int psys_check_enabled(Object *ob, ParticleSystem *psys)
|
||||
{
|
||||
ParticleSystemModifierData *psmd;
|
||||
@@ -344,6 +285,14 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys)
|
||||
}
|
||||
else if(!(psmd->modifier.mode & eModifierMode_Realtime))
|
||||
return 0;
|
||||
|
||||
/* perhaps not the perfect place, but we have to be sure the rands are there before usage */
|
||||
if(!psys->frand)
|
||||
psys_create_frand(psys);
|
||||
else if(psys->recalc & PSYS_RECALC_RESET) {
|
||||
MEM_freeN(psys->frand);
|
||||
psys_create_frand(psys);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -423,7 +372,7 @@ void free_keyed_keys(ParticleSystem *psys)
|
||||
}
|
||||
}
|
||||
}
|
||||
void free_child_path_cache(ParticleSystem *psys)
|
||||
static void free_child_path_cache(ParticleSystem *psys)
|
||||
{
|
||||
psys_free_path_cache_buffers(psys->childcache, &psys->childcachebufs);
|
||||
psys->childcache = NULL;
|
||||
@@ -477,6 +426,24 @@ void psys_free_particles(ParticleSystem *psys)
|
||||
psys->totpart= 0;
|
||||
}
|
||||
}
|
||||
void psys_free_pdd(ParticleSystem *psys)
|
||||
{
|
||||
if(psys->pdd->cdata)
|
||||
MEM_freeN(psys->pdd->cdata);
|
||||
psys->pdd->cdata = NULL;
|
||||
|
||||
if(psys->pdd->vdata)
|
||||
MEM_freeN(psys->pdd->vdata);
|
||||
psys->pdd->vdata = NULL;
|
||||
|
||||
if(psys->pdd->ndata)
|
||||
MEM_freeN(psys->pdd->ndata);
|
||||
psys->pdd->ndata = NULL;
|
||||
|
||||
if(psys->pdd->vedata)
|
||||
MEM_freeN(psys->pdd->vedata);
|
||||
psys->pdd->vedata = NULL;
|
||||
}
|
||||
/* free everything */
|
||||
void psys_free(Object *ob, ParticleSystem * psys)
|
||||
{
|
||||
@@ -530,6 +497,14 @@ void psys_free(Object *ob, ParticleSystem * psys)
|
||||
|
||||
BLI_kdtree_free(psys->tree);
|
||||
|
||||
if(psys->frand)
|
||||
MEM_freeN(psys->frand);
|
||||
|
||||
if(psys->pdd) {
|
||||
psys_free_pdd(psys);
|
||||
MEM_freeN(psys->pdd);
|
||||
}
|
||||
|
||||
MEM_freeN(psys);
|
||||
}
|
||||
}
|
||||
@@ -721,12 +696,12 @@ void psys_render_restore(Object *ob, ParticleSystem *psys)
|
||||
int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot)
|
||||
{
|
||||
DerivedMesh *dm= ctx->dm;
|
||||
Mesh *me= (Mesh*)(ctx->ob->data);
|
||||
Mesh *me= (Mesh*)(ctx->sim.ob->data);
|
||||
MFace *mf, *mface;
|
||||
MVert *mvert;
|
||||
ParticleRenderData *data;
|
||||
ParticleRenderElem *elems, *elem;
|
||||
ParticleSettings *part= ctx->psys->part;
|
||||
ParticleSettings *part= ctx->sim.psys->part;
|
||||
float *facearea, (*facecenter)[3], size[3], fac, powrate, scaleclamp;
|
||||
float co1[3], co2[3], co3[3], co4[3], lambda, arearatio, t, area, viewport;
|
||||
double vprate;
|
||||
@@ -735,10 +710,10 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot)
|
||||
|
||||
if(part->ren_as!=PART_DRAW_PATH || !(part->draw & PART_DRAW_REN_STRAND))
|
||||
return tot;
|
||||
if(!ctx->psys->renderdata)
|
||||
if(!ctx->sim.psys->renderdata)
|
||||
return tot;
|
||||
|
||||
data= ctx->psys->renderdata;
|
||||
data= ctx->sim.psys->renderdata;
|
||||
if(data->timeoffset)
|
||||
return 0;
|
||||
if(!(part->simplify_flag & PART_SIMPLIFY_ENABLE))
|
||||
@@ -815,7 +790,7 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot)
|
||||
|
||||
/* set simplification parameters per original face */
|
||||
for(a=0, elem=elems; a<totorigface; a++, elem++) {
|
||||
area = psys_render_projected_area(ctx->psys, facecenter[a], facearea[a], vprate, &viewport);
|
||||
area = psys_render_projected_area(ctx->sim.psys, facecenter[a], facearea[a], vprate, &viewport);
|
||||
arearatio= fac*area/facearea[a];
|
||||
|
||||
if((arearatio < 1.0f || viewport < 1.0f) && elem->totchild) {
|
||||
@@ -1437,7 +1412,7 @@ void psys_interpolate_mcol(MCol *mcol, int quad, float *w, MCol *mc)
|
||||
}
|
||||
}
|
||||
|
||||
float psys_interpolate_value_from_verts(DerivedMesh *dm, short from, int index, float *fw, float *values)
|
||||
static float psys_interpolate_value_from_verts(DerivedMesh *dm, short from, int index, float *fw, float *values)
|
||||
{
|
||||
if(values==0 || index==-1)
|
||||
return 0.0;
|
||||
@@ -2074,7 +2049,7 @@ static void do_rough_end(float *loc, float mat[4][4], float t, float fac, float
|
||||
VECADDFAC(state->co,state->co,mat[0],rough[0]);
|
||||
VECADDFAC(state->co,state->co,mat[1],rough[1]);
|
||||
}
|
||||
static void do_path_effectors(Scene *scene, Object *ob, ParticleSystem *psys, int i, ParticleCacheKey *ca, int k, int steps, float *rootco, float effector, float dfra, float cfra, float *length, float *vec)
|
||||
static void do_path_effectors(ParticleSimulationData *sim, int i, ParticleCacheKey *ca, int k, int steps, float *rootco, float effector, float dfra, float cfra, float *length, float *vec)
|
||||
{
|
||||
float force[3] = {0.0f,0.0f,0.0f}, vel[3] = {0.0f,0.0f,0.0f};
|
||||
ParticleKey eff_key;
|
||||
@@ -2084,10 +2059,10 @@ static void do_path_effectors(Scene *scene, Object *ob, ParticleSystem *psys, in
|
||||
VECCOPY(eff_key.vel,(ca-1)->vel);
|
||||
QUATCOPY(eff_key.rot,(ca-1)->rot);
|
||||
|
||||
pa= psys->particles+i;
|
||||
do_effectors(i, pa, &eff_key, scene, ob, psys, rootco, force, vel, dfra, cfra);
|
||||
pa= sim->psys->particles+i;
|
||||
do_effectors(sim, i, pa, &eff_key, rootco, force, vel, dfra, cfra);
|
||||
|
||||
VecMulf(force, effector*pow((float)k / (float)steps, 100.0f * psys->part->eff_hair) / (float)steps);
|
||||
VecMulf(force, effector*pow((float)k / (float)steps, 100.0f * sim->psys->part->eff_hair) / (float)steps);
|
||||
|
||||
VecAddf(force, force, vec);
|
||||
|
||||
@@ -2154,12 +2129,12 @@ float *psys_cache_vgroup(DerivedMesh *dm, ParticleSystem *psys, int vgroup)
|
||||
}
|
||||
return vg;
|
||||
}
|
||||
void psys_find_parents(Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys)
|
||||
void psys_find_parents(ParticleSimulationData *sim)
|
||||
{
|
||||
ParticleSettings *part=psys->part;
|
||||
ParticleSettings *part=sim->psys->part;
|
||||
KDTree *tree;
|
||||
ChildParticle *cpa;
|
||||
int p, totparent,totchild=psys->totchild;
|
||||
int p, totparent,totchild=sim->psys->totchild;
|
||||
float co[3], orco[3];
|
||||
int from=PART_FROM_FACE;
|
||||
totparent=(int)(totchild*part->parents*0.3);
|
||||
@@ -2169,15 +2144,15 @@ void psys_find_parents(Object *ob, ParticleSystemModifierData *psmd, ParticleSys
|
||||
|
||||
tree=BLI_kdtree_new(totparent);
|
||||
|
||||
for(p=0,cpa=psys->child; p<totparent; p++,cpa++){
|
||||
psys_particle_on_emitter(psmd,from,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,0,0,0,orco,0);
|
||||
for(p=0,cpa=sim->psys->child; p<totparent; p++,cpa++){
|
||||
psys_particle_on_emitter(sim->psmd,from,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,0,0,0,orco,0);
|
||||
BLI_kdtree_insert(tree, p, orco, NULL);
|
||||
}
|
||||
|
||||
BLI_kdtree_balance(tree);
|
||||
|
||||
for(; p<totchild; p++,cpa++){
|
||||
psys_particle_on_emitter(psmd,from,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,0,0,0,orco,0);
|
||||
psys_particle_on_emitter(sim->psmd,from,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,0,0,0,orco,0);
|
||||
cpa->parent=BLI_kdtree_find_nearest(tree, orco, NULL, NULL);
|
||||
}
|
||||
|
||||
@@ -2215,11 +2190,11 @@ static void get_strand_normal(Material *ma, float *surfnor, float surfdist, floa
|
||||
VECCOPY(nor, vnor);
|
||||
}
|
||||
|
||||
int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, int editupdate)
|
||||
static int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, int editupdate)
|
||||
{
|
||||
ParticleThreadContext *ctx= threads[0].ctx;
|
||||
Object *ob= ctx->ob;
|
||||
ParticleSystem *psys= ctx->psys;
|
||||
Object *ob= ctx->sim.ob;
|
||||
ParticleSystem *psys= ctx->sim.psys;
|
||||
ParticleSettings *part = psys->part;
|
||||
ParticleEditSettings *pset = &scene->toolsettings->particle;
|
||||
int totparent=0, between=0;
|
||||
@@ -2252,10 +2227,10 @@ int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, in
|
||||
if(totchild==0) return 0;
|
||||
|
||||
/* init random number generator */
|
||||
if(ctx->psys->part->flag & PART_ANIM_BRANCHING)
|
||||
seed= 31415926 + ctx->psys->seed + (int)cfra;
|
||||
if(ctx->sim.psys->part->flag & PART_ANIM_BRANCHING)
|
||||
seed= 31415926 + ctx->sim.psys->seed + (int)cfra;
|
||||
else
|
||||
seed= 31415926 + ctx->psys->seed;
|
||||
seed= 31415926 + ctx->sim.psys->seed;
|
||||
|
||||
if(part->flag & PART_BRANCHING || ctx->editupdate || totchild < 10000)
|
||||
totthread= 1;
|
||||
@@ -2273,7 +2248,7 @@ int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, in
|
||||
ctx->parent_pass= 0;
|
||||
ctx->cfra= cfra;
|
||||
|
||||
psys->lattice = psys_get_lattice(scene, ob, psys);
|
||||
psys->lattice = psys_get_lattice(&ctx->sim);
|
||||
|
||||
/* cache all relevant vertex groups if they exist */
|
||||
if(part->from!=PART_FROM_PARTICLE){
|
||||
@@ -2299,11 +2274,11 @@ int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, in
|
||||
}
|
||||
|
||||
/* note: this function must be thread safe, except for branching! */
|
||||
void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, ParticleCacheKey *keys, int i)
|
||||
static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, ParticleCacheKey *keys, int i)
|
||||
{
|
||||
ParticleThreadContext *ctx= thread->ctx;
|
||||
Object *ob= ctx->ob;
|
||||
ParticleSystem *psys = ctx->psys;
|
||||
Object *ob= ctx->sim.ob;
|
||||
ParticleSystem *psys = ctx->sim.psys;
|
||||
ParticleSettings *part = psys->part;
|
||||
ParticleCacheKey **cache= psys->childcache;
|
||||
ParticleCacheKey **pcache= psys->pathcache;
|
||||
@@ -2372,7 +2347,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
|
||||
cpa_fuv = cpa->fuv;
|
||||
cpa_from = PART_FROM_FACE;
|
||||
|
||||
psys_particle_on_emitter(ctx->psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa->fuv,foffset,co,ornor,0,0,orco,0);
|
||||
psys_particle_on_emitter(ctx->sim.psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa->fuv,foffset,co,ornor,0,0,orco,0);
|
||||
|
||||
if(part->path_start==0.0f) {
|
||||
/* we need to save the actual root position of the child for positioning it accurately to the surface of the emitter */
|
||||
@@ -2382,7 +2357,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
|
||||
|
||||
pa = psys->particles + cpa->parent;
|
||||
|
||||
psys_mat_hair_to_global(ob, ctx->psmd->dm, psys->part->from, pa, hairmat);
|
||||
psys_mat_hair_to_global(ob, ctx->sim.psmd->dm, psys->part->from, pa, hairmat);
|
||||
|
||||
pa=0;
|
||||
}
|
||||
@@ -2404,9 +2379,9 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
|
||||
cpa_num=pa->num;
|
||||
cpa_fuv=pa->fuv;
|
||||
|
||||
psys_particle_on_emitter(ctx->psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa_fuv,pa->foffset,co,ornor,0,0,orco,0);
|
||||
psys_particle_on_emitter(ctx->sim.psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa_fuv,pa->foffset,co,ornor,0,0,orco,0);
|
||||
|
||||
psys_mat_hair_to_global(ob, ctx->psmd->dm, psys->part->from, pa, hairmat);
|
||||
psys_mat_hair_to_global(ob, ctx->sim.psmd->dm, psys->part->from, pa, hairmat);
|
||||
}
|
||||
|
||||
keys->steps = ctx->steps;
|
||||
@@ -2423,7 +2398,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
|
||||
/* get different child parameters from textures & vgroups */
|
||||
get_child_modifier_parameters(part, ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex);
|
||||
|
||||
if(ptex.exist < cpa->rand[1]) {
|
||||
if(ptex.exist < PSYS_FRAND(i + 24)) {
|
||||
keys->steps = -1;
|
||||
return;
|
||||
}
|
||||
@@ -2472,7 +2447,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
|
||||
if(part->flag & PART_CHILD_EFFECT) {
|
||||
for(k=0,state=keys; k<=ctx->steps; k++,state++) {
|
||||
if(k) {
|
||||
do_path_effectors(ctx->scene, ob, psys, cpa->pa[0], state, k, ctx->steps, keys->co, ptex.effector, 0.0f, ctx->cfra, &eff_length, eff_vec);
|
||||
do_path_effectors(&ctx->sim, cpa->pa[0], state, k, ctx->steps, keys->co, ptex.effector, 0.0f, ctx->cfra, &eff_length, eff_vec);
|
||||
}
|
||||
else {
|
||||
VecSubf(eff_vec,(state+1)->co,state->co);
|
||||
@@ -2498,7 +2473,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
|
||||
}
|
||||
|
||||
/* apply different deformations to the child path */
|
||||
do_child_modifiers(ctx->scene, ob, psys, part, &ptex, (ParticleKey *)par, par_rot, cpa, orco, hairmat, (ParticleKey *)state, t);
|
||||
do_child_modifiers(&ctx->sim, &ptex, (ParticleKey *)par, par_rot, cpa, orco, hairmat, (ParticleKey *)state, t);
|
||||
|
||||
/* TODO: better branching */
|
||||
//if(part->flag & PART_BRANCHING && ctx->between == 0 && part->flag & PART_ANIM_BRANCHING)
|
||||
@@ -2575,7 +2550,7 @@ static void *exec_child_path_cache(void *data)
|
||||
{
|
||||
ParticleThread *thread= (ParticleThread*)data;
|
||||
ParticleThreadContext *ctx= thread->ctx;
|
||||
ParticleSystem *psys= ctx->psys;
|
||||
ParticleSystem *psys= ctx->sim.psys;
|
||||
ParticleCacheKey **cache= psys->childcache;
|
||||
ChildParticle *cpa;
|
||||
int i, totchild= ctx->totchild, first= 0;
|
||||
@@ -2592,21 +2567,21 @@ static void *exec_child_path_cache(void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void psys_cache_child_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra, int editupdate)
|
||||
void psys_cache_child_paths(ParticleSimulationData *sim, float cfra, int editupdate)
|
||||
{
|
||||
ParticleSettings *part = psys->part;
|
||||
ParticleSettings *part = sim->psys->part;
|
||||
ParticleThread *pthreads;
|
||||
ParticleThreadContext *ctx;
|
||||
ParticleCacheKey **cache;
|
||||
ListBase threads;
|
||||
int i, totchild, totparent, totthread;
|
||||
|
||||
if(psys->flag & PSYS_GLOBAL_HAIR)
|
||||
if(sim->psys->flag & PSYS_GLOBAL_HAIR)
|
||||
return;
|
||||
|
||||
pthreads= psys_threads_create(scene, ob, psys);
|
||||
pthreads= psys_threads_create(sim);
|
||||
|
||||
if(!psys_threads_init_path(pthreads, scene, cfra, editupdate)) {
|
||||
if(!psys_threads_init_path(pthreads, sim->scene, cfra, editupdate)) {
|
||||
psys_threads_free(pthreads);
|
||||
return;
|
||||
}
|
||||
@@ -2615,14 +2590,14 @@ void psys_cache_child_paths(Scene *scene, Object *ob, ParticleSystem *psys, floa
|
||||
totchild= ctx->totchild;
|
||||
totparent= ctx->totparent;
|
||||
|
||||
if(editupdate && psys->childcache && !(part->flag & PART_BRANCHING) && totchild == psys->totchildcache) {
|
||||
cache = psys->childcache;
|
||||
if(editupdate && sim->psys->childcache && !(part->flag & PART_BRANCHING) && totchild == sim->psys->totchildcache) {
|
||||
cache = sim->psys->childcache;
|
||||
}
|
||||
else {
|
||||
/* clear out old and create new empty path cache */
|
||||
free_child_path_cache(psys);
|
||||
psys->childcache= psys_alloc_path_cache_buffers(&psys->childcachebufs, totchild, ctx->steps+1);
|
||||
psys->totchildcache = totchild;
|
||||
free_child_path_cache(sim->psys);
|
||||
sim->psys->childcache= psys_alloc_path_cache_buffers(&sim->psys->childcachebufs, totchild, ctx->steps+1);
|
||||
sim->psys->totchildcache = totchild;
|
||||
}
|
||||
|
||||
totthread= pthreads[0].tot;
|
||||
@@ -2660,27 +2635,29 @@ void psys_cache_child_paths(Scene *scene, Object *ob, ParticleSystem *psys, floa
|
||||
/* -Usefull for making use of opengl vertex arrays for super fast strand drawing. */
|
||||
/* -Makes child strands possible and creates them too into the cache. */
|
||||
/* -Cached path data is also used to determine cut position for the editmode tool. */
|
||||
void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra)
|
||||
void psys_cache_paths(ParticleSimulationData *sim, float cfra)
|
||||
{
|
||||
ParticleCacheKey *ca, **cache= psys->pathcache;
|
||||
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
|
||||
PARTICLE_PSMD;
|
||||
ParticleEditSettings *pset = &sim->scene->toolsettings->particle;
|
||||
ParticleSystem *psys = sim->psys;
|
||||
ParticleSettings *part = psys->part;
|
||||
ParticleEditSettings *pset = &scene->toolsettings->particle;
|
||||
ParticleCacheKey *ca, **cache= psys->pathcache;
|
||||
|
||||
DerivedMesh *hair_dm = psys->hair_out_dm;
|
||||
|
||||
ParticleData *pa = psys->particles;
|
||||
ParticleKey result;
|
||||
|
||||
Material *ma;
|
||||
ParticleInterpolationData pind;
|
||||
|
||||
PARTICLE_P;
|
||||
|
||||
float birthtime = 0.0, dietime = 0.0;
|
||||
float t, time = 0.0, dfra = 1.0, frs_sec = scene->r.frs_sec;
|
||||
float t, time = 0.0, dfra = 1.0, frs_sec = sim->scene->r.frs_sec;
|
||||
float col[4] = {0.5f, 0.5f, 0.5f, 1.0f};
|
||||
float prev_tangent[3], hairmat[4][4];
|
||||
float rotmat[3][3];
|
||||
int k,i;
|
||||
int k;
|
||||
int steps = (int)pow(2.0, (double)(psys->renderdata ? part->ren_step : part->draw_step));
|
||||
int totpart = psys->totpart;
|
||||
float length, vec[3];
|
||||
@@ -2692,7 +2669,7 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
|
||||
if((psys->flag & PSYS_HAIR_DONE || psys->flag & PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED)==0)
|
||||
return;
|
||||
|
||||
if(psys_in_edit_mode(scene, psys))
|
||||
if(psys_in_edit_mode(sim->scene, psys))
|
||||
if(psys->renderdata==0 && (psys->edit==NULL || pset->flag & PE_DRAW_PART)==0)
|
||||
return;
|
||||
|
||||
@@ -2705,8 +2682,8 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
|
||||
psys_free_path_cache(psys, psys->edit);
|
||||
cache= psys->pathcache= psys_alloc_path_cache_buffers(&psys->pathcachebufs, totpart, steps+1);
|
||||
|
||||
psys->lattice = psys_get_lattice(scene, ob, psys);
|
||||
ma= give_current_material(ob, psys->part->omat);
|
||||
psys->lattice = psys_get_lattice(sim);
|
||||
ma= give_current_material(sim->ob, psys->part->omat);
|
||||
if(ma && (psys->part->draw & PART_DRAW_MAT_COL))
|
||||
VECCOPY(col, &ma->r)
|
||||
|
||||
@@ -2719,12 +2696,9 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
|
||||
}
|
||||
|
||||
/*---first main loop: create all actual particles' paths---*/
|
||||
for(i=0; i<totpart; i++, pa++){
|
||||
if(pa->flag & PARS_NO_DISP || pa->flag & PARS_UNEXIST)
|
||||
continue;
|
||||
|
||||
LOOP_SHOWN_PARTICLES {
|
||||
if(!psys->totchild) {
|
||||
BLI_srandom(psys->seed + i);
|
||||
BLI_srandom(psys->seed + p);
|
||||
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);
|
||||
@@ -2736,15 +2710,15 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
|
||||
pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE);
|
||||
pind.dm = hair_dm;
|
||||
|
||||
memset(cache[i], 0, sizeof(*cache[i])*(steps+1));
|
||||
memset(cache[p], 0, sizeof(*cache[p])*(steps+1));
|
||||
|
||||
cache[i]->steps = steps;
|
||||
cache[p]->steps = steps;
|
||||
|
||||
/*--get the first data points--*/
|
||||
init_particle_interpolation(ob, psys, pa, &pind);
|
||||
init_particle_interpolation(sim->ob, sim->psys, pa, &pind);
|
||||
|
||||
/* hairmat is needed for for non-hair particle too so we get proper rotations */
|
||||
psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
|
||||
psys_mat_hair_to_global(sim->ob, psmd->dm, psys->part->from, pa, hairmat);
|
||||
VECCOPY(rotmat[0], hairmat[2]);
|
||||
VECCOPY(rotmat[1], hairmat[1]);
|
||||
VECCOPY(rotmat[2], hairmat[0]);
|
||||
@@ -2760,26 +2734,26 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
|
||||
}
|
||||
|
||||
if(birthtime >= dietime) {
|
||||
cache[i]->steps = -1;
|
||||
cache[p]->steps = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
dietime = birthtime + pa_length * (dietime - birthtime);
|
||||
|
||||
/*--interpolate actual path from data points--*/
|
||||
for(k=0, ca=cache[i]; k<=steps; k++, ca++){
|
||||
for(k=0, ca=cache[p]; k<=steps; k++, ca++){
|
||||
time = (float)k / (float)steps;
|
||||
|
||||
t = birthtime + time * (dietime - birthtime);
|
||||
|
||||
result.time = -t;
|
||||
|
||||
do_particle_interpolation(psys, i, pa, t, frs_sec, &pind, &result);
|
||||
do_particle_interpolation(psys, p, pa, t, frs_sec, &pind, &result);
|
||||
|
||||
/* dynamic hair is in object space */
|
||||
/* keyed and baked are allready in global space */
|
||||
if(hair_dm)
|
||||
Mat4MulVecfl(ob->obmat, result.co);
|
||||
Mat4MulVecfl(sim->ob->obmat, result.co);
|
||||
else if(!keyed && !baked && !(psys->flag & PSYS_GLOBAL_HAIR))
|
||||
Mat4MulVecfl(hairmat, result.co);
|
||||
|
||||
@@ -2789,23 +2763,23 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra
|
||||
|
||||
/*--modify paths and calculate rotation & velocity--*/
|
||||
|
||||
VecSubf(vec,(cache[i]+1)->co,cache[i]->co);
|
||||
VecSubf(vec,(cache[p]+1)->co,cache[p]->co);
|
||||
length = VecLength(vec);
|
||||
|
||||
effector= 1.0f;
|
||||
if(vg_effector)
|
||||
effector*= psys_particle_value_from_verts(psmd->dm,psys->part->from,pa,vg_effector);
|
||||
|
||||
for(k=0, ca=cache[i]; k<=steps; k++, ca++) {
|
||||
for(k=0, ca=cache[p]; k<=steps; k++, ca++) {
|
||||
if(!(psys->flag & PSYS_GLOBAL_HAIR)) {
|
||||
/* apply effectors */
|
||||
if(!(psys->part->flag & PART_CHILD_EFFECT) && k)
|
||||
do_path_effectors(scene, ob, psys, i, ca, k, steps, cache[i]->co, effector, dfra, cfra, &length, vec);
|
||||
do_path_effectors(sim, p, ca, k, steps, cache[p]->co, effector, dfra, cfra, &length, vec);
|
||||
|
||||
/* apply guide curves to path data */
|
||||
if(psys->effectors.first && (psys->part->flag & PART_CHILD_EFFECT)==0)
|
||||
/* ca is safe to cast, since only co and vel are used */
|
||||
do_guide(scene, (ParticleKey*)ca, i, (float)k/(float)steps, &psys->effectors);
|
||||
do_guide(sim->scene, (ParticleKey*)ca, p, (float)k/(float)steps, &psys->effectors);
|
||||
|
||||
/* apply lattice */
|
||||
if(psys->lattice)
|
||||
@@ -3021,23 +2995,6 @@ void psys_get_from_key(ParticleKey *key, float *loc, float *vel, float *rot, flo
|
||||
if(time) *time=key->time;
|
||||
}
|
||||
/*-------changing particle keys from space to another-------*/
|
||||
void psys_key_to_object(Object *ob, ParticleKey *key, float imat[][4]){
|
||||
float q[4], imat2[4][4];
|
||||
|
||||
if(imat==0){
|
||||
Mat4Invert(imat2,ob->obmat);
|
||||
imat=imat2;
|
||||
}
|
||||
|
||||
VECADD(key->vel,key->vel,key->co);
|
||||
|
||||
Mat4MulVecfl(imat,key->co);
|
||||
Mat4MulVecfl(imat,key->vel);
|
||||
Mat4ToQuat(imat,q);
|
||||
|
||||
VECSUB(key->vel,key->vel,key->co);
|
||||
QuatMul(key->rot,q,key->rot);
|
||||
}
|
||||
#if 0
|
||||
static void key_from_object(Object *ob, ParticleKey *key){
|
||||
float q[4];
|
||||
@@ -3410,41 +3367,6 @@ void psys_flush_particle_settings(Scene *scene, ParticleSettings *part, int reca
|
||||
}
|
||||
}
|
||||
|
||||
LinkNode *psys_using_settings(struct Scene *scene, ParticleSettings *part, int flush_update)
|
||||
{
|
||||
Object *ob, *tob;
|
||||
ParticleSystem *psys, *tpsys;
|
||||
LinkNode *node= NULL;
|
||||
int found;
|
||||
|
||||
/* update all that have same particle settings */
|
||||
for(ob=G.main->object.first; ob; ob=ob->id.next) {
|
||||
found= 0;
|
||||
|
||||
for(psys=ob->particlesystem.first; psys; psys=psys->next) {
|
||||
if(psys->part == part) {
|
||||
BLI_linklist_append(&node, psys);
|
||||
found++;
|
||||
}
|
||||
else if(psys->part->type == PART_REACTOR){
|
||||
tob= (psys->target_ob)? psys->target_ob: ob;
|
||||
tpsys= BLI_findlink(&tob->particlesystem, psys->target_psys-1);
|
||||
|
||||
if(tpsys && tpsys->part==part) {
|
||||
BLI_linklist_append(&node, tpsys);
|
||||
found++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(flush_update && found)
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
/************************************************/
|
||||
/* Textures */
|
||||
/************************************************/
|
||||
@@ -3541,7 +3463,7 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float
|
||||
}
|
||||
if(event & MAP_PA_DENS) { CLAMP(ptex->exist,0.0,1.0); }
|
||||
}
|
||||
void psys_get_texture(Object *ob, Material *ma, ParticleSystemModifierData *psmd, ParticleSystem *psys, ParticleData *pa, ParticleTexture *ptex, int event)
|
||||
void psys_get_texture(ParticleSimulationData *sim, Material *ma, ParticleData *pa, ParticleTexture *ptex, int event)
|
||||
{
|
||||
MTex *mtex;
|
||||
int m;
|
||||
@@ -3556,14 +3478,14 @@ void psys_get_texture(Object *ob, Material *ma, ParticleSystemModifierData *psmd
|
||||
short blend=mtex->blendtype;
|
||||
short neg=mtex->pmaptoneg;
|
||||
|
||||
if((mtex->texco & TEXCO_UV) && ELEM(psys->part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
|
||||
if(!get_particle_uv(psmd->dm, pa, 0, pa->fuv, mtex->uvname, texco)) {
|
||||
if((mtex->texco & TEXCO_UV) && ELEM(sim->psys->part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
|
||||
if(!get_particle_uv(sim->psmd->dm, pa, 0, pa->fuv, mtex->uvname, texco)) {
|
||||
/* failed to get uv's, let's try orco's */
|
||||
psys_particle_on_emitter(psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texco, 0);
|
||||
psys_particle_on_emitter(sim->psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texco, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
psys_particle_on_emitter(psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texco, 0);
|
||||
psys_particle_on_emitter(sim->psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texco, 0);
|
||||
}
|
||||
|
||||
externtex(mtex, texco, &value, rgba, rgba+1, rgba+2, rgba+3);
|
||||
@@ -3608,38 +3530,9 @@ void psys_get_texture(Object *ob, Material *ma, ParticleSystemModifierData *psmd
|
||||
/************************************************/
|
||||
/* Particle State */
|
||||
/************************************************/
|
||||
float psys_get_timestep(ParticleSettings *part)
|
||||
float psys_get_timestep(ParticleSimulationData *sim)
|
||||
{
|
||||
return 0.04f*part->timetweak;
|
||||
}
|
||||
/* part->size should be updated with possible ipo effection before this is called */
|
||||
float psys_get_size(Object *ob, Material *ma, ParticleSystemModifierData *psmd, IpoCurve *icu_size, ParticleSystem *psys, ParticleSettings *part, ParticleData *pa, float *vg_size)
|
||||
{
|
||||
ParticleTexture ptex;
|
||||
float size=1.0f;
|
||||
|
||||
BLI_srandom(psys->seed + (pa - psys->particles) + 100);
|
||||
|
||||
if(ma && part->from!=PART_FROM_PARTICLE){
|
||||
ptex.size=size;
|
||||
psys_get_texture(ob,ma,psmd,psys,pa,&ptex,MAP_PA_SIZE);
|
||||
size=ptex.size;
|
||||
}
|
||||
|
||||
#if 0 // XXX old animation system
|
||||
if(icu_size){
|
||||
calc_icu(icu_size,pa->time);
|
||||
size*=icu_size->curval;
|
||||
}
|
||||
#endif // XXX old animation system
|
||||
|
||||
if(vg_size)
|
||||
size*=psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_size);
|
||||
|
||||
if(part->randsize!=0.0)
|
||||
size*= 1.0f - part->randsize * BLI_frand();
|
||||
|
||||
return size*part->size;
|
||||
return 0.04f * sim->psys->part->timetweak;
|
||||
}
|
||||
float psys_get_child_time(ParticleSystem *psys, ChildParticle *cpa, float cfra, float *birthtime, float *dietime)
|
||||
{
|
||||
@@ -3654,7 +3547,7 @@ float psys_get_child_time(ParticleSystem *psys, ChildParticle *cpa, float cfra,
|
||||
w++;
|
||||
}
|
||||
|
||||
life = part->lifetime*(1.0f-part->randlife*cpa->rand[1]);
|
||||
life = part->lifetime * (1.0f - part->randlife * PSYS_FRAND(cpa - psys->child + 25));
|
||||
}
|
||||
else{
|
||||
ParticleData *pa = psys->particles + cpa->parent;
|
||||
@@ -3703,13 +3596,16 @@ float psys_get_child_size(ParticleSystem *psys, ChildParticle *cpa, float cfra,
|
||||
size*=part->childsize;
|
||||
|
||||
if(part->childrandsize!=0.0)
|
||||
size *= 1.0f - part->childrandsize*cpa->rand[2];
|
||||
size *= 1.0f - part->childrandsize * PSYS_FRAND(cpa - psys->child + 26);
|
||||
|
||||
return size;
|
||||
}
|
||||
static void get_child_modifier_parameters(ParticleSettings *part, ParticleThreadContext *ctx, ChildParticle *cpa, short cpa_from, int cpa_num, float *cpa_fuv, float *orco, ParticleTexture *ptex)
|
||||
{
|
||||
ptex->length= 1.0f - part->randlength*cpa->rand[0];
|
||||
ParticleSystem *psys = ctx->sim.psys;
|
||||
int i = cpa - psys->child;
|
||||
|
||||
ptex->length= 1.0f - part->randlength * PSYS_FRAND(i + 26);
|
||||
ptex->clump=1.0;
|
||||
ptex->kink=1.0;
|
||||
ptex->rough1= 1.0;
|
||||
@@ -3718,13 +3614,13 @@ static void get_child_modifier_parameters(ParticleSettings *part, ParticleThread
|
||||
ptex->exist= 1.0;
|
||||
ptex->effector= 1.0;
|
||||
|
||||
ptex->length*= part->clength_thres < cpa->rand[1] ? part->clength : 1.0f;
|
||||
ptex->length*= part->clength_thres < PSYS_FRAND(i + 27) ? part->clength : 1.0f;
|
||||
|
||||
get_cpa_texture(ctx->dm,ctx->ma,cpa_num,cpa_fuv,orco,ptex,
|
||||
MAP_PA_DENS|MAP_PA_LENGTH|MAP_PA_CLUMP|MAP_PA_KINK|MAP_PA_ROUGH);
|
||||
|
||||
|
||||
if(ptex->exist < cpa->rand[1])
|
||||
if(ptex->exist < PSYS_FRAND(i + 24))
|
||||
return;
|
||||
|
||||
if(ctx->vg_length)
|
||||
@@ -3742,18 +3638,20 @@ static void get_child_modifier_parameters(ParticleSettings *part, ParticleThread
|
||||
if(ctx->vg_effector)
|
||||
ptex->effector*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_effector);
|
||||
}
|
||||
static void do_child_modifiers(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSettings *part, ParticleTexture *ptex, ParticleKey *par, float *par_rot, ChildParticle *cpa, float *orco, float mat[4][4], ParticleKey *state, float t)
|
||||
static void do_child_modifiers(ParticleSimulationData *sim, ParticleTexture *ptex, ParticleKey *par, float *par_rot, ChildParticle *cpa, float *orco, float mat[4][4], ParticleKey *state, float t)
|
||||
{
|
||||
ParticleSettings *part = sim->psys->part;
|
||||
int i = cpa - sim->psys->child;
|
||||
int guided = 0;
|
||||
|
||||
if(part->flag & PART_CHILD_EFFECT)
|
||||
/* state is safe to cast, since only co and vel are used */
|
||||
guided = do_guide(scene, (ParticleKey*)state, cpa->parent, t, &(psys->effectors));
|
||||
guided = do_guide(sim->scene, (ParticleKey*)state, cpa->parent, t, &(sim->psys->effectors));
|
||||
|
||||
if(guided==0){
|
||||
if(part->kink)
|
||||
do_prekink(state, par, par_rot, t, part->kink_freq * ptex->kink, part->kink_shape,
|
||||
part->kink_amp, part->kink, part->kink_axis, ob->obmat);
|
||||
part->kink_amp, part->kink, part->kink_axis, sim->ob->obmat);
|
||||
|
||||
do_clump(state, par, t, part->clumpfac, part->clumppow, ptex->clump);
|
||||
}
|
||||
@@ -3762,17 +3660,18 @@ static void do_child_modifiers(Scene *scene, Object *ob, ParticleSystem *psys, P
|
||||
do_rough(orco, mat, t, ptex->rough1*part->rough1, part->rough1_size, 0.0, state);
|
||||
|
||||
if(part->rough2 != 0.0 && ptex->rough2 != 0.0)
|
||||
do_rough(cpa->rand, mat, t, ptex->rough2*part->rough2, part->rough2_size, part->rough2_thres, state);
|
||||
do_rough(sim->psys->frand + ((i + 27) % (PSYS_FRAND_COUNT - 3)), mat, t, ptex->rough2*part->rough2, part->rough2_size, part->rough2_thres, state);
|
||||
|
||||
if(part->rough_end != 0.0 && ptex->roughe != 0.0)
|
||||
do_rough_end(cpa->rand, mat, t, ptex->roughe*part->rough_end, part->rough_end_shape, state);
|
||||
do_rough_end(sim->psys->frand + ((i + 27) % (PSYS_FRAND_COUNT - 3)), mat, t, ptex->roughe*part->rough_end, part->rough_end_shape, state);
|
||||
}
|
||||
/* get's hair (or keyed) particles state at the "path time" specified in state->time */
|
||||
void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, int p, ParticleKey *state, int vel)
|
||||
void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *state, int vel)
|
||||
{
|
||||
ParticleSettings *part = psys->part;
|
||||
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
|
||||
Material *ma = give_current_material(ob, part->omat);
|
||||
PARTICLE_PSMD;
|
||||
ParticleSystem *psys = sim->psys;
|
||||
ParticleSettings *part = sim->psys->part;
|
||||
Material *ma = give_current_material(sim->ob, part->omat);
|
||||
ParticleData *pa;
|
||||
ChildParticle *cpa;
|
||||
ParticleTexture ptex;
|
||||
@@ -3780,7 +3679,7 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
|
||||
ParticleThreadContext ctx; /* fake thread context for child modifiers */
|
||||
ParticleInterpolationData pind;
|
||||
|
||||
float t, frs_sec = scene->r.frs_sec;
|
||||
float t, frs_sec = sim->scene->r.frs_sec;
|
||||
float co[3], orco[3];
|
||||
float hairmat[4][4];
|
||||
int totparent = 0;
|
||||
@@ -3808,17 +3707,17 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
|
||||
pind.cache = cached ? psys->pointcache : NULL;
|
||||
pind.epoint = NULL;
|
||||
pind.dm = psys->hair_out_dm;
|
||||
init_particle_interpolation(ob, psys, pa, &pind);
|
||||
init_particle_interpolation(sim->ob, psys, pa, &pind);
|
||||
do_particle_interpolation(psys, p, pa, t, frs_sec, &pind, state);
|
||||
|
||||
if(!keyed && !cached) {
|
||||
if((pa->flag & PARS_REKEY)==0) {
|
||||
psys_mat_hair_to_global(ob, psmd->dm, part->from, pa, hairmat);
|
||||
psys_mat_hair_to_global(sim->ob, sim->psmd->dm, part->from, pa, hairmat);
|
||||
Mat4MulVecfl(hairmat, state->co);
|
||||
Mat4Mul3Vecfl(hairmat, state->vel);
|
||||
|
||||
if(psys->effectors.first && (part->flag & PART_CHILD_GUIDE)==0) {
|
||||
do_guide(scene, state, p, state->time, &psys->effectors);
|
||||
do_guide(sim->scene, state, p, state->time, &psys->effectors);
|
||||
/* TODO: proper velocity handling */
|
||||
}
|
||||
|
||||
@@ -3851,7 +3750,7 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
|
||||
/* get parent states */
|
||||
while(w<4 && cpa->pa[w]>=0){
|
||||
keys[w].time = state->time;
|
||||
psys_get_particle_on_path(scene, ob, psys, cpa->pa[w], keys+w, 1);
|
||||
psys_get_particle_on_path(sim, cpa->pa[w], keys+w, 1);
|
||||
w++;
|
||||
}
|
||||
|
||||
@@ -3871,14 +3770,14 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
|
||||
|
||||
pa = psys->particles + cpa->parent;
|
||||
|
||||
psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
|
||||
psys_mat_hair_to_global(sim->ob, sim->psmd->dm, psys->part->from, pa, hairmat);
|
||||
|
||||
pa=0;
|
||||
}
|
||||
else{
|
||||
/* get the parent state */
|
||||
keys->time = state->time;
|
||||
psys_get_particle_on_path(scene, ob, psys, cpa->parent, keys,1);
|
||||
psys_get_particle_on_path(sim, cpa->parent, keys,1);
|
||||
|
||||
/* get the original coordinates (orco) for texture usage */
|
||||
pa=psys->particles+cpa->parent;
|
||||
@@ -3889,7 +3788,7 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
|
||||
|
||||
psys_particle_on_emitter(psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa_fuv,pa->foffset,co,0,0,0,orco,0);
|
||||
|
||||
psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
|
||||
psys_mat_hair_to_global(sim->ob, sim->psmd->dm, psys->part->from, pa, hairmat);
|
||||
}
|
||||
|
||||
/* correct child ipo timing */
|
||||
@@ -3938,7 +3837,7 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
|
||||
copy_particle_key(&tstate, state, 1);
|
||||
|
||||
/* apply different deformations to the child path */
|
||||
do_child_modifiers(scene, ob, psys, part, &ptex, par, par->rot, cpa, orco, hairmat, state, t);
|
||||
do_child_modifiers(sim, &ptex, par, par->rot, cpa, orco, hairmat, state, t);
|
||||
|
||||
/* try to estimate correct velocity */
|
||||
if(vel){
|
||||
@@ -3947,13 +3846,13 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
|
||||
|
||||
if(t>=0.001f){
|
||||
tstate.time=t-0.001f;
|
||||
psys_get_particle_on_path(scene,ob,psys,p,&tstate,0);
|
||||
psys_get_particle_on_path(sim,p,&tstate,0);
|
||||
VECSUB(state->vel,state->co,tstate.co);
|
||||
Normalize(state->vel);
|
||||
}
|
||||
else{
|
||||
tstate.time=t+0.001f;
|
||||
psys_get_particle_on_path(scene, ob,psys,p,&tstate,0);
|
||||
psys_get_particle_on_path(sim,p,&tstate,0);
|
||||
VECSUB(state->vel,tstate.co,state->co);
|
||||
Normalize(state->vel);
|
||||
}
|
||||
@@ -3963,39 +3862,52 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i
|
||||
}
|
||||
}
|
||||
/* gets particle's state at a time, returns 1 if particle exists and can be seen and 0 if not */
|
||||
int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psys, int p, ParticleKey *state, int always){
|
||||
ParticleSettings *part=psys->part;
|
||||
ParticleData *pa=0;
|
||||
int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *state, int always){
|
||||
ParticleSystem *psys = sim->psys;
|
||||
ParticleSettings *part = psys->part;
|
||||
ParticleData *pa = NULL;
|
||||
ChildParticle *cpa = NULL;
|
||||
float cfra;
|
||||
int totpart=psys->totpart, between=0;
|
||||
int totpart = psys->totpart, between = 0;
|
||||
|
||||
/* negative time means "use current time" */
|
||||
if(state->time>0)
|
||||
cfra=state->time;
|
||||
else
|
||||
cfra= bsystem_time(scene, 0, (float)scene->r.cfra,0.0);
|
||||
cfra = state->time > 0 ? state->time : bsystem_time(sim->scene, 0, (float)sim->scene->r.cfra, 0.0);
|
||||
|
||||
if(psys->totchild && p>=totpart){
|
||||
if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
|
||||
between=1;
|
||||
}
|
||||
else
|
||||
pa=psys->particles+(psys->child+p-totpart)->parent;
|
||||
}
|
||||
else
|
||||
pa=psys->particles+p;
|
||||
if(p>=totpart){
|
||||
if(!psys->totchild)
|
||||
return 0;
|
||||
|
||||
if(between){
|
||||
state->time = psys_get_child_time(psys,&psys->child[p-totpart],cfra,NULL,NULL);
|
||||
|
||||
if(always==0)
|
||||
if((state->time<0.0 && (part->flag & PART_UNBORN)==0)
|
||||
|| (state->time>1.0 && (part->flag & PART_DIED)==0))
|
||||
if(part->from != PART_FROM_PARTICLE && part->childtype == PART_CHILD_FACES){
|
||||
if(!(psys->flag & PSYS_KEYED))
|
||||
return 0;
|
||||
|
||||
cpa = psys->child + p - totpart;
|
||||
|
||||
state->time = psys_get_child_time(psys, cpa, cfra, NULL, NULL);
|
||||
|
||||
if(!always)
|
||||
if((state->time < 0.0 && !(part->flag & PART_UNBORN))
|
||||
|| (state->time > 1.0 && !(part->flag & PART_DIED)))
|
||||
return 0;
|
||||
|
||||
state->time= (cfra - (part->sta + (part->end - part->sta) * PSYS_FRAND(p + 23))) / (part->lifetime * PSYS_FRAND(p + 24));
|
||||
|
||||
psys_get_particle_on_path(sim, p, state,1);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
cpa = sim->psys->child + p - totpart;
|
||||
pa = sim->psys->particles + cpa->parent;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(pa->alive==PARS_KILLED) return 0;
|
||||
if(always==0)
|
||||
else {
|
||||
pa = sim->psys->particles + p;
|
||||
}
|
||||
|
||||
if(pa) {
|
||||
if(pa->alive == PARS_KILLED) return 0;
|
||||
|
||||
if(!always)
|
||||
if((pa->alive==PARS_UNBORN && (part->flag & PART_UNBORN)==0)
|
||||
|| (pa->alive==PARS_DEAD && (part->flag & PART_DIED)==0))
|
||||
return 0;
|
||||
@@ -4003,38 +3915,28 @@ int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psy
|
||||
state->time = MIN2(state->time, pa->dietime);
|
||||
}
|
||||
|
||||
if(psys->flag & PSYS_KEYED){
|
||||
if(between){
|
||||
ChildParticle *cpa=psys->child+p-totpart;
|
||||
state->time= (cfra-(part->sta+(part->end-part->sta)*cpa->rand[0]))/(part->lifetime*cpa->rand[1]);
|
||||
}
|
||||
else
|
||||
state->time= -cfra;
|
||||
|
||||
psys_get_particle_on_path(scene, ob, psys, p, state,1);
|
||||
if(sim->psys->flag & PSYS_KEYED){
|
||||
state->time= -cfra;
|
||||
psys_get_particle_on_path(sim, p, state,1);
|
||||
return 1;
|
||||
}
|
||||
else{
|
||||
if(between)
|
||||
return 0; /* currently not supported */
|
||||
else if(psys->totchild && p>=psys->totpart){
|
||||
ChildParticle *cpa=psys->child+p-psys->totpart;
|
||||
if(cpa){
|
||||
ParticleKey *key1;
|
||||
float t = (cfra - pa->time + pa->loop * pa->lifetime) / pa->lifetime;
|
||||
|
||||
pa = psys->particles + cpa->parent;
|
||||
key1=&pa->state;
|
||||
offset_child(cpa, key1, state, part->childflat, part->childrad);
|
||||
|
||||
CLAMP(t,0.0,1.0);
|
||||
if(part->kink) /* TODO: part->kink_freq*pa_kink */
|
||||
do_prekink(state,key1,key1->rot,t,part->kink_freq,part->kink_shape,part->kink_amp,part->kink,part->kink_axis,ob->obmat);
|
||||
do_prekink(state,key1,key1->rot,t,part->kink_freq,part->kink_shape,part->kink_amp,part->kink,part->kink_axis,sim->ob->obmat);
|
||||
|
||||
/* TODO: pa_clump vgroup */
|
||||
do_clump(state,key1,t,part->clumpfac,part->clumppow,1.0);
|
||||
|
||||
if(psys->lattice)
|
||||
calc_latt_deform(psys->lattice, state->co,1.0f);
|
||||
calc_latt_deform(sim->psys->lattice, state->co,1.0f);
|
||||
}
|
||||
else{
|
||||
if(pa->state.time==state->time || ELEM(part->phystype,PART_PHYS_NO,PART_PHYS_KEYED))
|
||||
@@ -4045,7 +3947,7 @@ int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psy
|
||||
/* let's interpolate to try to be as accurate as possible */
|
||||
if(pa->state.time + 1.0f > state->time && pa->prev_state.time - 1.0f < state->time) {
|
||||
ParticleKey keys[4];
|
||||
float dfra, keytime, frs_sec = scene->r.frs_sec;
|
||||
float dfra, keytime, frs_sec = sim->scene->r.frs_sec;
|
||||
|
||||
if(pa->prev_state.time >= pa->state.time) {
|
||||
/* prev_state is wrong so let's not use it, this can happen at frame 1 or particle birth */
|
||||
@@ -4080,8 +3982,8 @@ int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psy
|
||||
}
|
||||
}
|
||||
|
||||
if(psys->lattice)
|
||||
calc_latt_deform(psys->lattice, state->co,1.0f);
|
||||
if(sim->psys->lattice)
|
||||
calc_latt_deform(sim->psys->lattice, state->co,1.0f);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -4137,8 +4039,11 @@ void psys_get_dupli_texture(Object *ob, ParticleSettings *part, ParticleSystemMo
|
||||
}
|
||||
}
|
||||
|
||||
void psys_get_dupli_path_transform(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, ParticleData *pa, ChildParticle *cpa, ParticleCacheKey *cache, float mat[][4], float *scale)
|
||||
void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa, ChildParticle *cpa, ParticleCacheKey *cache, float mat[][4], float *scale)
|
||||
{
|
||||
Object *ob = sim->ob;
|
||||
ParticleSystem *psys = sim->psys;
|
||||
ParticleSystemModifierData *psmd = sim->psmd;
|
||||
float loc[3], nor[3], vec[3], side[3], len, obrotmat[4][4], qmat[4][4];
|
||||
float xvec[3] = {-1.0, 0.0, 0.0}, q[4];
|
||||
|
||||
@@ -4146,7 +4051,7 @@ void psys_get_dupli_path_transform(Object *ob, ParticleSystem *psys, ParticleSys
|
||||
len= Normalize(vec);
|
||||
|
||||
if(pa)
|
||||
psys_particle_on_emitter(psmd,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,nor,0,0,0,0);
|
||||
psys_particle_on_emitter(psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,nor,0,0,0,0);
|
||||
else
|
||||
psys_particle_on_emitter(psmd,
|
||||
(psys->part->childtype == PART_CHILD_FACES)? PART_FROM_FACE: PART_FROM_PARTICLE,
|
||||
|
||||
@@ -164,20 +164,22 @@ void psys_reset(ParticleSystem *psys, int mode)
|
||||
psys->pointcache->simframe= 0;
|
||||
}
|
||||
|
||||
static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart)
|
||||
static void realloc_particles(ParticleSimulationData *sim, int new_totpart)
|
||||
{
|
||||
ParticleSystem *psys = sim->psys;
|
||||
ParticleSettings *part = psys->part;
|
||||
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) {
|
||||
totpart= psys->part->grid_res;
|
||||
if(part->distr==PART_DISTR_GRID && part->from != PART_FROM_VERT) {
|
||||
totpart= part->grid_res;
|
||||
totpart*=totpart*totpart;
|
||||
}
|
||||
else
|
||||
totpart=psys->part->totpart;
|
||||
totpart=part->totpart;
|
||||
}
|
||||
else
|
||||
totpart=new_totpart;
|
||||
@@ -212,6 +214,7 @@ static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart)
|
||||
if(pa->hair) MEM_freeN(pa->hair);
|
||||
|
||||
MEM_freeN(psys->particles);
|
||||
psys_free_pdd(psys);
|
||||
}
|
||||
|
||||
psys->particles=newpars;
|
||||
@@ -605,13 +608,13 @@ static int binary_search_distribution(float *sum, int n, float value)
|
||||
|
||||
/* note: this function must be thread safe, for from == PART_FROM_CHILD */
|
||||
#define ONLY_WORKING_WITH_PA_VERTS 0
|
||||
void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, ChildParticle *cpa, int p)
|
||||
static void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, ChildParticle *cpa, int p)
|
||||
{
|
||||
ParticleThreadContext *ctx= thread->ctx;
|
||||
Object *ob= ctx->ob;
|
||||
Object *ob= ctx->sim.ob;
|
||||
DerivedMesh *dm= ctx->dm;
|
||||
ParticleData *tpa;
|
||||
ParticleSettings *part= ctx->psys->part;
|
||||
ParticleSettings *part= ctx->sim.psys->part;
|
||||
float *v1, *v2, *v3, *v4, nor[3], orco1[3], co1[3], co2[3], nor1[3], ornor1[3];
|
||||
float cur_d, min_d, randu, randv;
|
||||
int from= ctx->from;
|
||||
@@ -624,7 +627,6 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
|
||||
pa->num= ctx->index[p];
|
||||
pa->fuv[0] = 1.0f;
|
||||
pa->fuv[1] = pa->fuv[2] = pa->fuv[3] = 0.0;
|
||||
//pa->verts[0] = pa->verts[1] = pa->verts[2] = 0;
|
||||
|
||||
#if ONLY_WORKING_WITH_PA_VERTS
|
||||
if(ctx->tree){
|
||||
@@ -652,7 +654,6 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
|
||||
ctx->jitoff[i] = fmod(ctx->jitoff[i],(float)ctx->jitlevel);
|
||||
psys_uv_to_w(ctx->jit[2*(int)ctx->jitoff[i]], ctx->jit[2*(int)ctx->jitoff[i]+1], mface->v4, pa->fuv);
|
||||
ctx->jitoff[i]++;
|
||||
//ctx->jitoff[i]=(float)fmod(ctx->jitoff[i]+ctx->maxweight/ctx->weight[i],(float)ctx->jitlevel);
|
||||
break;
|
||||
case PART_DISTR_RAND:
|
||||
randu= rng_getFloat(thread->rng);
|
||||
@@ -662,12 +663,6 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
|
||||
}
|
||||
pa->foffset= 0.0f;
|
||||
|
||||
/*
|
||||
pa->verts[0] = mface->v1;
|
||||
pa->verts[1] = mface->v2;
|
||||
pa->verts[2] = mface->v3;
|
||||
*/
|
||||
|
||||
/* experimental */
|
||||
if(from==PART_FROM_VOLUME){
|
||||
MVert *mvert=dm->getVertDataArray(dm,CD_MVERT);
|
||||
@@ -723,10 +718,6 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
|
||||
}
|
||||
}
|
||||
else if(from == PART_FROM_PARTICLE) {
|
||||
//pa->verts[0]=0; /* not applicable */
|
||||
//pa->verts[1]=0;
|
||||
//pa->verts[2]=0;
|
||||
|
||||
tpa=ctx->tpars+ctx->index[p];
|
||||
pa->num=ctx->index[p];
|
||||
pa->fuv[0]=tpa->fuv[0];
|
||||
@@ -742,42 +733,30 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
|
||||
cpa->num=0;
|
||||
cpa->fuv[0]=cpa->fuv[1]=cpa->fuv[2]=cpa->fuv[3]=0.0f;
|
||||
cpa->pa[0]=cpa->pa[1]=cpa->pa[2]=cpa->pa[3]=0;
|
||||
cpa->rand[0]=cpa->rand[1]=cpa->rand[2]=0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
mf= dm->getFaceData(dm, ctx->index[p], CD_MFACE);
|
||||
|
||||
//switch(distr){
|
||||
// case PART_DISTR_JIT:
|
||||
// i=index[p];
|
||||
// psys_uv_to_w(ctx->jit[2*(int)ctx->jitoff[i]], ctx->jit[2*(int)ctx->jitoff[i]+1], mf->v4, cpa->fuv);
|
||||
// ctx->jitoff[i]=(float)fmod(ctx->jitoff[i]+ctx->maxweight/ctx->weight[i],(float)ctx->jitlevel);
|
||||
// break;
|
||||
// case PART_DISTR_RAND:
|
||||
randu= rng_getFloat(thread->rng);
|
||||
randv= rng_getFloat(thread->rng);
|
||||
psys_uv_to_w(randu, randv, mf->v4, cpa->fuv);
|
||||
// break;
|
||||
//}
|
||||
randu= rng_getFloat(thread->rng);
|
||||
randv= rng_getFloat(thread->rng);
|
||||
psys_uv_to_w(randu, randv, mf->v4, cpa->fuv);
|
||||
|
||||
cpa->rand[0] = rng_getFloat(thread->rng);
|
||||
cpa->rand[1] = rng_getFloat(thread->rng);
|
||||
cpa->rand[2] = rng_getFloat(thread->rng);
|
||||
cpa->num = ctx->index[p];
|
||||
|
||||
if(ctx->tree){
|
||||
KDTreeNearest ptn[10];
|
||||
int w,maxw, do_seams;
|
||||
int w,maxw;//, do_seams;
|
||||
float maxd,mind,dd,totw=0.0;
|
||||
int parent[10];
|
||||
float pweight[10];
|
||||
|
||||
do_seams= (part->flag&PART_CHILD_SEAMS && ctx->seams);
|
||||
/*do_seams= (part->flag&PART_CHILD_SEAMS && ctx->seams);*/
|
||||
|
||||
psys_particle_on_dm(dm,cfrom,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co1,nor1,0,0,orco1,ornor1);
|
||||
transform_mesh_orco_verts((Mesh*)ob->data, &orco1, 1, 1);
|
||||
maxw = BLI_kdtree_find_n_nearest(ctx->tree,(do_seams)?10:4,orco1,ornor1,ptn);
|
||||
//maxw = BLI_kdtree_find_n_nearest(ctx->tree,(do_seams)?10:4,orco1,ornor1,ptn);
|
||||
maxw = BLI_kdtree_find_n_nearest(ctx->tree,4,orco1,ornor1,ptn);
|
||||
|
||||
maxd=ptn[maxw-1].dist;
|
||||
mind=ptn[0].dist;
|
||||
@@ -787,70 +766,68 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
|
||||
for(w=0; w<maxw; w++){
|
||||
parent[w]=ptn[w].index;
|
||||
pweight[w]=(float)pow(2.0,(double)(-6.0f*ptn[w].dist/maxd));
|
||||
//pweight[w]= (1.0f - ptn[w].dist*ptn[w].dist/(maxd*maxd));
|
||||
//pweight[w] *= pweight[w];
|
||||
}
|
||||
for(;w<10; w++){
|
||||
parent[w]=-1;
|
||||
pweight[w]=0.0f;
|
||||
}
|
||||
if(do_seams){
|
||||
ParticleSeam *seam=ctx->seams;
|
||||
float temp[3],temp2[3],tan[3];
|
||||
float inp,cur_len,min_len=10000.0f;
|
||||
int min_seam=0, near_vert=0;
|
||||
/* find closest seam */
|
||||
for(i=0; i<ctx->totseam; i++, seam++){
|
||||
VecSubf(temp,co1,seam->v0);
|
||||
inp=Inpf(temp,seam->dir)/seam->length2;
|
||||
if(inp<0.0f){
|
||||
cur_len=VecLenf(co1,seam->v0);
|
||||
}
|
||||
else if(inp>1.0f){
|
||||
cur_len=VecLenf(co1,seam->v1);
|
||||
}
|
||||
else{
|
||||
VecCopyf(temp2,seam->dir);
|
||||
VecMulf(temp2,inp);
|
||||
cur_len=VecLenf(temp,temp2);
|
||||
}
|
||||
if(cur_len<min_len){
|
||||
min_len=cur_len;
|
||||
min_seam=i;
|
||||
if(inp<0.0f) near_vert=-1;
|
||||
else if(inp>1.0f) near_vert=1;
|
||||
else near_vert=0;
|
||||
}
|
||||
}
|
||||
seam=ctx->seams+min_seam;
|
||||
|
||||
VecCopyf(temp,seam->v0);
|
||||
|
||||
if(near_vert){
|
||||
if(near_vert==-1)
|
||||
VecSubf(tan,co1,seam->v0);
|
||||
else{
|
||||
VecSubf(tan,co1,seam->v1);
|
||||
VecCopyf(temp,seam->v1);
|
||||
}
|
||||
//if(do_seams){
|
||||
// ParticleSeam *seam=ctx->seams;
|
||||
// float temp[3],temp2[3],tan[3];
|
||||
// float inp,cur_len,min_len=10000.0f;
|
||||
// int min_seam=0, near_vert=0;
|
||||
// /* find closest seam */
|
||||
// for(i=0; i<ctx->totseam; i++, seam++){
|
||||
// VecSubf(temp,co1,seam->v0);
|
||||
// inp=Inpf(temp,seam->dir)/seam->length2;
|
||||
// if(inp<0.0f){
|
||||
// cur_len=VecLenf(co1,seam->v0);
|
||||
// }
|
||||
// else if(inp>1.0f){
|
||||
// cur_len=VecLenf(co1,seam->v1);
|
||||
// }
|
||||
// else{
|
||||
// VecCopyf(temp2,seam->dir);
|
||||
// VecMulf(temp2,inp);
|
||||
// cur_len=VecLenf(temp,temp2);
|
||||
// }
|
||||
// if(cur_len<min_len){
|
||||
// min_len=cur_len;
|
||||
// min_seam=i;
|
||||
// if(inp<0.0f) near_vert=-1;
|
||||
// else if(inp>1.0f) near_vert=1;
|
||||
// else near_vert=0;
|
||||
// }
|
||||
// }
|
||||
// seam=ctx->seams+min_seam;
|
||||
//
|
||||
// VecCopyf(temp,seam->v0);
|
||||
//
|
||||
// if(near_vert){
|
||||
// if(near_vert==-1)
|
||||
// VecSubf(tan,co1,seam->v0);
|
||||
// else{
|
||||
// VecSubf(tan,co1,seam->v1);
|
||||
// VecCopyf(temp,seam->v1);
|
||||
// }
|
||||
|
||||
Normalize(tan);
|
||||
}
|
||||
else{
|
||||
VecCopyf(tan,seam->tan);
|
||||
VecSubf(temp2,co1,temp);
|
||||
if(Inpf(tan,temp2)<0.0f)
|
||||
VecNegf(tan);
|
||||
}
|
||||
for(w=0; w<maxw; w++){
|
||||
VecSubf(temp2,ptn[w].co,temp);
|
||||
if(Inpf(tan,temp2)<0.0f){
|
||||
parent[w]=-1;
|
||||
pweight[w]=0.0f;
|
||||
}
|
||||
}
|
||||
// Normalize(tan);
|
||||
// }
|
||||
// else{
|
||||
// VecCopyf(tan,seam->tan);
|
||||
// VecSubf(temp2,co1,temp);
|
||||
// if(Inpf(tan,temp2)<0.0f)
|
||||
// VecNegf(tan);
|
||||
// }
|
||||
// for(w=0; w<maxw; w++){
|
||||
// VecSubf(temp2,ptn[w].co,temp);
|
||||
// if(Inpf(tan,temp2)<0.0f){
|
||||
// parent[w]=-1;
|
||||
// pweight[w]=0.0f;
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
//}
|
||||
|
||||
for(w=0,i=0; w<maxw && i<4; w++){
|
||||
if(parent[w]>=0){
|
||||
@@ -876,7 +853,7 @@ void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, C
|
||||
static void *exec_distribution(void *data)
|
||||
{
|
||||
ParticleThread *thread= (ParticleThread*)data;
|
||||
ParticleSystem *psys= thread->ctx->psys;
|
||||
ParticleSystem *psys= thread->ctx->sim.psys;
|
||||
ParticleData *pa;
|
||||
ChildParticle *cpa;
|
||||
int p, totpart;
|
||||
@@ -943,11 +920,11 @@ static int compare_orig_index(const void *p1, const void *p2)
|
||||
/* 6. and we're done! */
|
||||
|
||||
/* This is to denote functionality that does not yet work with mesh - only derived mesh */
|
||||
int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, DerivedMesh *finaldm, int from)
|
||||
static int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, DerivedMesh *finaldm, int from)
|
||||
{
|
||||
ParticleThreadContext *ctx= threads[0].ctx;
|
||||
Object *ob= ctx->ob;
|
||||
ParticleSystem *psys= ctx->psys;
|
||||
Object *ob= ctx->sim.ob;
|
||||
ParticleSystem *psys= ctx->sim.psys;
|
||||
Object *tob;
|
||||
ParticleData *pa=0, *tpars= 0;
|
||||
ParticleSettings *part;
|
||||
@@ -999,49 +976,49 @@ int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, Derive
|
||||
totpart=get_psys_tot_child(scene, psys);
|
||||
cfrom=from=PART_FROM_FACE;
|
||||
|
||||
if(part->flag&PART_CHILD_SEAMS){
|
||||
MEdge *ed, *medge=dm->getEdgeDataArray(dm,CD_MEDGE);
|
||||
MVert *mvert=dm->getVertDataArray(dm,CD_MVERT);
|
||||
int totedge=dm->getNumEdges(dm);
|
||||
//if(part->flag&PART_CHILD_SEAMS){
|
||||
// MEdge *ed, *medge=dm->getEdgeDataArray(dm,CD_MEDGE);
|
||||
// MVert *mvert=dm->getVertDataArray(dm,CD_MVERT);
|
||||
// int totedge=dm->getNumEdges(dm);
|
||||
|
||||
for(p=0, ed=medge; p<totedge; p++,ed++)
|
||||
if(ed->flag&ME_SEAM)
|
||||
totseam++;
|
||||
// for(p=0, ed=medge; p<totedge; p++,ed++)
|
||||
// if(ed->flag&ME_SEAM)
|
||||
// totseam++;
|
||||
|
||||
if(totseam){
|
||||
ParticleSeam *cur_seam=seams=MEM_callocN(totseam*sizeof(ParticleSeam),"Child Distribution Seams");
|
||||
float temp[3],temp2[3];
|
||||
// if(totseam){
|
||||
// ParticleSeam *cur_seam=seams=MEM_callocN(totseam*sizeof(ParticleSeam),"Child Distribution Seams");
|
||||
// float temp[3],temp2[3];
|
||||
|
||||
for(p=0, ed=medge; p<totedge; p++,ed++){
|
||||
if(ed->flag&ME_SEAM){
|
||||
VecCopyf(cur_seam->v0,(mvert+ed->v1)->co);
|
||||
VecCopyf(cur_seam->v1,(mvert+ed->v2)->co);
|
||||
// for(p=0, ed=medge; p<totedge; p++,ed++){
|
||||
// if(ed->flag&ME_SEAM){
|
||||
// VecCopyf(cur_seam->v0,(mvert+ed->v1)->co);
|
||||
// VecCopyf(cur_seam->v1,(mvert+ed->v2)->co);
|
||||
|
||||
VecSubf(cur_seam->dir,cur_seam->v1,cur_seam->v0);
|
||||
// VecSubf(cur_seam->dir,cur_seam->v1,cur_seam->v0);
|
||||
|
||||
cur_seam->length2=VecLength(cur_seam->dir);
|
||||
cur_seam->length2*=cur_seam->length2;
|
||||
// cur_seam->length2=VecLength(cur_seam->dir);
|
||||
// cur_seam->length2*=cur_seam->length2;
|
||||
|
||||
temp[0]=(float)((mvert+ed->v1)->no[0]);
|
||||
temp[1]=(float)((mvert+ed->v1)->no[1]);
|
||||
temp[2]=(float)((mvert+ed->v1)->no[2]);
|
||||
temp2[0]=(float)((mvert+ed->v2)->no[0]);
|
||||
temp2[1]=(float)((mvert+ed->v2)->no[1]);
|
||||
temp2[2]=(float)((mvert+ed->v2)->no[2]);
|
||||
// temp[0]=(float)((mvert+ed->v1)->no[0]);
|
||||
// temp[1]=(float)((mvert+ed->v1)->no[1]);
|
||||
// temp[2]=(float)((mvert+ed->v1)->no[2]);
|
||||
// temp2[0]=(float)((mvert+ed->v2)->no[0]);
|
||||
// temp2[1]=(float)((mvert+ed->v2)->no[1]);
|
||||
// temp2[2]=(float)((mvert+ed->v2)->no[2]);
|
||||
|
||||
VecAddf(cur_seam->nor,temp,temp2);
|
||||
Normalize(cur_seam->nor);
|
||||
// VecAddf(cur_seam->nor,temp,temp2);
|
||||
// Normalize(cur_seam->nor);
|
||||
|
||||
Crossf(cur_seam->tan,cur_seam->dir,cur_seam->nor);
|
||||
// Crossf(cur_seam->tan,cur_seam->dir,cur_seam->nor);
|
||||
|
||||
Normalize(cur_seam->tan);
|
||||
// Normalize(cur_seam->tan);
|
||||
|
||||
cur_seam++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// cur_seam++;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
}
|
||||
else{
|
||||
/* no need to figure out distribution */
|
||||
@@ -1063,10 +1040,6 @@ int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, Derive
|
||||
length=VecLength(cpa->fuv);
|
||||
}
|
||||
|
||||
cpa->rand[0]=BLI_frand();
|
||||
cpa->rand[1]=BLI_frand();
|
||||
cpa->rand[2]=BLI_frand();
|
||||
|
||||
cpa->num=-1;
|
||||
}
|
||||
}
|
||||
@@ -1345,7 +1318,6 @@ int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, Derive
|
||||
jitlevel= totpart/tot;
|
||||
if(part->flag & PART_EDISTR) jitlevel*= 2; /* looks better in general, not very scietific */
|
||||
if(jitlevel<3) jitlevel= 3;
|
||||
//if(jitlevel>100) jitlevel= 100;
|
||||
}
|
||||
|
||||
jit= MEM_callocN((2+ jitlevel*2)*sizeof(float), "jit");
|
||||
@@ -1364,7 +1336,7 @@ int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, Derive
|
||||
ctx->tree= tree;
|
||||
ctx->seams= seams;
|
||||
ctx->totseam= totseam;
|
||||
ctx->psys= psys;
|
||||
ctx->sim.psys= psys;
|
||||
ctx->index= index;
|
||||
ctx->jit= jit;
|
||||
ctx->jitlevel= jitlevel;
|
||||
@@ -1385,7 +1357,7 @@ int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, Derive
|
||||
if(!children || psys->totchild < 10000)
|
||||
totthread= 1;
|
||||
|
||||
seed= 31415926 + ctx->psys->seed;
|
||||
seed= 31415926 + ctx->sim.psys->seed;
|
||||
for(i=0; i<totthread; i++) {
|
||||
threads[i].rng= rng_new(seed);
|
||||
threads[i].tot= totthread;
|
||||
@@ -1394,16 +1366,17 @@ int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, Derive
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void distribute_particles_on_dm(DerivedMesh *finaldm, Scene *scene, Object *ob, ParticleSystem *psys, int from)
|
||||
static void distribute_particles_on_dm(ParticleSimulationData *sim, int from)
|
||||
{
|
||||
DerivedMesh *finaldm = sim->psmd->dm;
|
||||
ListBase threads;
|
||||
ParticleThread *pthreads;
|
||||
ParticleThreadContext *ctx;
|
||||
int i, totthread;
|
||||
|
||||
pthreads= psys_threads_create(scene, ob, psys);
|
||||
pthreads= psys_threads_create(sim);
|
||||
|
||||
if(!psys_threads_init_distribution(pthreads, scene, finaldm, from)) {
|
||||
if(!psys_threads_init_distribution(pthreads, sim->scene, finaldm, from)) {
|
||||
psys_threads_free(pthreads);
|
||||
return;
|
||||
}
|
||||
@@ -1420,7 +1393,7 @@ static void distribute_particles_on_dm(DerivedMesh *finaldm, Scene *scene, Objec
|
||||
else
|
||||
exec_distribution(&pthreads[0]);
|
||||
|
||||
psys_calc_dmcache(ob, finaldm, psys);
|
||||
psys_calc_dmcache(sim->ob, finaldm, sim->psys);
|
||||
|
||||
ctx= pthreads[0].ctx;
|
||||
if(ctx->dm != finaldm)
|
||||
@@ -1430,8 +1403,9 @@ 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)
|
||||
static void distribute_particles_on_shape(ParticleSimulationData *sim, int from)
|
||||
{
|
||||
ParticleSystem *psys = sim->psys;
|
||||
PARTICLE_P;
|
||||
|
||||
fprintf(stderr,"Shape emission not yet possible!\n");
|
||||
@@ -1442,22 +1416,22 @@ static void distribute_particles_on_shape(Object *ob, ParticleSystem *psys, int
|
||||
pa->num= -1;
|
||||
}
|
||||
}
|
||||
static void distribute_particles(Scene *scene, Object *ob, ParticleSystem *psys, int from)
|
||||
static void distribute_particles(ParticleSimulationData *sim, int from)
|
||||
{
|
||||
ParticleSystemModifierData *psmd=0;
|
||||
PARTICLE_PSMD;
|
||||
int distr_error=0;
|
||||
psmd=psys_get_modifier(ob,psys);
|
||||
|
||||
if(psmd){
|
||||
if(psmd->dm)
|
||||
distribute_particles_on_dm(psmd->dm, scene, ob, psys, from);
|
||||
distribute_particles_on_dm(sim, from);
|
||||
else
|
||||
distr_error=1;
|
||||
}
|
||||
else
|
||||
distribute_particles_on_shape(ob,psys,from);
|
||||
distribute_particles_on_shape(sim, from);
|
||||
|
||||
if(distr_error){
|
||||
ParticleSystem *psys = sim->psys;
|
||||
PARTICLE_P;
|
||||
|
||||
fprintf(stderr,"Particle distribution error!\n");
|
||||
@@ -1471,26 +1445,23 @@ static void distribute_particles(Scene *scene, Object *ob, ParticleSystem *psys,
|
||||
}
|
||||
|
||||
/* threaded child particle distribution and path caching */
|
||||
ParticleThread *psys_threads_create(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys)
|
||||
ParticleThread *psys_threads_create(ParticleSimulationData *sim)
|
||||
{
|
||||
ParticleThread *threads;
|
||||
ParticleThreadContext *ctx;
|
||||
int i, totthread;
|
||||
|
||||
if(scene->r.mode & R_FIXED_THREADS)
|
||||
totthread= scene->r.threads;
|
||||
if(sim->scene->r.mode & R_FIXED_THREADS)
|
||||
totthread= sim->scene->r.threads;
|
||||
else
|
||||
totthread= BLI_system_thread_count();
|
||||
|
||||
threads= MEM_callocN(sizeof(ParticleThread)*totthread, "ParticleThread");
|
||||
ctx= MEM_callocN(sizeof(ParticleThreadContext), "ParticleThreadContext");
|
||||
|
||||
ctx->scene= scene;
|
||||
ctx->ob= ob;
|
||||
ctx->psys= psys;
|
||||
ctx->psmd= psys_get_modifier(ob, psys);
|
||||
ctx->dm= ctx->psmd->dm;
|
||||
ctx->ma= give_current_material(ob, psys->part->omat);
|
||||
ctx->sim = *sim;
|
||||
ctx->dm= ctx->sim.psmd->dm;
|
||||
ctx->ma= give_current_material(sim->ob, sim->psys->part->omat);
|
||||
|
||||
memset(threads, 0, sizeof(ParticleThread)*totthread);
|
||||
|
||||
@@ -1522,9 +1493,9 @@ void psys_threads_free(ParticleThread *threads)
|
||||
if(ctx->vg_roughe)
|
||||
MEM_freeN(ctx->vg_roughe);
|
||||
|
||||
if(ctx->psys->lattice){
|
||||
end_latt_deform(ctx->psys->lattice);
|
||||
ctx->psys->lattice= NULL;
|
||||
if(ctx->sim.psys->lattice){
|
||||
end_latt_deform(ctx->sim.psys->lattice);
|
||||
ctx->sim.psys->lattice= NULL;
|
||||
}
|
||||
|
||||
/* distribution */
|
||||
@@ -1550,37 +1521,34 @@ void psys_threads_free(ParticleThread *threads)
|
||||
}
|
||||
|
||||
/* set particle parameters that don't change during particle's life */
|
||||
void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd)
|
||||
void initialize_particle(ParticleSimulationData *sim, ParticleData *pa, int p)
|
||||
{
|
||||
ParticleSettings *part;
|
||||
ParticleSettings *part = sim->psys->part;
|
||||
ParticleTexture ptex;
|
||||
Material *ma=0;
|
||||
//IpoCurve *icu=0; // XXX old animation system
|
||||
int totpart;
|
||||
float rand;
|
||||
|
||||
part=psys->part;
|
||||
|
||||
totpart=psys->totpart;
|
||||
totpart=sim->psys->totpart;
|
||||
|
||||
ptex.life=ptex.size=ptex.exist=ptex.length=1.0;
|
||||
ptex.time=(float)p/(float)totpart;
|
||||
|
||||
BLI_srandom(psys->seed+p);
|
||||
BLI_srandom(sim->psys->seed + p + 125);
|
||||
|
||||
if(part->from!=PART_FROM_PARTICLE && part->type!=PART_FLUID){
|
||||
ma=give_current_material(ob,part->omat);
|
||||
ma=give_current_material(sim->ob,part->omat);
|
||||
|
||||
/* TODO: needs some work to make most blendtypes generally usefull */
|
||||
psys_get_texture(ob,ma,psmd,psys,pa,&ptex,MAP_PA_INIT);
|
||||
psys_get_texture(sim,ma,pa,&ptex,MAP_PA_INIT);
|
||||
}
|
||||
|
||||
pa->lifetime= part->lifetime*ptex.life;
|
||||
|
||||
if(part->type==PART_HAIR)
|
||||
pa->time= 0.0f;
|
||||
else if(part->type==PART_REACTOR && (part->flag&PART_REACT_STA_END)==0)
|
||||
pa->time= 300000.0f; /* max frame */
|
||||
//else if(part->type==PART_REACTOR && (part->flag&PART_REACT_STA_END)==0)
|
||||
// pa->time= 300000.0f; /* max frame */
|
||||
else{
|
||||
//icu=find_ipocurve(psys->part->ipo,PART_EMIT_TIME);
|
||||
//if(icu){
|
||||
@@ -1604,10 +1572,8 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps
|
||||
}
|
||||
#endif // XXX old animation system
|
||||
|
||||
/* need to get every rand even if we don't use them so that randoms don't affect each other */
|
||||
rand= BLI_frand();
|
||||
if(part->randlife!=0.0)
|
||||
pa->lifetime*= 1.0f - part->randlife*rand;
|
||||
pa->lifetime*= 1.0f - part->randlife * BLI_frand();
|
||||
}
|
||||
|
||||
pa->dietime= pa->time+pa->lifetime;
|
||||
@@ -1624,13 +1590,14 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps
|
||||
/* usage other than straight after distribute has to handle this index by itself - jahka*/
|
||||
//pa->num_dmcache = DMCACHE_NOTFOUND; /* assume we dont have a derived mesh face */
|
||||
}
|
||||
static void initialize_all_particles(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd)
|
||||
static void initialize_all_particles(ParticleSimulationData *sim)
|
||||
{
|
||||
//IpoCurve *icu=0; // XXX old animation system
|
||||
ParticleSystem *psys = sim->psys;
|
||||
PARTICLE_P;
|
||||
|
||||
LOOP_PARTICLES
|
||||
initialize_particle(pa,p,ob,psys,psmd);
|
||||
initialize_particle(sim, pa, p);
|
||||
|
||||
if(psys->part->type != PART_FLUID) {
|
||||
#if 0 // XXX old animation system
|
||||
@@ -1687,66 +1654,51 @@ static void initialize_all_particles(Object *ob, ParticleSystem *psys, ParticleS
|
||||
}
|
||||
}
|
||||
/* sets particle to the emitter surface with initial velocity & rotation */
|
||||
void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, ParticleSystemModifierData *psmd, Object *ob,
|
||||
float dtime, float cfra, float *vg_vel, float *vg_tan, float *vg_rot)
|
||||
void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, float cfra)
|
||||
{
|
||||
Object *ob = sim->ob;
|
||||
ParticleSystem *psys = sim->psys;
|
||||
ParticleSettings *part;
|
||||
ParticleTexture ptex;
|
||||
ParticleKey state;
|
||||
//IpoCurve *icu=0; // XXX old animation system
|
||||
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 fac, phasefac, nor[3]={0,0,0},loc[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], length, r_phase;
|
||||
float q_phase[4], r_phase;
|
||||
int p = pa - psys->particles;
|
||||
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);
|
||||
}
|
||||
r_vel[0] = 2.0f * (PSYS_FRAND(p + 10) - 0.5f);
|
||||
r_vel[1] = 2.0f * (PSYS_FRAND(p + 11) - 0.5f);
|
||||
r_vel[2] = 2.0f * (PSYS_FRAND(p + 12) - 0.5f);
|
||||
|
||||
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);
|
||||
r_ave[0] = 2.0f * (PSYS_FRAND(p + 13) - 0.5f);
|
||||
r_ave[1] = 2.0f * (PSYS_FRAND(p + 14) - 0.5f);
|
||||
r_ave[2] = 2.0f * (PSYS_FRAND(p + 15) - 0.5f);
|
||||
|
||||
r_rot[0] = 2.0f * (PSYS_FRAND(p + 16) - 0.5f);
|
||||
r_rot[1] = 2.0f * (PSYS_FRAND(p + 17) - 0.5f);
|
||||
r_rot[2] = 2.0f * (PSYS_FRAND(p + 18) - 0.5f);
|
||||
r_rot[3] = 2.0f * (PSYS_FRAND(p + 19) - 0.5f);
|
||||
NormalQuat(r_rot);
|
||||
|
||||
r_phase = BLI_frand();
|
||||
r_phase = PSYS_FRAND(p + 20);
|
||||
|
||||
if(part->from==PART_FROM_PARTICLE){
|
||||
Object *tob;
|
||||
ParticleSystem *tpsys=0;
|
||||
ParticleSimulationData tsim = {sim->scene, psys->target_ob ? psys->target_ob : ob, NULL, NULL};
|
||||
float speed;
|
||||
|
||||
tob=psys->target_ob;
|
||||
if(tob==0)
|
||||
tob=ob;
|
||||
|
||||
tpsys=BLI_findlink(&tob->particlesystem, psys->target_psys-1);
|
||||
tsim.psys = BLI_findlink(&tsim.ob->particlesystem, sim->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_particle_state(&tsim, pa->num, &state, 1);
|
||||
psys_get_from_key(&state, loc, nor, rot, 0);
|
||||
|
||||
QuatMulVecf(rot, vtan);
|
||||
@@ -1763,23 +1715,20 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
|
||||
}
|
||||
else{
|
||||
/* get precise emitter matrix if particle is born */
|
||||
if(part->type!=PART_HAIR && pa->time < cfra && pa->time >= psys->cfra)
|
||||
where_is_object_time(scene, ob,pa->time);
|
||||
if(part->type!=PART_HAIR && pa->time < cfra && pa->time >= sim->psys->cfra)
|
||||
where_is_object_time(sim->scene, sim->ob, pa->time);
|
||||
|
||||
/* get birth location from object */
|
||||
if(part->tanfac!=0.0)
|
||||
psys_particle_on_emitter(psmd,part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0);
|
||||
psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0);
|
||||
else
|
||||
psys_particle_on_emitter(psmd,part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,0,0,0,0);
|
||||
|
||||
/* save local coordinates for later */
|
||||
VECCOPY(tloc,loc);
|
||||
psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,0,0,0,0);
|
||||
|
||||
/* get possible textural influence */
|
||||
psys_get_texture(ob,give_current_material(ob,part->omat),psmd,psys,pa,&ptex,MAP_PA_IVEL);
|
||||
psys_get_texture(sim, give_current_material(sim->ob,part->omat), pa, &ptex, MAP_PA_IVEL);
|
||||
|
||||
if(vg_vel && pa->num != -1)
|
||||
ptex.ivel*=psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_vel);
|
||||
//if(vg_vel && pa->num != -1)
|
||||
// ptex.ivel*=psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_vel);
|
||||
|
||||
/* particles live in global space so */
|
||||
/* let's convert: */
|
||||
@@ -1787,21 +1736,18 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
|
||||
Mat4MulVecfl(ob->obmat,loc);
|
||||
|
||||
/* -normal */
|
||||
VECADD(nor,tloc,nor);
|
||||
Mat4MulVecfl(ob->obmat,nor);
|
||||
VECSUB(nor,nor,loc);
|
||||
Mat4Mul3Vecfl(ob->obmat,nor);
|
||||
Normalize(nor);
|
||||
|
||||
/* -tangent */
|
||||
if(part->tanfac!=0.0){
|
||||
float phase=vg_rot?2.0f*(psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_rot)-0.5f):0.0f;
|
||||
//float phase=vg_rot?2.0f*(psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_rot)-0.5f):0.0f;
|
||||
float phase=0.0f;
|
||||
VecMulf(vtan,-(float)cos(M_PI*(part->tanphase+phase)));
|
||||
fac=-(float)sin(M_PI*(part->tanphase+phase));
|
||||
VECADDFAC(vtan,vtan,utan,fac);
|
||||
|
||||
VECADD(vtan,tloc,vtan);
|
||||
Mat4MulVecfl(ob->obmat,vtan);
|
||||
VECSUB(vtan,vtan,loc);
|
||||
Mat4Mul3Vecfl(ob->obmat,vtan);
|
||||
|
||||
VECCOPY(utan,nor);
|
||||
VecMulf(utan,Inpf(vtan,nor));
|
||||
@@ -1853,11 +1799,6 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
|
||||
if(part->acc[2]!=0.0f)
|
||||
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, r_vel, pa->state.ave);
|
||||
VecSubf(mat[0], pa->state.ave, dvec);
|
||||
@@ -1896,8 +1837,9 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
|
||||
VECADDFAC(vel,vel,nor,part->normfac);
|
||||
|
||||
/* *emitter tangent */
|
||||
if(psmd && part->tanfac!=0.0)
|
||||
VECADDFAC(vel,vel,vtan,part->tanfac*(vg_tan?psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_tan):1.0f));
|
||||
if(sim->psmd && part->tanfac!=0.0)
|
||||
VECADDFAC(vel,vel,vtan,part->tanfac);
|
||||
//VECADDFAC(vel,vel,vtan,part->tanfac*(vg_tan?psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_tan):1.0f));
|
||||
|
||||
/* *texture */
|
||||
/* TODO */
|
||||
@@ -1917,9 +1859,6 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
|
||||
//}
|
||||
|
||||
VecMulf(vel,ptex.ivel);
|
||||
|
||||
//if(ELEM(part->phystype, PART_PHYS_GRADU_EX, PART_PHYS_GRADU_SIM))
|
||||
// VecAddf(vel,vel,part->acc);
|
||||
|
||||
VECCOPY(pa->state.vel,vel);
|
||||
|
||||
@@ -2001,22 +1940,20 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
|
||||
pa->alive = PARS_UNBORN;
|
||||
|
||||
pa->state.time = cfra;
|
||||
|
||||
// pa->flag &= ~PARS_STICKY;
|
||||
}
|
||||
static void reset_all_particles(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float dtime, float cfra, int from)
|
||||
static void reset_all_particles(ParticleSimulationData *sim, float dtime, float cfra, int from)
|
||||
{
|
||||
ParticleData *pa;
|
||||
int p, totpart=psys->totpart;
|
||||
float *vg_vel=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_VEL);
|
||||
float *vg_tan=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_TAN);
|
||||
float *vg_rot=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_ROT);
|
||||
int p, totpart=sim->psys->totpart;
|
||||
//float *vg_vel=psys_cache_vgroup(sim->psmd->dm,sim->psys,PSYS_VG_VEL);
|
||||
//float *vg_tan=psys_cache_vgroup(sim->psmd->dm,sim->psys,PSYS_VG_TAN);
|
||||
//float *vg_rot=psys_cache_vgroup(sim->psmd->dm,sim->psys,PSYS_VG_ROT);
|
||||
|
||||
for(p=from, pa=psys->particles+from; p<totpart; p++, pa++)
|
||||
reset_particle(scene, pa, psys, psmd, ob, dtime, cfra, vg_vel, vg_tan, vg_rot);
|
||||
for(p=from, pa=sim->psys->particles+from; p<totpart; p++, pa++)
|
||||
reset_particle(sim, pa, dtime, cfra);
|
||||
|
||||
if(vg_vel)
|
||||
MEM_freeN(vg_vel);
|
||||
//if(vg_vel)
|
||||
// MEM_freeN(vg_vel);
|
||||
}
|
||||
/************************************************/
|
||||
/* Particle targets */
|
||||
@@ -2041,15 +1978,15 @@ ParticleSystem *psys_get_target_system(Object *ob, ParticleTarget *pt)
|
||||
/* Keyed particles */
|
||||
/************************************************/
|
||||
/* Counts valid keyed targets */
|
||||
void psys_count_keyed_targets(Object *ob, ParticleSystem *psys)
|
||||
void psys_count_keyed_targets(ParticleSimulationData *sim)
|
||||
{
|
||||
ParticleSystem *kpsys;
|
||||
ParticleSystem *psys = sim->psys, *kpsys;
|
||||
ParticleTarget *pt = psys->targets.first;
|
||||
int keys_valid = 1;
|
||||
psys->totkeyed = 0;
|
||||
|
||||
for(; pt; pt=pt->next) {
|
||||
kpsys = psys_get_target_system(ob, pt);
|
||||
kpsys = psys_get_target_system(sim->ob, pt);
|
||||
|
||||
if(kpsys && kpsys->totpart) {
|
||||
psys->totkeyed += keys_valid;
|
||||
@@ -2064,9 +2001,10 @@ void psys_count_keyed_targets(Object *ob, ParticleSystem *psys)
|
||||
psys->totkeyed *= psys->flag & PSYS_KEYED_TIMING ? 1 : psys->part->keyed_loops;
|
||||
}
|
||||
|
||||
static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys)
|
||||
static void set_keyed_keys(ParticleSimulationData *sim)
|
||||
{
|
||||
ParticleSystem *kpsys = psys;
|
||||
ParticleSystem *psys = sim->psys;
|
||||
ParticleSimulationData ksim = {sim->scene, NULL, NULL, NULL};
|
||||
ParticleTarget *pt;
|
||||
PARTICLE_P;
|
||||
ParticleKey *key;
|
||||
@@ -2096,16 +2034,14 @@ static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys)
|
||||
|
||||
pt = psys->targets.first;
|
||||
for(k=0; k<totkeys; k++) {
|
||||
if(pt->ob)
|
||||
kpsys = BLI_findlink(&pt->ob->particlesystem, pt->psys - 1);
|
||||
else
|
||||
kpsys = BLI_findlink(&ob->particlesystem, pt->psys - 1);
|
||||
ksim.ob = pt->ob ? pt->ob : sim->ob;
|
||||
ksim.psys = BLI_findlink(&ksim.ob->particlesystem, pt->psys - 1);
|
||||
|
||||
LOOP_PARTICLES {
|
||||
key = pa->keys + k;
|
||||
key->time = -1.0; /* use current time */
|
||||
|
||||
psys_get_particle_state(scene, pt->ob, kpsys, p%kpsys->totpart, key, 1);
|
||||
psys_get_particle_state(&ksim, p%ksim.psys->totpart, key, 1);
|
||||
|
||||
if(psys->flag & PSYS_KEYED_TIMING){
|
||||
key->time = pa->time + pt->time;
|
||||
@@ -2131,111 +2067,109 @@ static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys)
|
||||
/************************************************/
|
||||
/* Reactors */
|
||||
/************************************************/
|
||||
static void push_reaction(Object* ob, ParticleSystem *psys, int pa_num, int event, ParticleKey *state)
|
||||
{
|
||||
Object *rob;
|
||||
ParticleSystem *rpsys;
|
||||
ParticleSettings *rpart;
|
||||
ParticleData *pa;
|
||||
ListBase *lb=&psys->effectors;
|
||||
ParticleEffectorCache *ec;
|
||||
ParticleReactEvent *re;
|
||||
|
||||
if(lb->first) for(ec = lb->first; ec; ec= ec->next){
|
||||
if(ec->type & PSYS_EC_REACTOR){
|
||||
/* all validity checks already done in add_to_effectors */
|
||||
rob=ec->ob;
|
||||
rpsys=BLI_findlink(&rob->particlesystem,ec->psys_nbr);
|
||||
rpart=rpsys->part;
|
||||
if(rpsys->part->reactevent==event){
|
||||
pa=psys->particles+pa_num;
|
||||
re= MEM_callocN(sizeof(ParticleReactEvent), "react event");
|
||||
re->event=event;
|
||||
re->pa_num = pa_num;
|
||||
re->ob = ob;
|
||||
re->psys = psys;
|
||||
re->size = pa->size;
|
||||
copy_particle_key(&re->state,state,1);
|
||||
|
||||
switch(event){
|
||||
case PART_EVENT_DEATH:
|
||||
re->time=pa->dietime;
|
||||
break;
|
||||
case PART_EVENT_COLLIDE:
|
||||
re->time=state->time;
|
||||
break;
|
||||
case PART_EVENT_NEAR:
|
||||
re->time=state->time;
|
||||
break;
|
||||
}
|
||||
|
||||
BLI_addtail(&rpsys->reactevents, re);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
static void react_to_events(ParticleSystem *psys, int pa_num)
|
||||
{
|
||||
ParticleSettings *part=psys->part;
|
||||
ParticleData *pa=psys->particles+pa_num;
|
||||
ParticleReactEvent *re=psys->reactevents.first;
|
||||
int birth=0;
|
||||
float dist=0.0f;
|
||||
|
||||
for(re=psys->reactevents.first; re; re=re->next){
|
||||
birth=0;
|
||||
if(part->from==PART_FROM_PARTICLE){
|
||||
if(pa->num==re->pa_num && pa->alive==PARS_UNBORN){
|
||||
if(re->event==PART_EVENT_NEAR){
|
||||
ParticleData *tpa = re->psys->particles+re->pa_num;
|
||||
float pa_time=tpa->time + pa->foffset*tpa->lifetime;
|
||||
if(re->time >= pa_time){
|
||||
pa->time=pa_time;
|
||||
pa->dietime=pa->time+pa->lifetime;
|
||||
}
|
||||
}
|
||||
else{
|
||||
pa->time=re->time;
|
||||
pa->dietime=pa->time+pa->lifetime;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
dist=VecLenf(pa->state.co, re->state.co);
|
||||
if(dist <= re->size){
|
||||
if(pa->alive==PARS_UNBORN){
|
||||
pa->time=re->time;
|
||||
pa->dietime=pa->time+pa->lifetime;
|
||||
birth=1;
|
||||
}
|
||||
if(birth || part->flag&PART_REACT_MULTIPLE){
|
||||
float vec[3];
|
||||
VECSUB(vec,pa->state.co, re->state.co);
|
||||
if(birth==0)
|
||||
VecMulf(vec,(float)pow(1.0f-dist/re->size,part->reactshape));
|
||||
VECADDFAC(pa->state.vel,pa->state.vel,vec,part->reactfac);
|
||||
VECADDFAC(pa->state.vel,pa->state.vel,re->state.vel,part->partfac);
|
||||
}
|
||||
if(birth)
|
||||
VecMulf(pa->state.vel,(float)pow(1.0f-dist/re->size,part->reactshape));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void psys_get_reactor_target(Object *ob, ParticleSystem *psys, Object **target_ob, ParticleSystem **target_psys)
|
||||
{
|
||||
Object *tob;
|
||||
|
||||
tob=psys->target_ob;
|
||||
if(tob==0)
|
||||
tob=ob;
|
||||
|
||||
*target_psys=BLI_findlink(&tob->particlesystem,psys->target_psys-1);
|
||||
if(*target_psys)
|
||||
*target_ob=tob;
|
||||
else
|
||||
*target_ob=0;
|
||||
}
|
||||
//static void push_reaction(ParticleSimulationData *sim, int pa_num, int event, ParticleKey *state)
|
||||
//{
|
||||
// Object *rob;
|
||||
// ParticleSystem *rpsys;
|
||||
// ParticleSettings *rpart;
|
||||
// ParticleData *pa;
|
||||
// ListBase *lb=&sim->psys->effectors;
|
||||
// ParticleEffectorCache *ec;
|
||||
// ParticleReactEvent *re;
|
||||
//
|
||||
// if(lb->first) for(ec = lb->first; ec; ec= ec->next){
|
||||
// if(ec->type & PSYS_EC_REACTOR){
|
||||
// /* all validity checks already done in add_to_effectors */
|
||||
// rob=ec->ob;
|
||||
// rpsys=BLI_findlink(&rob->particlesystem,ec->psys_nbr);
|
||||
// rpart=rpsys->part;
|
||||
// if(rpsys->part->reactevent==event){
|
||||
// pa=sim->psys->particles+pa_num;
|
||||
// re= MEM_callocN(sizeof(ParticleReactEvent), "react event");
|
||||
// re->event=event;
|
||||
// re->pa_num = pa_num;
|
||||
// re->ob = sim->ob;
|
||||
// re->psys = sim->psys;
|
||||
// re->size = pa->size;
|
||||
// copy_particle_key(&re->state,state,1);
|
||||
//
|
||||
// switch(event){
|
||||
// case PART_EVENT_DEATH:
|
||||
// re->time=pa->dietime;
|
||||
// break;
|
||||
// case PART_EVENT_COLLIDE:
|
||||
// re->time=state->time;
|
||||
// break;
|
||||
// case PART_EVENT_NEAR:
|
||||
// re->time=state->time;
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// BLI_addtail(&rpsys->reactevents, re);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//static void react_to_events(ParticleSystem *psys, int pa_num)
|
||||
//{
|
||||
// ParticleSettings *part=psys->part;
|
||||
// ParticleData *pa=psys->particles+pa_num;
|
||||
// ParticleReactEvent *re=psys->reactevents.first;
|
||||
// int birth=0;
|
||||
// float dist=0.0f;
|
||||
//
|
||||
// for(re=psys->reactevents.first; re; re=re->next){
|
||||
// birth=0;
|
||||
// if(part->from==PART_FROM_PARTICLE){
|
||||
// if(pa->num==re->pa_num && pa->alive==PARS_UNBORN){
|
||||
// if(re->event==PART_EVENT_NEAR){
|
||||
// ParticleData *tpa = re->psys->particles+re->pa_num;
|
||||
// float pa_time=tpa->time + pa->foffset*tpa->lifetime;
|
||||
// if(re->time >= pa_time){
|
||||
// pa->time=pa_time;
|
||||
// pa->dietime=pa->time+pa->lifetime;
|
||||
// }
|
||||
// }
|
||||
// else{
|
||||
// pa->time=re->time;
|
||||
// pa->dietime=pa->time+pa->lifetime;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else{
|
||||
// dist=VecLenf(pa->state.co, re->state.co);
|
||||
// if(dist <= re->size){
|
||||
// if(pa->alive==PARS_UNBORN){
|
||||
// pa->time=re->time;
|
||||
// pa->dietime=pa->time+pa->lifetime;
|
||||
// birth=1;
|
||||
// }
|
||||
// if(birth || part->flag&PART_REACT_MULTIPLE){
|
||||
// float vec[3];
|
||||
// VECSUB(vec,pa->state.co, re->state.co);
|
||||
// if(birth==0)
|
||||
// VecMulf(vec,(float)pow(1.0f-dist/re->size,part->reactshape));
|
||||
// VECADDFAC(pa->state.vel,pa->state.vel,vec,part->reactfac);
|
||||
// VECADDFAC(pa->state.vel,pa->state.vel,re->state.vel,part->partfac);
|
||||
// }
|
||||
// if(birth)
|
||||
// VecMulf(pa->state.vel,(float)pow(1.0f-dist/re->size,part->reactshape));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//void psys_get_reactor_target(ParticleSimulationData *sim, Object **target_ob, ParticleSystem **target_psys)
|
||||
//{
|
||||
// Object *tob;
|
||||
//
|
||||
// tob = sim->psys->target_ob ? sim->psys->target_ob : sim->ob;
|
||||
//
|
||||
// *target_psys = BLI_findlink(&tob->particlesystem, sim->psys->target_psys-1);
|
||||
// if(*target_psys)
|
||||
// *target_ob=tob;
|
||||
// else
|
||||
// *target_ob=0;
|
||||
//}
|
||||
/************************************************/
|
||||
/* Point Cache */
|
||||
/************************************************/
|
||||
@@ -2280,11 +2214,9 @@ static void update_particle_tree(ParticleSystem *psys)
|
||||
|
||||
psys->tree = BLI_kdtree_new(psys->totpart);
|
||||
|
||||
LOOP_PARTICLES {
|
||||
if(pa->flag & (PARS_NO_DISP+PARS_UNEXIST) || pa->alive != PARS_ALIVE)
|
||||
continue;
|
||||
|
||||
BLI_kdtree_insert(psys->tree, p, pa->state.co, NULL);
|
||||
LOOP_SHOWN_PARTICLES {
|
||||
if(pa->alive == PARS_ALIVE)
|
||||
BLI_kdtree_insert(psys->tree, p, pa->state.co, NULL);
|
||||
}
|
||||
BLI_kdtree_balance(psys->tree);
|
||||
|
||||
@@ -2301,7 +2233,7 @@ static void do_texture_effector(Tex *tex, short mode, short is_2d, float nabla,
|
||||
|
||||
result[0].nor = result[1].nor = result[2].nor = result[3].nor = 0;
|
||||
|
||||
strength= force_val*falloff;///(float)pow((double)distance,(double)power);
|
||||
strength= force_val*falloff;
|
||||
|
||||
VECCOPY(tex_co,pa_co);
|
||||
|
||||
@@ -2364,19 +2296,19 @@ static void do_texture_effector(Tex *tex, short mode, short is_2d, float nabla,
|
||||
|
||||
VecAddf(field,field,mag_vec);
|
||||
}
|
||||
static void add_to_effectors(ListBase *lb, Scene *scene, Object *ob, Object *obsrc, ParticleSystem *psys)
|
||||
static void add_to_effectors(ParticleSimulationData *sim, ListBase *lb, Object *ob)
|
||||
{
|
||||
ParticleEffectorCache *ec;
|
||||
PartDeflect *pd= ob->pd;
|
||||
short type=0,i;
|
||||
|
||||
if(pd && ob != obsrc){
|
||||
if(pd && ob != sim->ob){
|
||||
if(pd->forcefield == PFIELD_GUIDE) {
|
||||
if(ob->type==OB_CURVE) {
|
||||
Curve *cu= ob->data;
|
||||
if(cu->flag & CU_PATH) {
|
||||
if(cu->path==NULL || cu->path->data==NULL)
|
||||
makeDispListCurveTypes(scene, ob, 0);
|
||||
makeDispListCurveTypes(sim->scene, ob, 0);
|
||||
if(cu->path && cu->path->data) {
|
||||
type |= PSYS_EC_EFFECTOR;
|
||||
}
|
||||
@@ -2410,13 +2342,13 @@ static void add_to_effectors(ListBase *lb, Scene *scene, Object *ob, Object *obs
|
||||
if(ob->particlesystem.first){
|
||||
ParticleSystem *epsys=ob->particlesystem.first;
|
||||
ParticleSettings *epart=0;
|
||||
Object *tob;
|
||||
//Object *tob;
|
||||
|
||||
for(i=0; epsys; epsys=epsys->next,i++){
|
||||
if(!psys_check_enabled(ob, epsys))
|
||||
continue;
|
||||
type=0;
|
||||
if(epsys!=psys || (psys->part->flag & PART_SELF_EFFECT)){
|
||||
if(epsys!=sim->psys || (sim->psys->part->flag & PART_SELF_EFFECT)){
|
||||
epart=epsys->part;
|
||||
|
||||
if((epsys->part->pd && epsys->part->pd->forcefield)
|
||||
@@ -2425,13 +2357,13 @@ static void add_to_effectors(ListBase *lb, Scene *scene, Object *ob, Object *obs
|
||||
type=PSYS_EC_PARTICLE;
|
||||
}
|
||||
|
||||
if(epart->type==PART_REACTOR) {
|
||||
tob=epsys->target_ob;
|
||||
if(tob==0)
|
||||
tob=ob;
|
||||
if(BLI_findlink(&tob->particlesystem,epsys->target_psys-1)==psys)
|
||||
type|=PSYS_EC_REACTOR;
|
||||
}
|
||||
//if(epart->type==PART_REACTOR) {
|
||||
// tob=epsys->target_ob;
|
||||
// if(tob==0)
|
||||
// tob=ob;
|
||||
// if(BLI_findlink(&tob->particlesystem,epsys->target_psys-1)==sim->psys)
|
||||
// type|=PSYS_EC_REACTOR;
|
||||
//}
|
||||
|
||||
if(type){
|
||||
ec= MEM_callocN(sizeof(ParticleEffectorCache), "effector cache");
|
||||
@@ -2449,29 +2381,29 @@ static void add_to_effectors(ListBase *lb, Scene *scene, Object *ob, Object *obs
|
||||
}
|
||||
}
|
||||
|
||||
static void psys_init_effectors_recurs(Scene *scene, Object *ob, Object *obsrc, ParticleSystem *psys, ListBase *listb, int level)
|
||||
static void psys_init_effectors_recurs(ParticleSimulationData *sim, Object *ob, ListBase *listb, int level)
|
||||
{
|
||||
Group *group;
|
||||
GroupObject *go;
|
||||
unsigned int layer= obsrc->lay;
|
||||
unsigned int layer= sim->ob->lay;
|
||||
|
||||
if(level>MAX_DUPLI_RECUR) return;
|
||||
|
||||
if(ob->lay & layer) {
|
||||
if(ob->pd || ob->particlesystem.first)
|
||||
add_to_effectors(listb, scene, ob, obsrc, psys);
|
||||
add_to_effectors(sim, listb, ob);
|
||||
|
||||
if(ob->dup_group) {
|
||||
group= ob->dup_group;
|
||||
for(go= group->gobject.first; go; go= go->next)
|
||||
psys_init_effectors_recurs(scene, go->ob, obsrc, psys, listb, level+1);
|
||||
psys_init_effectors_recurs(sim, go->ob, listb, level+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void psys_init_effectors(Scene *scene, Object *obsrc, Group *group, ParticleSystem *psys)
|
||||
static void psys_init_effectors(ParticleSimulationData *sim, Group *group)
|
||||
{
|
||||
ListBase *listb= &psys->effectors;
|
||||
ListBase *listb= &sim->psys->effectors;
|
||||
Base *base;
|
||||
|
||||
listb->first=listb->last=0;
|
||||
@@ -2480,11 +2412,11 @@ void psys_init_effectors(Scene *scene, Object *obsrc, Group *group, ParticleSyst
|
||||
GroupObject *go;
|
||||
|
||||
for(go= group->gobject.first; go; go= go->next)
|
||||
psys_init_effectors_recurs(scene, go->ob, obsrc, psys, listb, 0);
|
||||
psys_init_effectors_recurs(sim, go->ob, listb, 0);
|
||||
}
|
||||
else {
|
||||
for(base = scene->base.first; base; base= base->next)
|
||||
psys_init_effectors_recurs(scene, base->object, obsrc, psys, listb, 0);
|
||||
for(base = sim->scene->base.first; base; base= base->next)
|
||||
psys_init_effectors_recurs(sim, base->object, listb, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2518,13 +2450,16 @@ void psys_end_effectors(ParticleSystem *psys)
|
||||
BLI_freelistN(&psys->effectors);
|
||||
}
|
||||
|
||||
static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra)
|
||||
/* precalcs effectors and returns 1 if there were any collision object
|
||||
/* so collision checks can be avoided as quickly as possible */
|
||||
static int precalc_effectors(ParticleSimulationData *sim, float cfra)
|
||||
{
|
||||
ParticleSystem *psys = sim->psys;
|
||||
ListBase *lb=&psys->effectors;
|
||||
ParticleEffectorCache *ec;
|
||||
ParticleSettings *part=psys->part;
|
||||
PARTICLE_P;
|
||||
int totpart;
|
||||
int totpart, collision = 0;
|
||||
float vec2[3],loc[3],radius,*co=0;
|
||||
|
||||
for(ec= lb->first; ec; ec= ec->next) {
|
||||
@@ -2556,9 +2491,9 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa
|
||||
VECCOPY(loc, pa->fuv);
|
||||
}
|
||||
else
|
||||
psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,0,0);
|
||||
psys_particle_on_emitter(sim->psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,0,0);
|
||||
|
||||
Mat4MulVecfl(ob->obmat,loc);
|
||||
Mat4MulVecfl(sim->ob->obmat,loc);
|
||||
ec->distances[p]=VecLenf(loc,vec);
|
||||
VECSUB(loc,loc,vec);
|
||||
VECCOPY(ec->locations+3*p,loc);
|
||||
@@ -2566,11 +2501,10 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa
|
||||
}
|
||||
}
|
||||
else if(ec->type==PSYS_EC_PARTICLE){
|
||||
Object *eob = ec->ob;
|
||||
ParticleSystem *epsys = BLI_findlink(&eob->particlesystem,ec->psys_nbr);
|
||||
ParticleSettings *epart = epsys->part;
|
||||
ParticleSimulationData esim = {sim->scene, ec->ob, BLI_findlink(&ec->ob->particlesystem, ec->psys_nbr), NULL};
|
||||
ParticleSettings *epart = esim.psys->part;
|
||||
ParticleData *epa;
|
||||
int p, totepart = epsys->totpart;
|
||||
int p, totepart = esim.psys->totpart;
|
||||
|
||||
if(psys->part->phystype==PART_PHYS_BOIDS){
|
||||
ParticleKey state;
|
||||
@@ -2583,8 +2517,8 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa
|
||||
tree=BLI_kdtree_new(totepart);
|
||||
ec->tree=tree;
|
||||
|
||||
for(p=0, epa=epsys->particles; p<totepart; p++,epa++)
|
||||
if(epa->alive==PARS_ALIVE && psys_get_particle_state(scene, eob,epsys,p,&state,0))
|
||||
for(p=0, epa=esim.psys->particles; p<totepart; p++,epa++)
|
||||
if(epa->alive==PARS_ALIVE && psys_get_particle_state(&esim,p,&state,0))
|
||||
BLI_kdtree_insert(tree, p, state.co, NULL);
|
||||
|
||||
BLI_kdtree_balance(tree);
|
||||
@@ -2594,12 +2528,23 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa
|
||||
}
|
||||
else if(ec->type==PSYS_EC_DEFLECT) {
|
||||
CollisionModifierData *collmd = ( CollisionModifierData * ) ( modifiers_findByType ( ec->ob, eModifierType_Collision ) );
|
||||
if(collmd)
|
||||
if(collmd) {
|
||||
collision_move_object(collmd, 1.0, 0.0);
|
||||
collision = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return collision;
|
||||
}
|
||||
|
||||
/* updates particle effectors and returns if any collision objects were found */
|
||||
int psys_update_effectors(ParticleSimulationData *sim, float cfra, int precalc)
|
||||
{
|
||||
psys_end_effectors(sim->psys);
|
||||
psys_init_effectors(sim, sim->psys->part->eff_group);
|
||||
return (precalc ? precalc_effectors(sim, cfra) : 0);
|
||||
}
|
||||
int effector_find_co(Scene *scene, float *pco, SurfaceModifierData *sur, Object *ob, PartDeflect *pd, float *co, float *nor, float *vel, int *index)
|
||||
{
|
||||
SurfaceModifierData *surmd = NULL;
|
||||
@@ -2679,10 +2624,10 @@ int effector_find_co(Scene *scene, float *pco, SurfaceModifierData *sur, Object
|
||||
return ret;
|
||||
}
|
||||
/* calculate forces that all effectors apply to a particle*/
|
||||
void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Scene *scene, Object *ob, ParticleSystem *psys, float *rootco, float *force_field, float *vel,float framestep, float cfra)
|
||||
void do_effectors(ParticleSimulationData *sim, int pa_no, ParticleData *pa, ParticleKey *state, float *rootco, float *force_field, float *vel,float framestep, float cfra)
|
||||
{
|
||||
Object *eob;
|
||||
ParticleSystem *epsys;
|
||||
ParticleSystem *psys = sim->psys;
|
||||
ParticleSettings *epart;
|
||||
ParticleData *epa;
|
||||
ParticleKey estate;
|
||||
@@ -2712,19 +2657,19 @@ void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Scene *scene,
|
||||
if(ec->type & PSYS_EC_EFFECTOR){
|
||||
pd=eob->pd;
|
||||
if(psys->part->type!=PART_HAIR && psys->part->integrator)
|
||||
where_is_object_time(scene, eob,cfra);
|
||||
where_is_object_time(sim->scene, eob, cfra);
|
||||
|
||||
if(pd && pd->flag&PFIELD_SURFACE) {
|
||||
float velocity[3];
|
||||
/* using velocity corrected location allows for easier sliding over effector surface */
|
||||
VecCopyf(velocity, state->vel);
|
||||
VecMulf(velocity, psys_get_timestep(psys->part));
|
||||
VecMulf(velocity, psys_get_timestep(sim));
|
||||
VecAddf(pco, state->co, velocity);
|
||||
}
|
||||
else
|
||||
VECCOPY(pco, state->co);
|
||||
|
||||
effector_find_co(scene, pco, NULL, eob, pd, co, NULL, NULL, &face_index);
|
||||
effector_find_co(sim->scene, pco, NULL, eob, pd, co, NULL, NULL, &face_index);
|
||||
|
||||
VecSubf(vec_to_part, state->co, co);
|
||||
|
||||
@@ -2741,68 +2686,69 @@ void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Scene *scene,
|
||||
pd->flag & PFIELD_TEX_OBJECT, (pd->flag & PFIELD_TEX_ROOTCO) ? rootco : state->co, eob->obmat,
|
||||
strength, falloff, force_field);
|
||||
} else {
|
||||
do_physical_effector(scene, eob, state->co, pd->forcefield,strength,distance,
|
||||
do_physical_effector(sim->scene, eob, state->co, pd->forcefield,strength,distance,
|
||||
falloff,0.0,pd->f_damp,eob->obmat[2],vec_to_part,
|
||||
state->vel,force_field,pd->flag&PFIELD_PLANAR,ec->rng,pd->f_noise,charge,pa->size);
|
||||
}
|
||||
}
|
||||
if(ec->type & PSYS_EC_PARTICLE){
|
||||
ParticleSimulationData esim = {sim->scene, eob, BLI_findlink(&eob->particlesystem,ec->psys_nbr), NULL};
|
||||
int totepart, i;
|
||||
epsys= BLI_findlink(&eob->particlesystem,ec->psys_nbr);
|
||||
epart= epsys->part;
|
||||
pd=epart->pd;
|
||||
totepart= epsys->totpart;
|
||||
|
||||
epart = esim.psys->part;
|
||||
pd = epart->pd;
|
||||
totepart = esim.psys->totpart;
|
||||
|
||||
if(totepart <= 0)
|
||||
continue;
|
||||
|
||||
if(pd && pd->forcefield==PFIELD_HARMONIC){
|
||||
/* every particle is mapped to only one harmonic effector particle */
|
||||
p= pa_no%epsys->totpart;
|
||||
p= pa_no%esim.psys->totpart;
|
||||
totepart= p+1;
|
||||
}
|
||||
else{
|
||||
p=0;
|
||||
}
|
||||
|
||||
epsys->lattice= psys_get_lattice(scene, ob, psys);
|
||||
esim.psys->lattice= psys_get_lattice(sim);
|
||||
|
||||
for(; p<totepart; p++){
|
||||
/* particle skips itself as effector */
|
||||
if(epsys==psys && p == pa_no) continue;
|
||||
if(esim.psys == psys && p == pa_no) continue;
|
||||
|
||||
epa = epsys->particles + p;
|
||||
estate.time=cfra;
|
||||
if(psys_get_particle_state(scene, eob,epsys,p,&estate,0)){
|
||||
epa = esim.psys->particles + p;
|
||||
estate.time = cfra;
|
||||
if(psys_get_particle_state(&esim, p, &estate, 0)){
|
||||
VECSUB(vec_to_part, state->co, estate.co);
|
||||
distance = VecLength(vec_to_part);
|
||||
|
||||
for(i=0, pd = epart->pd; i<2; i++,pd = epart->pd2) {
|
||||
if(pd==NULL || pd->forcefield==0) continue;
|
||||
|
||||
falloff=effector_falloff(pd,estate.vel,vec_to_part);
|
||||
falloff = effector_falloff(pd, estate.vel, vec_to_part);
|
||||
|
||||
strength = pd->f_strength * psys->part->effector_weight[0] * psys->part->effector_weight[pd->forcefield];
|
||||
|
||||
if(falloff<=0.0f)
|
||||
; /* don't do anything */
|
||||
else
|
||||
do_physical_effector(scene, eob, state->co, pd->forcefield,strength,distance,
|
||||
do_physical_effector(sim->scene, eob, state->co, pd->forcefield,strength,distance,
|
||||
falloff,epart->size,pd->f_damp,estate.vel,vec_to_part,
|
||||
state->vel,force_field,0, ec->rng, pd->f_noise,charge,pa->size);
|
||||
}
|
||||
}
|
||||
else if(pd && pd->forcefield==PFIELD_HARMONIC && cfra-framestep <= epa->dietime && cfra>epa->dietime){
|
||||
/* first step after key release */
|
||||
psys_get_particle_state(scene, eob,epsys,p,&estate,1);
|
||||
VECADD(vel,vel,estate.vel);
|
||||
psys_get_particle_state(&esim, p, &estate, 1);
|
||||
VECADD(vel, vel, estate.vel);
|
||||
/* TODO: add rotation handling here too */
|
||||
}
|
||||
}
|
||||
|
||||
if(epsys->lattice){
|
||||
end_latt_deform(epsys->lattice);
|
||||
epsys->lattice= NULL;
|
||||
if(esim.psys->lattice){
|
||||
end_latt_deform(esim.psys->lattice);
|
||||
esim.psys->lattice= NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2813,11 +2759,14 @@ void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Scene *scene,
|
||||
/* Newtonian physics */
|
||||
/************************************************/
|
||||
/* gathers all forces that effect particles and calculates a new state for the particle */
|
||||
static void apply_particle_forces(Scene *scene, int pa_no, ParticleData *pa, Object *ob, ParticleSystem *psys, ParticleSettings *part, float timestep, float dfra, float cfra)
|
||||
static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra, float cfra)
|
||||
{
|
||||
ParticleSettings *part = sim->psys->part;
|
||||
ParticleData *pa = sim->psys->particles + p;
|
||||
ParticleKey states[5], tkey;
|
||||
float timestep = psys_get_timestep(sim);
|
||||
float force[3],tvel[3],dx[4][3],dv[4][3];
|
||||
float dtime=dfra*timestep, time, pa_mass=part->mass, fac, fra=psys->cfra;
|
||||
float dtime=dfra*timestep, time, pa_mass=part->mass, fac, fra=sim->psys->cfra;
|
||||
int i, steps=1;
|
||||
|
||||
/* maintain angular velocity */
|
||||
@@ -2845,7 +2794,7 @@ static void apply_particle_forces(Scene *scene, int pa_no, ParticleData *pa, Obj
|
||||
tvel[0]=tvel[1]=tvel[2]=0.0;
|
||||
/* add effectors */
|
||||
if(part->type != PART_HAIR)
|
||||
do_effectors(pa_no,pa,states+i,scene, ob, psys,states->co,force,tvel,dfra,fra);
|
||||
do_effectors(sim, p, pa, states+i, states->co, force, tvel, dfra, fra);
|
||||
|
||||
/* calculate air-particle interaction */
|
||||
if(part->dragfac!=0.0f){
|
||||
@@ -2878,7 +2827,7 @@ static void apply_particle_forces(Scene *scene, int pa_no, ParticleData *pa, Obj
|
||||
if(i==0){
|
||||
VECADDFAC(states[1].co,states->co,states->vel,dtime*0.5f);
|
||||
VECADDFAC(states[1].vel,states->vel,force,dtime*0.5f);
|
||||
fra=psys->cfra+0.5f*dfra;
|
||||
fra=sim->psys->cfra+0.5f*dfra;
|
||||
}
|
||||
else{
|
||||
VECADDFAC(pa->state.co,states->co,states[1].vel,dtime);
|
||||
@@ -2895,7 +2844,7 @@ static void apply_particle_forces(Scene *scene, int pa_no, ParticleData *pa, Obj
|
||||
|
||||
VECADDFAC(states[1].co,states->co,dx[0],0.5f);
|
||||
VECADDFAC(states[1].vel,states->vel,dv[0],0.5f);
|
||||
fra=psys->cfra+0.5f*dfra;
|
||||
fra=sim->psys->cfra+0.5f*dfra;
|
||||
break;
|
||||
case 1:
|
||||
VECADDFAC(dx[1],states->vel,dv[0],0.5f);
|
||||
@@ -2949,7 +2898,7 @@ static void apply_particle_forces(Scene *scene, int pa_no, ParticleData *pa, Obj
|
||||
tkey.time=pa->state.time;
|
||||
|
||||
if(part->type != PART_HAIR) {
|
||||
if(do_guide(scene, &tkey, pa_no, time, &psys->effectors)) {
|
||||
if(do_guide(sim->scene, &tkey, p, time, &sim->psys->effectors)) {
|
||||
VECCOPY(pa->state.co,tkey.co);
|
||||
/* guides don't produce valid velocity */
|
||||
VECSUB(pa->state.vel,tkey.co,pa->prev_state.co);
|
||||
@@ -3213,15 +3162,18 @@ void particle_intersect_face(void *userdata, int index, const BVHTreeRay *ray, B
|
||||
/* angular momentum <-> linear momentum and swept sphere - mesh collisions */
|
||||
/* 1. check for all possible deflectors for closest intersection on particle path */
|
||||
/* 2. if deflection was found kill the particle or calculate new coordinates */
|
||||
static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierData *psmd, ParticleSystem *psys, ParticleSettings *part, ParticleData *pa, int p, float timestep, float dfra, float cfra){
|
||||
static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, float cfra){
|
||||
Object *ob = NULL, *skip_ob = NULL;
|
||||
ListBase *lb=&psys->effectors;
|
||||
ParticleSettings *part = sim->psys->part;
|
||||
ListBase *lb=&sim->psys->effectors;
|
||||
ParticleEffectorCache *ec;
|
||||
ParticleKey reaction_state;
|
||||
ParticleCollision col;
|
||||
ParticleData *pa = sim->psys->particles + p;
|
||||
BVHTreeRayHit hit;
|
||||
float ray_dir[3], zerovec[3]={0.0,0.0,0.0};
|
||||
float radius = ((part->flag & PART_SIZE_DEFL)?pa->size:0.0f), boid_z = 0.0f;
|
||||
float timestep = psys_get_timestep(sim);
|
||||
int deflections=0, max_deflections=10;
|
||||
|
||||
VECCOPY(col.co1, pa->prev_state.co);
|
||||
@@ -3258,11 +3210,11 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa
|
||||
continue;
|
||||
|
||||
/* particles should not collide with emitter at birth */
|
||||
if(ob==pob && pa->time < cfra && pa->time >= psys->cfra)
|
||||
if(ob==sim->ob && pa->time < cfra && pa->time >= sim->psys->cfra)
|
||||
continue;
|
||||
|
||||
if(part->type!=PART_HAIR)
|
||||
where_is_object_time(scene,ob,cfra);
|
||||
where_is_object_time(sim->scene, sim->ob, cfra);
|
||||
|
||||
col.md = ( CollisionModifierData * ) ( modifiers_findByType ( ec->ob, eModifierType_Collision ) );
|
||||
col.ob_t = ob;
|
||||
@@ -3399,9 +3351,9 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa
|
||||
}
|
||||
|
||||
/* store state for reactors */
|
||||
VECCOPY(reaction_state.co, co);
|
||||
VecLerpf(reaction_state.vel, pa->prev_state.vel, pa->state.vel, dt);
|
||||
QuatInterpol(reaction_state.rot, pa->prev_state.rot, pa->state.rot, dt);
|
||||
//VECCOPY(reaction_state.co, co);
|
||||
//VecLerpf(reaction_state.vel, pa->prev_state.vel, pa->state.vel, dt);
|
||||
//QuatInterpol(reaction_state.rot, pa->prev_state.rot, pa->state.rot, dt);
|
||||
|
||||
/* set coordinates for next iteration */
|
||||
VECCOPY(col.co1, co);
|
||||
@@ -3423,8 +3375,8 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa
|
||||
}
|
||||
deflections++;
|
||||
|
||||
reaction_state.time = cfra - (1.0f - dt) * dfra;
|
||||
push_reaction(col.ob, psys, p, PART_EVENT_COLLIDE, &reaction_state);
|
||||
//reaction_state.time = cfra - (1.0f - dt) * dfra;
|
||||
//push_reaction(col.ob, psys, p, PART_EVENT_COLLIDE, &reaction_state);
|
||||
}
|
||||
else
|
||||
return;
|
||||
@@ -3434,29 +3386,30 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa
|
||||
/* Hair */
|
||||
/************************************************/
|
||||
/* check if path cache or children need updating and do it if needed */
|
||||
static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra)
|
||||
static void psys_update_path_cache(ParticleSimulationData *sim, float cfra)
|
||||
{
|
||||
ParticleSettings *part=psys->part;
|
||||
ParticleEditSettings *pset=&scene->toolsettings->particle;
|
||||
int distr=0,alloc=0,skip=0;
|
||||
ParticleSystem *psys = sim->psys;
|
||||
ParticleSettings *part = psys->part;
|
||||
ParticleEditSettings *pset = &sim->scene->toolsettings->particle;
|
||||
int distr=0, alloc=0, skip=0;
|
||||
|
||||
if((psys->part->childtype && psys->totchild != get_psys_tot_child(scene, psys)) || psys->recalc&PSYS_RECALC_RESET)
|
||||
if((psys->part->childtype && psys->totchild != get_psys_tot_child(sim->scene, psys)) || psys->recalc&PSYS_RECALC_RESET)
|
||||
alloc=1;
|
||||
|
||||
if(alloc || psys->recalc&PSYS_RECALC_CHILD || (psys->vgroup[PSYS_VG_DENSITY] && (ob && ob->mode & OB_MODE_WEIGHT_PAINT)))
|
||||
if(alloc || psys->recalc&PSYS_RECALC_CHILD || (psys->vgroup[PSYS_VG_DENSITY] && (sim->ob && sim->ob->mode & OB_MODE_WEIGHT_PAINT)))
|
||||
distr=1;
|
||||
|
||||
if(distr){
|
||||
if(alloc)
|
||||
realloc_particles(ob,psys,psys->totpart);
|
||||
realloc_particles(sim, sim->psys->totpart);
|
||||
|
||||
if(get_psys_tot_child(scene, psys)) {
|
||||
if(get_psys_tot_child(sim->scene, psys)) {
|
||||
/* don't generate children while computing the hair keys */
|
||||
if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE)) {
|
||||
distribute_particles(scene, ob, psys, PART_FROM_CHILD);
|
||||
distribute_particles(sim, PART_FROM_CHILD);
|
||||
|
||||
if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES && part->parents!=0.0)
|
||||
psys_find_parents(ob,psmd,psys);
|
||||
psys_find_parents(sim);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3470,7 +3423,7 @@ static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModif
|
||||
skip = 1; /* draw visualization */
|
||||
else if(psys->pointcache->flag & PTCACHE_BAKING)
|
||||
skip = 1; /* no need to cache paths while baking dynamics */
|
||||
else if(psys_in_edit_mode(scene, psys)) {
|
||||
else if(psys_in_edit_mode(sim->scene, psys)) {
|
||||
if((pset->flag & PE_DRAW_PART)==0)
|
||||
skip = 1;
|
||||
else if(part->childtype==0 && (psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED)==0)
|
||||
@@ -3479,7 +3432,7 @@ static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModif
|
||||
}
|
||||
|
||||
if(!skip) {
|
||||
psys_cache_paths(scene, ob, psys, cfra);
|
||||
psys_cache_paths(sim, cfra);
|
||||
|
||||
/* for render, child particle paths are computed on the fly */
|
||||
if(part->childtype) {
|
||||
@@ -3489,15 +3442,16 @@ static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModif
|
||||
skip = 1;
|
||||
|
||||
if(!skip)
|
||||
psys_cache_child_paths(scene, ob, psys, cfra, 0);
|
||||
psys_cache_child_paths(sim, cfra, 0);
|
||||
}
|
||||
}
|
||||
else if(psys->pathcache)
|
||||
psys_free_path_cache(psys, NULL);
|
||||
}
|
||||
|
||||
static void do_hair_dynamics(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd)
|
||||
static void do_hair_dynamics(ParticleSimulationData *sim)
|
||||
{
|
||||
ParticleSystem *psys = sim->psys;
|
||||
DerivedMesh *dm = psys->hair_in_dm;
|
||||
MVert *mvert = NULL;
|
||||
MEdge *medge = NULL;
|
||||
@@ -3520,7 +3474,8 @@ static void do_hair_dynamics(Scene *scene, Object *ob, ParticleSystem *psys, Par
|
||||
LOOP_PARTICLES
|
||||
totpoint += pa->totkey;
|
||||
|
||||
totedge = totpoint - psys->totpart;
|
||||
totedge = totpoint;
|
||||
totpoint += psys->totpart;
|
||||
|
||||
if(dm && (totpoint != dm->getNumVerts(dm) || totedge != dm->getNumEdges(dm))) {
|
||||
dm->release(dm);
|
||||
@@ -3539,14 +3494,39 @@ static void do_hair_dynamics(Scene *scene, Object *ob, ParticleSystem *psys, Par
|
||||
psys->clmd->sim_parms->vgroup_mass = 1;
|
||||
|
||||
/* make vgroup for pin roots etc.. */
|
||||
psys->particles->hair_index = 0;
|
||||
psys->particles->hair_index = 1;
|
||||
LOOP_PARTICLES {
|
||||
if(p)
|
||||
pa->hair_index = (pa-1)->hair_index + (pa-1)->totkey;
|
||||
pa->hair_index = (pa-1)->hair_index + (pa-1)->totkey + 1;
|
||||
|
||||
psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, pa, hairmat);
|
||||
psys_mat_hair_to_object(sim->ob, sim->psmd->dm, psys->part->from, pa, hairmat);
|
||||
|
||||
for(k=0, key=pa->hair; k<pa->totkey; k++,key++) {
|
||||
|
||||
/* create fake root before actual root to resist bending */
|
||||
if(k==0) {
|
||||
float temp[3];
|
||||
VECSUB(temp, key->co, (key+1)->co);
|
||||
VECCOPY(mvert->co, key->co);
|
||||
VECADD(mvert->co, mvert->co, temp);
|
||||
Mat4MulVecfl(hairmat, mvert->co);
|
||||
mvert++;
|
||||
|
||||
medge->v1 = pa->hair_index - 1;
|
||||
medge->v2 = pa->hair_index;
|
||||
medge++;
|
||||
|
||||
if(dvert) {
|
||||
if(!dvert->totweight) {
|
||||
dvert->dw = MEM_callocN (sizeof(MDeformWeight), "deformWeight");
|
||||
dvert->totweight = 1;
|
||||
}
|
||||
|
||||
dvert->dw->weight = 1.0f;
|
||||
dvert++;
|
||||
}
|
||||
}
|
||||
|
||||
VECCOPY(mvert->co, key->co);
|
||||
Mat4MulVecfl(hairmat, mvert->co);
|
||||
mvert++;
|
||||
@@ -3576,10 +3556,11 @@ static void do_hair_dynamics(Scene *scene, Object *ob, ParticleSystem *psys, Par
|
||||
|
||||
psys->clmd->point_cache = psys->pointcache;
|
||||
|
||||
psys->hair_out_dm = clothModifier_do(psys->clmd, scene, ob, dm, 0, 0);
|
||||
psys->hair_out_dm = clothModifier_do(psys->clmd, sim->scene, sim->ob, dm, 0, 0);
|
||||
}
|
||||
static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra)
|
||||
static void hair_step(ParticleSimulationData *sim, float cfra)
|
||||
{
|
||||
ParticleSystem *psys = sim->psys;
|
||||
ParticleSettings *part = psys->part;
|
||||
PARTICLE_P;
|
||||
float disp = (float)get_current_display_percentage(psys)/100.0f;
|
||||
@@ -3587,7 +3568,7 @@ static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd
|
||||
BLI_srandom(psys->seed);
|
||||
|
||||
LOOP_PARTICLES {
|
||||
if(BLI_frand() > disp)
|
||||
if(PSYS_FRAND(p) > disp)
|
||||
pa->flag |= PARS_NO_DISP;
|
||||
else
|
||||
pa->flag &= ~PARS_NO_DISP;
|
||||
@@ -3595,36 +3576,33 @@ static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd
|
||||
|
||||
if(psys->recalc & PSYS_RECALC_RESET) {
|
||||
/* need this for changing subsurf levels */
|
||||
psys_calc_dmcache(ob, psmd->dm, psys);
|
||||
psys_calc_dmcache(sim->ob, sim->psmd->dm, psys);
|
||||
|
||||
if(psys->clmd)
|
||||
cloth_free_modifier(ob, psys->clmd);
|
||||
cloth_free_modifier(sim->ob, psys->clmd);
|
||||
}
|
||||
|
||||
if(psys->effectors.first)
|
||||
psys_end_effectors(psys);
|
||||
|
||||
/* dynamics with cloth simulation */
|
||||
if(psys->part->type==PART_HAIR && psys->flag & PSYS_HAIR_DYNAMICS)
|
||||
do_hair_dynamics(scene, ob, psys, psmd);
|
||||
do_hair_dynamics(sim);
|
||||
|
||||
psys_init_effectors(scene, ob, part->eff_group, psys);
|
||||
if(psys->effectors.first)
|
||||
precalc_effectors(scene, ob,psys,psmd,cfra);
|
||||
psys_update_effectors(sim, cfra, 1);
|
||||
|
||||
psys_update_path_cache(scene, ob,psmd,psys,cfra);
|
||||
psys_update_path_cache(sim, cfra);
|
||||
|
||||
psys->flag |= PSYS_HAIR_UPDATED;
|
||||
}
|
||||
|
||||
static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra){
|
||||
static void save_hair(ParticleSimulationData *sim, float cfra){
|
||||
Object *ob = sim->ob;
|
||||
ParticleSystem *psys = sim->psys;
|
||||
HairKey *key, *root;
|
||||
PARTICLE_P;
|
||||
int totpart;
|
||||
|
||||
Mat4Invert(ob->imat,ob->obmat);
|
||||
Mat4Invert(ob->imat, ob->obmat);
|
||||
|
||||
psys->lattice= psys_get_lattice(scene, ob, psys);
|
||||
psys->lattice= psys_get_lattice(sim);
|
||||
|
||||
if(psys->totpart==0) return;
|
||||
|
||||
@@ -3647,7 +3625,7 @@ static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSy
|
||||
|
||||
if(pa->totkey) {
|
||||
VECSUB(key->co, key->co, root->co);
|
||||
psys_vec_rot_to_face(psmd->dm, pa, key->co);
|
||||
psys_vec_rot_to_face(sim->psmd->dm, pa, key->co);
|
||||
}
|
||||
|
||||
key->time = pa->state.time;
|
||||
@@ -3665,17 +3643,17 @@ static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSy
|
||||
/* System Core */
|
||||
/************************************************/
|
||||
/* unbaked particles are calculated dynamically */
|
||||
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)
|
||||
static void dynamics_step(ParticleSimulationData *sim, float cfra)
|
||||
{
|
||||
ParticleSystem *psys = sim->psys;
|
||||
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);
|
||||
Material *ma=give_current_material(sim->ob, part->omat);
|
||||
BoidBrainData bbd;
|
||||
PARTICLE_P;
|
||||
float timestep;
|
||||
int totpart;
|
||||
int totpart, check_collisions = 0;
|
||||
/* current time */
|
||||
float ctime, ipotime; // XXX old animation system
|
||||
/* frame & time changes */
|
||||
@@ -3687,7 +3665,7 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
|
||||
|
||||
totpart=psys->totpart;
|
||||
|
||||
timestep=psys_get_timestep(part);
|
||||
timestep=psys_get_timestep(sim);
|
||||
dtime= dfra*timestep;
|
||||
ctime= cfra*timestep;
|
||||
ipotime= cfra; // XXX old animation system
|
||||
@@ -3701,12 +3679,10 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
|
||||
|
||||
if(dfra<0.0){
|
||||
float *vg_size=0;
|
||||
if(part->type==PART_REACTOR)
|
||||
vg_size=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_SIZE);
|
||||
|
||||
LOOP_PARTICLES {
|
||||
if(pa->flag & PARS_UNEXIST) continue;
|
||||
//if(part->type==PART_REACTOR)
|
||||
// vg_size=psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_SIZE);
|
||||
|
||||
LOOP_EXISTING_PARTICLES {
|
||||
/* set correct ipo timing */
|
||||
#if 0 // XXX old animation system
|
||||
if((part->flag&PART_ABS_TIME)==0 && part->ipo){
|
||||
@@ -3715,13 +3691,15 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
|
||||
execute_ipo((ID *)part, part->ipo);
|
||||
}
|
||||
#endif // XXX old animation system
|
||||
pa->size=psys_get_size(ob,ma,psmd,icu_esize,psys,part,pa,vg_size);
|
||||
pa->size = part->size;
|
||||
if(part->randsize > 0.0)
|
||||
pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
|
||||
|
||||
reset_particle(scene, pa,psys,psmd,ob,dtime,cfra,vg_vel,vg_tan,vg_rot);
|
||||
reset_particle(sim, pa, dtime, cfra);
|
||||
|
||||
if(cfra>pa->time && part->flag & PART_LOOP && part->type!=PART_HAIR){
|
||||
pa->loop=(short)((cfra-pa->time)/pa->lifetime);
|
||||
pa->alive=PARS_UNBORN;
|
||||
if(cfra > pa->time && part->flag & PART_LOOP && part->type!=PART_HAIR){
|
||||
pa->loop = (short)((cfra-pa->time)/pa->lifetime);
|
||||
pa->alive = PARS_UNBORN;
|
||||
}
|
||||
else{
|
||||
pa->loop = 0;
|
||||
@@ -3742,21 +3720,12 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
|
||||
}
|
||||
else{
|
||||
BLI_srandom(31415926 + (int)cfra + psys->seed);
|
||||
|
||||
/* update effectors */
|
||||
if(psys->effectors.first)
|
||||
psys_end_effectors(psys);
|
||||
|
||||
psys_init_effectors(scene, ob, part->eff_group, psys);
|
||||
|
||||
if(psys->effectors.first)
|
||||
precalc_effectors(scene, ob,psys,psmd,cfra);
|
||||
psys_update_effectors(sim, cfra, 1);
|
||||
|
||||
if(part->phystype==PART_PHYS_BOIDS){
|
||||
ParticleTarget *pt = psys->targets.first;
|
||||
bbd.scene = scene;
|
||||
bbd.ob = ob;
|
||||
bbd.psys = psys;
|
||||
bbd.sim = sim;
|
||||
bbd.part = part;
|
||||
bbd.cfra = cfra;
|
||||
bbd.dfra = dfra;
|
||||
@@ -3773,9 +3742,7 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
|
||||
}
|
||||
|
||||
/* main loop: calculate physics for all particles */
|
||||
LOOP_PARTICLES {
|
||||
if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue;
|
||||
|
||||
LOOP_SHOWN_PARTICLES {
|
||||
copy_particle_key(&pa->prev_state,&pa->state,1);
|
||||
|
||||
/* set correct ipo timing */
|
||||
@@ -3786,23 +3753,19 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
|
||||
execute_ipo((ID *)part, part->ipo);
|
||||
}
|
||||
#endif // XXX old animation system
|
||||
pa->size=psys_get_size(ob,ma,psmd,icu_esize,psys,part,pa,vg_size);
|
||||
//update_particle_settings(psys, part, &tpart, pa);
|
||||
|
||||
/* reactions can change birth time so they need to be checked first */
|
||||
if(psys->reactevents.first && ELEM(pa->alive,PARS_DEAD,PARS_KILLED)==0)
|
||||
react_to_events(psys,p);
|
||||
pa->size = part->size;
|
||||
if(part->randsize > 0.0)
|
||||
pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
|
||||
|
||||
///* reactions can change birth time so they need to be checked first */
|
||||
//if(psys->reactevents.first && ELEM(pa->alive,PARS_DEAD,PARS_KILLED)==0)
|
||||
// react_to_events(psys,p);
|
||||
|
||||
birthtime = pa->time + pa->loop * pa->lifetime;
|
||||
dietime = birthtime + pa->lifetime;
|
||||
|
||||
/* allways reset particles to emitter before birth */
|
||||
if(pa->alive==PARS_UNBORN
|
||||
|| pa->alive==PARS_KILLED
|
||||
|| ELEM(part->phystype,PART_PHYS_NO,PART_PHYS_KEYED)
|
||||
|| birthtime >= psys->cfra){
|
||||
reset_particle(scene, pa,psys,psmd,ob,dtime,cfra,vg_vel,vg_tan,vg_rot);
|
||||
}
|
||||
|
||||
pa_dfra = dfra;
|
||||
pa_dtime = dtime;
|
||||
|
||||
@@ -3815,6 +3778,7 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
|
||||
}
|
||||
else if(birthtime <= cfra && birthtime >= psys->cfra){
|
||||
/* particle is born some time between this and last step*/
|
||||
reset_particle(sim, pa, dtime, cfra);
|
||||
pa->alive = PARS_ALIVE;
|
||||
pa_dfra = cfra - birthtime;
|
||||
pa_dtime = pa_dfra*timestep;
|
||||
@@ -3823,18 +3787,22 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
|
||||
/* nothing to be done when particle is dead */
|
||||
}
|
||||
|
||||
/* only reset unborn particles if they're shown */
|
||||
if(pa->alive==PARS_UNBORN && part->flag & PART_UNBORN)
|
||||
reset_particle(sim, pa, dtime, cfra);
|
||||
|
||||
if(dfra>0.0 && ELEM(pa->alive,PARS_ALIVE,PARS_DYING)){
|
||||
switch(part->phystype){
|
||||
case PART_PHYS_NEWTON:
|
||||
/* do global forces & effectors */
|
||||
apply_particle_forces(scene, p, pa, ob, psys, part, timestep,pa_dfra,cfra);
|
||||
apply_particle_forces(sim, p, pa_dfra, cfra);
|
||||
|
||||
/* deflection */
|
||||
deflect_particle(scene, ob,psmd,psys,part,pa,p,timestep,pa_dfra,cfra);
|
||||
if(check_collisions)
|
||||
deflect_particle(sim, p, pa_dfra, cfra);
|
||||
|
||||
/* rotations */
|
||||
rotate_particle(part,pa,pa_dfra,timestep);
|
||||
rotate_particle(part, pa, pa_dfra, timestep);
|
||||
break;
|
||||
case PART_PHYS_BOIDS:
|
||||
{
|
||||
@@ -3844,18 +3812,18 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
|
||||
boid_body(&bbd, pa);
|
||||
|
||||
/* deflection */
|
||||
deflect_particle(scene,ob,psmd,psys,part,pa,p,timestep,pa_dfra,cfra);
|
||||
deflect_particle(sim, p, pa_dfra, cfra);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(pa->alive == PARS_DYING){
|
||||
push_reaction(ob,psys,p,PART_EVENT_DEATH,&pa->state);
|
||||
//push_reaction(ob,psys,p,PART_EVENT_DEATH,&pa->state);
|
||||
|
||||
if(part->flag & PART_LOOP && part->type!=PART_HAIR){
|
||||
pa->loop++;
|
||||
reset_particle(scene, pa,psys,psmd,ob,0.0,cfra,vg_vel,vg_tan,vg_rot);
|
||||
reset_particle(sim, pa, 0.0, cfra);
|
||||
pa->alive=PARS_ALIVE;
|
||||
}
|
||||
else{
|
||||
@@ -3866,7 +3834,7 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
|
||||
else
|
||||
pa->state.time=cfra;
|
||||
|
||||
push_reaction(ob,psys,p,PART_EVENT_NEAR,&pa->state);
|
||||
//push_reaction(ob,psys,p,PART_EVENT_NEAR,&pa->state);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3878,28 +3846,21 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
|
||||
}
|
||||
|
||||
/* updates cached particles' alive & other flags etc..*/
|
||||
static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra)
|
||||
static void cached_step(ParticleSimulationData *sim, float cfra)
|
||||
{
|
||||
ParticleSettings *part=psys->part;
|
||||
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);
|
||||
ParticleSystem *psys = sim->psys;
|
||||
ParticleSettings *part = psys->part;
|
||||
IpoCurve *icu_esize = NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
|
||||
Material *ma = give_current_material(sim->ob,part->omat);
|
||||
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);
|
||||
vg_size= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_SIZE);
|
||||
|
||||
if(psys->effectors.first)
|
||||
psys_end_effectors(psys);
|
||||
|
||||
//if(part->flag & (PART_BAKED_GUIDES+PART_BAKED_DEATHS)){
|
||||
psys_init_effectors(scene, ob, part->eff_group, psys);
|
||||
if(psys->effectors.first)
|
||||
precalc_effectors(scene, ob,psys,psmd,cfra);
|
||||
//}
|
||||
psys_update_effectors(sim, cfra, 1);
|
||||
|
||||
disp= (float)get_current_display_percentage(psys)/100.0f;
|
||||
|
||||
@@ -3911,9 +3872,13 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps
|
||||
execute_ipo((ID *)part, part->ipo);
|
||||
}
|
||||
#endif // XXX old animation system
|
||||
pa->size= psys_get_size(ob,ma,psmd,icu_esize,psys,part,pa,vg_size);
|
||||
//update_settings_with_particle(psys, part, pa);
|
||||
|
||||
psys->lattice= psys_get_lattice(scene, ob, psys);
|
||||
pa->size = part->size;
|
||||
if(part->randsize > 0.0)
|
||||
pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
|
||||
|
||||
psys->lattice= psys_get_lattice(sim);
|
||||
|
||||
if(part->flag & PART_LOOP && part->type!=PART_HAIR)
|
||||
pa->loop = (short)((cfra - pa->time) / pa->lifetime);
|
||||
@@ -3924,25 +3889,16 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps
|
||||
dietime = birthtime + (1 + pa->loop) * (pa->dietime - pa->time);
|
||||
|
||||
/* update alive status and push events */
|
||||
if(pa->time >= cfra) {
|
||||
pa->alive = pa->time==cfra ? PARS_ALIVE : PARS_UNBORN;
|
||||
if((psys->pointcache->flag & PTCACHE_EXTERNAL) == 0)
|
||||
reset_particle(scene, pa, psys, psmd, ob, 0.0f, cfra, NULL, NULL, NULL);
|
||||
if(pa->time > cfra) {
|
||||
pa->alive = PARS_UNBORN;
|
||||
if(part->flag & PART_UNBORN && (psys->pointcache->flag & PTCACHE_EXTERNAL) == 0)
|
||||
reset_particle(sim, pa, 0.0f, cfra);
|
||||
}
|
||||
else if(dietime <= cfra){
|
||||
if(dietime > psys->cfra){
|
||||
state.time = dietime;
|
||||
psys_get_particle_state(scene, ob,psys,p,&state,1);
|
||||
push_reaction(ob,psys,p,PART_EVENT_DEATH,&state);
|
||||
}
|
||||
pa->alive = PARS_DEAD;
|
||||
}
|
||||
else{
|
||||
pa->alive = PARS_ALIVE;
|
||||
state.time = cfra;
|
||||
psys_get_particle_state(scene, ob,psys,p,&state,1);
|
||||
state.time = cfra;
|
||||
push_reaction(ob,psys,p,PART_EVENT_NEAR,&state);
|
||||
}
|
||||
|
||||
if(psys->lattice){
|
||||
@@ -3950,43 +3906,41 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps
|
||||
psys->lattice= NULL;
|
||||
}
|
||||
|
||||
if(BLI_frand() > disp)
|
||||
if(PSYS_FRAND(p) > disp)
|
||||
pa->flag |= PARS_NO_DISP;
|
||||
else
|
||||
pa->flag &= ~PARS_NO_DISP;
|
||||
}
|
||||
|
||||
/* make sure that children are up to date */
|
||||
if(psys->part->childtype && psys->totchild != get_psys_tot_child(scene, psys)) {
|
||||
realloc_particles(ob, psys, psys->totpart);
|
||||
distribute_particles(scene, ob, psys, PART_FROM_CHILD);
|
||||
if(psys->part->childtype && psys->totchild != get_psys_tot_child(sim->scene, psys)) {
|
||||
realloc_particles(sim, psys->totpart);
|
||||
distribute_particles(sim, PART_FROM_CHILD);
|
||||
}
|
||||
|
||||
psys_update_path_cache(scene, ob,psmd,psys,cfra);
|
||||
psys_update_path_cache(sim, cfra);
|
||||
|
||||
if(vg_size)
|
||||
MEM_freeN(vg_size);
|
||||
}
|
||||
|
||||
static void psys_changed_type(Object *ob, ParticleSystem *psys)
|
||||
static void psys_changed_type(ParticleSimulationData *sim)
|
||||
{
|
||||
ParticleSettings *part;
|
||||
ParticleSettings *part = sim->psys->part;
|
||||
PTCacheID pid;
|
||||
|
||||
part= psys->part;
|
||||
|
||||
BKE_ptcache_id_from_particles(&pid, ob, psys);
|
||||
BKE_ptcache_id_from_particles(&pid, sim->ob, sim->psys);
|
||||
|
||||
/* system type has changed so set sensible defaults and clear non applicable flags */
|
||||
if(part->from == PART_FROM_PARTICLE) {
|
||||
if(part->type != PART_REACTOR)
|
||||
part->from = PART_FROM_FACE;
|
||||
//if(part->type != PART_REACTOR)
|
||||
part->from = PART_FROM_FACE;
|
||||
if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT)
|
||||
part->distr = PART_DISTR_JIT;
|
||||
}
|
||||
|
||||
if(part->phystype != PART_PHYS_KEYED)
|
||||
psys->flag &= ~PSYS_KEYED;
|
||||
sim->psys->flag &= ~PSYS_KEYED;
|
||||
|
||||
if(part->type == PART_HAIR) {
|
||||
if(ELEM4(part->ren_as, PART_DRAW_NOT, PART_DRAW_PATH, PART_DRAW_OB, PART_DRAW_GR)==0)
|
||||
@@ -4001,13 +3955,13 @@ static void psys_changed_type(Object *ob, ParticleSystem *psys)
|
||||
BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0);
|
||||
}
|
||||
else {
|
||||
free_hair(ob, psys, 1);
|
||||
free_hair(sim->ob, sim->psys, 1);
|
||||
|
||||
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_reset(psys, PSYS_RESET_ALL);
|
||||
psys_reset(sim->psys, PSYS_RESET_ALL);
|
||||
}
|
||||
void psys_check_boid_data(ParticleSystem *psys)
|
||||
{
|
||||
@@ -4033,24 +3987,24 @@ void psys_check_boid_data(ParticleSystem *psys)
|
||||
pa->boid = NULL;
|
||||
}
|
||||
}
|
||||
static void psys_changed_physics(Object *ob, ParticleSystem *psys)
|
||||
static void psys_changed_physics(ParticleSimulationData *sim)
|
||||
{
|
||||
ParticleSettings *part = psys->part;
|
||||
ParticleSettings *part = sim->psys->part;
|
||||
|
||||
if(ELEM(part->phystype, PART_PHYS_NO, PART_PHYS_KEYED)) {
|
||||
PTCacheID pid;
|
||||
BKE_ptcache_id_from_particles(&pid, ob, psys);
|
||||
BKE_ptcache_id_from_particles(&pid, sim->ob, sim->psys);
|
||||
BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0);
|
||||
}
|
||||
else {
|
||||
free_keyed_keys(psys);
|
||||
psys->flag &= ~PSYS_KEYED;
|
||||
free_keyed_keys(sim->psys);
|
||||
sim->psys->flag &= ~PSYS_KEYED;
|
||||
}
|
||||
|
||||
if(part->phystype == PART_PHYS_BOIDS && part->boids == NULL) {
|
||||
BoidState *state;
|
||||
|
||||
psys_check_boid_data(psys);
|
||||
psys_check_boid_data(sim->psys);
|
||||
|
||||
part->boids = MEM_callocN(sizeof(BoidSettings), "Boid Settings");
|
||||
boid_default_settings(part->boids);
|
||||
@@ -4065,8 +4019,9 @@ static void psys_changed_physics(Object *ob, ParticleSystem *psys)
|
||||
BLI_addtail(&part->boids->states, state);
|
||||
}
|
||||
}
|
||||
static void particles_fluid_step(Scene *scene, Object *ob, ParticleSystem *psys, int cfra)
|
||||
static void particles_fluid_step(ParticleSimulationData *sim, int cfra)
|
||||
{
|
||||
ParticleSystem *psys = sim->psys;
|
||||
if(psys->particles){
|
||||
MEM_freeN(psys->particles);
|
||||
psys->particles = 0;
|
||||
@@ -4076,7 +4031,7 @@ static void particles_fluid_step(Scene *scene, Object *ob, ParticleSystem *psys,
|
||||
/* fluid sim particle import handling, actual loading of particles from file */
|
||||
#ifndef DISABLE_ELBEEM
|
||||
{
|
||||
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
|
||||
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(sim->ob, eModifierType_Fluidsim);
|
||||
|
||||
if( fluidmd && fluidmd->fss) {
|
||||
FluidsimSettings *fss= fluidmd->fss;
|
||||
@@ -4086,7 +4041,7 @@ static void particles_fluid_step(Scene *scene, Object *ob, ParticleSystem *psys,
|
||||
char *suffix2 = ".gz";
|
||||
char filename[256];
|
||||
char debugStrBuffer[256];
|
||||
int curFrame = scene->r.cfra -1; // warning - sync with derived mesh fsmesh loading
|
||||
int curFrame = sim->scene->r.cfra -1; // warning - sync with derived mesh fsmesh loading
|
||||
int p, j, numFileParts, totpart;
|
||||
int readMask, activeParts = 0, fileParts = 0;
|
||||
gzFile gzf;
|
||||
@@ -4114,11 +4069,11 @@ static void particles_fluid_step(Scene *scene, Object *ob, ParticleSystem *psys,
|
||||
|
||||
part->totpart= totpart;
|
||||
part->sta=part->end = 1.0f;
|
||||
part->lifetime = scene->r.efra + 1;
|
||||
part->lifetime = sim->scene->r.efra + 1;
|
||||
|
||||
/* initialize particles */
|
||||
realloc_particles(ob, psys, part->totpart);
|
||||
initialize_all_particles(ob, psys, 0);
|
||||
realloc_particles(sim, part->totpart);
|
||||
initialize_all_particles(sim);
|
||||
|
||||
// set up reading mask
|
||||
readMask = fss->typeFlags;
|
||||
@@ -4174,10 +4129,11 @@ static void particles_fluid_step(Scene *scene, Object *ob, ParticleSystem *psys,
|
||||
|
||||
/* Calculates the next state for all particles of the system */
|
||||
/* In particles code most fra-ending are frames, time-ending are fra*timestep (seconds)*/
|
||||
static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra)
|
||||
static void system_step(ParticleSimulationData *sim, float cfra)
|
||||
{
|
||||
ParticleSettings *part;
|
||||
PointCache *cache;
|
||||
ParticleSystem *psys = sim->psys;
|
||||
ParticleSettings *part = psys->part;
|
||||
PointCache *cache = psys->pointcache;
|
||||
PTCacheID pid;
|
||||
PARTICLE_P;
|
||||
int totpart, oldtotpart, totchild, oldtotchild;
|
||||
@@ -4185,20 +4141,17 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
|
||||
int init= 0, distr= 0, alloc= 0, usecache= 0, only_children_changed= 0;
|
||||
int framenr, framedelta, startframe, endframe;
|
||||
|
||||
part= psys->part;
|
||||
cache= psys->pointcache;
|
||||
|
||||
framenr= (int)scene->r.cfra;
|
||||
framenr= (int)sim->scene->r.cfra;
|
||||
framedelta= framenr - cache->simframe;
|
||||
|
||||
/* set suitable cache range automatically */
|
||||
if((cache->flag & (PTCACHE_BAKING|PTCACHE_BAKED))==0 && !(psys->flag & PSYS_HAIR_DYNAMICS))
|
||||
psys_get_pointcache_start_end(scene, psys, &cache->startframe, &cache->endframe);
|
||||
psys_get_pointcache_start_end(sim->scene, sim->psys, &cache->startframe, &cache->endframe);
|
||||
|
||||
BKE_ptcache_id_from_particles(&pid, ob, psys);
|
||||
BKE_ptcache_id_time(&pid, scene, 0.0f, &startframe, &endframe, NULL);
|
||||
BKE_ptcache_id_from_particles(&pid, sim->ob, psys);
|
||||
BKE_ptcache_id_time(&pid, sim->scene, 0.0f, &startframe, &endframe, NULL);
|
||||
|
||||
psys_clear_temp_pointcache(psys);
|
||||
psys_clear_temp_pointcache(sim->psys);
|
||||
|
||||
/* update ipo's */
|
||||
#if 0 // XXX old animation system
|
||||
@@ -4210,14 +4163,14 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
|
||||
|
||||
/* hair if it's already done is handled separate */
|
||||
if(part->type == PART_HAIR && (psys->flag & PSYS_HAIR_DONE)) {
|
||||
hair_step(scene, ob, psmd, psys, cfra);
|
||||
hair_step(sim, cfra);
|
||||
psys->cfra = cfra;
|
||||
psys->recalc = 0;
|
||||
return;
|
||||
}
|
||||
/* fluid is also handled separate */
|
||||
else if(part->type == PART_FLUID) {
|
||||
particles_fluid_step(scene, ob, psys, framenr);
|
||||
particles_fluid_step(sim, framenr);
|
||||
psys->cfra = cfra;
|
||||
psys->recalc = 0;
|
||||
return;
|
||||
@@ -4254,7 +4207,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
|
||||
totpart = part->grid_res*part->grid_res*part->grid_res;
|
||||
else
|
||||
totpart = psys->part->totpart;
|
||||
totchild = get_psys_tot_child(scene, psys);
|
||||
totchild = get_psys_tot_child(sim->scene, psys);
|
||||
|
||||
if(oldtotpart != totpart || oldtotchild != totchild) {
|
||||
only_children_changed = (oldtotpart == totpart);
|
||||
@@ -4271,45 +4224,45 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
|
||||
if(init) {
|
||||
if(distr) {
|
||||
if(alloc) {
|
||||
realloc_particles(ob, psys, totpart);
|
||||
realloc_particles(sim, totpart);
|
||||
|
||||
if(usecache && !only_children_changed) {
|
||||
BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0);
|
||||
BKE_ptcache_id_from_particles(&pid, ob, psys);
|
||||
BKE_ptcache_id_from_particles(&pid, sim->ob, psys);
|
||||
}
|
||||
}
|
||||
|
||||
if(!only_children_changed)
|
||||
distribute_particles(scene, ob, psys, part->from);
|
||||
distribute_particles(sim, part->from);
|
||||
|
||||
if((psys->part->type == PART_HAIR) && !(psys->flag & PSYS_HAIR_DONE))
|
||||
/* don't generate children while growing hair - waste of time */
|
||||
psys_free_children(psys);
|
||||
else if(get_psys_tot_child(scene, psys))
|
||||
distribute_particles(scene, ob, psys, PART_FROM_CHILD);
|
||||
else if(get_psys_tot_child(sim->scene, psys))
|
||||
distribute_particles(sim, PART_FROM_CHILD);
|
||||
}
|
||||
|
||||
if(!only_children_changed) {
|
||||
free_keyed_keys(psys);
|
||||
|
||||
initialize_all_particles(ob, psys, psmd);
|
||||
initialize_all_particles(sim);
|
||||
|
||||
|
||||
if(alloc) {
|
||||
reset_all_particles(scene, ob, psys, psmd, 0.0, cfra, oldtotpart);
|
||||
reset_all_particles(sim, 0.0, cfra, oldtotpart);
|
||||
}
|
||||
}
|
||||
|
||||
/* flag for possible explode modifiers after this system */
|
||||
psmd->flag |= eParticleSystemFlag_Pars;
|
||||
sim->psmd->flag |= eParticleSystemFlag_Pars;
|
||||
}
|
||||
|
||||
/* try to read from the cache */
|
||||
if(usecache) {
|
||||
int result = BKE_ptcache_read_cache(&pid, cfra, scene->r.frs_sec);
|
||||
int result = BKE_ptcache_read_cache(&pid, cfra, sim->scene->r.frs_sec);
|
||||
|
||||
if(result == PTCACHE_READ_EXACT || result == PTCACHE_READ_INTERPOLATED) {
|
||||
cached_step(scene, ob, psmd, psys, cfra);
|
||||
cached_step(sim, cfra);
|
||||
psys->cfra=cfra;
|
||||
psys->recalc = 0;
|
||||
|
||||
@@ -4333,7 +4286,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
|
||||
pa->alive = PARS_ALIVE;
|
||||
}
|
||||
}
|
||||
else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) {
|
||||
else if(sim->ob->id.lib || (cache->flag & PTCACHE_BAKED)) {
|
||||
psys_reset(psys, PSYS_RESET_CACHE_MISS);
|
||||
psys->cfra=cfra;
|
||||
psys->recalc = 0;
|
||||
@@ -4351,14 +4304,14 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
|
||||
BKE_ptcache_write_cache(&pid, startframe);
|
||||
|
||||
if(part->phystype==PART_PHYS_KEYED)
|
||||
psys_count_keyed_targets(ob,psys);
|
||||
psys_count_keyed_targets(sim);
|
||||
|
||||
/* initialize vertex groups */
|
||||
if(part->from!=PART_FROM_PARTICLE) {
|
||||
vg_vel= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_VEL);
|
||||
vg_tan= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_TAN);
|
||||
vg_rot= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_ROT);
|
||||
vg_size= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_SIZE);
|
||||
vg_vel= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_VEL);
|
||||
vg_tan= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_TAN);
|
||||
vg_rot= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_ROT);
|
||||
vg_size= psys_cache_vgroup(sim->psmd->dm,psys,PSYS_VG_SIZE);
|
||||
}
|
||||
|
||||
/* set particles to be not calculated TODO: can't work with pointcache */
|
||||
@@ -4366,7 +4319,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
|
||||
|
||||
BLI_srandom(psys->seed);
|
||||
LOOP_PARTICLES {
|
||||
if(BLI_frand() > disp)
|
||||
if(PSYS_FRAND(p) > disp)
|
||||
pa->flag |= PARS_NO_DISP;
|
||||
else
|
||||
pa->flag &= ~PARS_NO_DISP;
|
||||
@@ -4382,7 +4335,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
|
||||
|
||||
for(dframe=-totframesback; dframe<=0; dframe++) {
|
||||
/* ok now we're all set so let's go */
|
||||
dynamics_step(scene, ob, psys, psmd, cfra+dframe, vg_vel, vg_tan, vg_rot, vg_size);
|
||||
dynamics_step(sim, cfra+dframe);
|
||||
psys->cfra = cfra+dframe;
|
||||
}
|
||||
}
|
||||
@@ -4399,8 +4352,8 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
|
||||
|
||||
/* for keyed particles the path is allways known so it can be drawn */
|
||||
if(part->phystype==PART_PHYS_KEYED) {
|
||||
set_keyed_keys(scene, ob, psys);
|
||||
psys_update_path_cache(scene, ob, psmd, psys,(int)cfra);
|
||||
set_keyed_keys(sim);
|
||||
psys_update_path_cache(sim,(int)cfra);
|
||||
}
|
||||
else if(psys->pathcache)
|
||||
psys_free_path_cache(psys, NULL);
|
||||
@@ -4430,30 +4383,33 @@ static int hair_needs_recalc(ParticleSystem *psys)
|
||||
/* main particle update call, checks that things are ok on the large scale before actual particle calculations */
|
||||
void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys)
|
||||
{
|
||||
ParticleSystemModifierData *psmd;
|
||||
ParticleSimulationData sim = {scene, ob, psys, NULL};
|
||||
float cfra;
|
||||
|
||||
/* drawdata is outdated after ANY change */
|
||||
if(psys->pdd) psys->pdd->flag &= ~PARTICLE_DRAW_DATA_UPDATED;
|
||||
|
||||
if(!psys_check_enabled(ob, psys))
|
||||
return;
|
||||
|
||||
cfra= bsystem_time(scene, ob, (float)scene->r.cfra, 0.0f);
|
||||
psmd= psys_get_modifier(ob, psys);
|
||||
sim.psmd= psys_get_modifier(ob, psys);
|
||||
|
||||
/* system was already updated from modifier stack */
|
||||
if(psmd->flag & eParticleSystemFlag_psys_updated) {
|
||||
psmd->flag &= ~eParticleSystemFlag_psys_updated;
|
||||
if(sim.psmd->flag & eParticleSystemFlag_psys_updated) {
|
||||
sim.psmd->flag &= ~eParticleSystemFlag_psys_updated;
|
||||
/* make sure it really was updated to cfra */
|
||||
if(psys->cfra == cfra)
|
||||
return;
|
||||
}
|
||||
|
||||
if(!psmd->dm)
|
||||
if(!sim.psmd->dm)
|
||||
return;
|
||||
|
||||
if(psys->recalc & PSYS_RECALC_TYPE)
|
||||
psys_changed_type(ob, psys);
|
||||
psys_changed_type(&sim);
|
||||
else if(psys->recalc & PSYS_RECALC_PHYS)
|
||||
psys_changed_physics(ob, psys);
|
||||
psys_changed_physics(&sim);
|
||||
|
||||
/* (re-)create hair */
|
||||
if(psys->part->type==PART_HAIR && hair_needs_recalc(psys)) {
|
||||
@@ -4467,15 +4423,15 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys)
|
||||
|
||||
for(i=0; i<=psys->part->hair_step; i++){
|
||||
hcfra=100.0f*(float)i/(float)psys->part->hair_step;
|
||||
system_step(scene, ob, psys, psmd, hcfra);
|
||||
save_hair(scene, ob, psys, psmd, hcfra);
|
||||
system_step(&sim, hcfra);
|
||||
save_hair(&sim, hcfra);
|
||||
}
|
||||
|
||||
psys->flag |= PSYS_HAIR_DONE;
|
||||
}
|
||||
|
||||
/* the main particle system step */
|
||||
system_step(scene, ob, psys, psmd, cfra);
|
||||
system_step(&sim, cfra);
|
||||
|
||||
/* save matrix for duplicators */
|
||||
Mat4Invert(psys->imat, ob->obmat);
|
||||
|
||||
@@ -79,6 +79,20 @@
|
||||
static void ptcache_data_to(void **data, int type, int index, void *to);
|
||||
static void ptcache_data_from(void **data, int type, void *from);
|
||||
|
||||
#define PTCACHE_DATA_FROM(data, type, from) if(data[type]) { memcpy(data[type], from, ptcache_data_size[type]); }
|
||||
#define PTCACHE_DATA_TO(data, type, index, to) if(data[type]) { memcpy(to, (char*)data[type] + (index ? index * ptcache_data_size[type] : 0), ptcache_data_size[type]); }
|
||||
|
||||
int ptcache_data_size[] = {
|
||||
sizeof(int), // BPHYS_DATA_INDEX
|
||||
3 * sizeof(float), // BPHYS_DATA_LOCATION:
|
||||
3 * sizeof(float), // BPHYS_DATA_VELOCITY:
|
||||
4 * sizeof(float), // BPHYS_DATA_ROTATION:
|
||||
3 * sizeof(float), // BPHYS_DATA_AVELOCITY: /* also BPHYS_DATA_XCONST */
|
||||
sizeof(float), // BPHYS_DATA_SIZE:
|
||||
3 * sizeof(float), // BPHYS_DATA_TIMES:
|
||||
sizeof(BoidData) // case BPHYS_DATA_BOIDS:
|
||||
};
|
||||
|
||||
/* Common functions */
|
||||
static int ptcache_read_basic_header(PTCacheFile *pf)
|
||||
{
|
||||
@@ -110,8 +124,8 @@ static int ptcache_write_softbody(int index, void *soft_v, void **data)
|
||||
SoftBody *soft= soft_v;
|
||||
BodyPoint *bp = soft->bpoint + index;
|
||||
|
||||
ptcache_data_from(data, BPHYS_DATA_LOCATION, bp->pos);
|
||||
ptcache_data_from(data, BPHYS_DATA_VELOCITY, bp->vec);
|
||||
PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, bp->pos);
|
||||
PTCACHE_DATA_FROM(data, BPHYS_DATA_VELOCITY, bp->vec);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -125,8 +139,8 @@ static void ptcache_read_softbody(int index, void *soft_v, void **data, float fr
|
||||
memcpy(bp->vec, data + 3, 3 * sizeof(float));
|
||||
}
|
||||
else {
|
||||
ptcache_data_to(data, BPHYS_DATA_LOCATION, 0, bp->pos);
|
||||
ptcache_data_to(data, BPHYS_DATA_VELOCITY, 0, bp->vec);
|
||||
PTCACHE_DATA_TO(data, BPHYS_DATA_LOCATION, 0, bp->pos);
|
||||
PTCACHE_DATA_TO(data, BPHYS_DATA_VELOCITY, 0, bp->vec);
|
||||
}
|
||||
}
|
||||
static void ptcache_interpolate_softbody(int index, void *soft_v, void **data, float frs_sec, float cfra, float cfra1, float cfra2, float *old_data)
|
||||
@@ -181,25 +195,25 @@ static int ptcache_write_particle(int index, void *psys_v, void **data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ptcache_data_from(data, BPHYS_DATA_INDEX, &index);
|
||||
ptcache_data_from(data, BPHYS_DATA_LOCATION, pa->state.co);
|
||||
ptcache_data_from(data, BPHYS_DATA_VELOCITY, pa->state.vel);
|
||||
ptcache_data_from(data, BPHYS_DATA_ROTATION, pa->state.rot);
|
||||
ptcache_data_from(data, BPHYS_DATA_AVELOCITY, pa->state.ave);
|
||||
ptcache_data_from(data, BPHYS_DATA_SIZE, &pa->size);
|
||||
ptcache_data_from(data, BPHYS_DATA_TIMES, times);
|
||||
PTCACHE_DATA_FROM(data, BPHYS_DATA_INDEX, &index);
|
||||
PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, pa->state.co);
|
||||
PTCACHE_DATA_FROM(data, BPHYS_DATA_VELOCITY, pa->state.vel);
|
||||
PTCACHE_DATA_FROM(data, BPHYS_DATA_ROTATION, pa->state.rot);
|
||||
PTCACHE_DATA_FROM(data, BPHYS_DATA_AVELOCITY, pa->state.ave);
|
||||
PTCACHE_DATA_FROM(data, BPHYS_DATA_SIZE, &pa->size);
|
||||
PTCACHE_DATA_FROM(data, BPHYS_DATA_TIMES, times);
|
||||
|
||||
if(boid)
|
||||
ptcache_data_from(data, BPHYS_DATA_BOIDS, &boid->data);
|
||||
PTCACHE_DATA_FROM(data, BPHYS_DATA_BOIDS, &boid->data);
|
||||
|
||||
return 1;
|
||||
}
|
||||
void BKE_ptcache_make_particle_key(ParticleKey *key, int index, void **data, float time)
|
||||
{
|
||||
ptcache_data_to(data, BPHYS_DATA_LOCATION, index, key->co);
|
||||
ptcache_data_to(data, BPHYS_DATA_VELOCITY, index, key->vel);
|
||||
ptcache_data_to(data, BPHYS_DATA_ROTATION, index, key->rot);
|
||||
ptcache_data_to(data, BPHYS_DATA_AVELOCITY, index, key->ave);
|
||||
PTCACHE_DATA_TO(data, BPHYS_DATA_LOCATION, index, key->co);
|
||||
PTCACHE_DATA_TO(data, BPHYS_DATA_VELOCITY, index, key->vel);
|
||||
PTCACHE_DATA_TO(data, BPHYS_DATA_ROTATION, index, key->rot);
|
||||
PTCACHE_DATA_TO(data, BPHYS_DATA_AVELOCITY, index, key->ave);
|
||||
key->time = time;
|
||||
}
|
||||
static void ptcache_read_particle(int index, void *psys_v, void **data, float frs_sec, float cfra, float *old_data)
|
||||
@@ -220,18 +234,18 @@ static void ptcache_read_particle(int index, void *psys_v, void **data, float fr
|
||||
BKE_ptcache_make_particle_key(&pa->state, 0, data, cfra);
|
||||
|
||||
if(data[BPHYS_DATA_SIZE])
|
||||
ptcache_data_to(data, BPHYS_DATA_SIZE, 0, &pa->size);
|
||||
PTCACHE_DATA_TO(data, BPHYS_DATA_SIZE, 0, &pa->size);
|
||||
|
||||
if(data[BPHYS_DATA_TIMES]) {
|
||||
float times[3];
|
||||
ptcache_data_to(data, BPHYS_DATA_TIMES, 0, ×);
|
||||
PTCACHE_DATA_TO(data, BPHYS_DATA_TIMES, 0, ×);
|
||||
pa->time = times[0];
|
||||
pa->dietime = times[1];
|
||||
pa->lifetime = times[2];
|
||||
}
|
||||
|
||||
if(boid)
|
||||
ptcache_data_to(data, BPHYS_DATA_BOIDS, 0, &boid->data);
|
||||
PTCACHE_DATA_TO(data, BPHYS_DATA_BOIDS, 0, &boid->data);
|
||||
|
||||
/* determine velocity from previous location */
|
||||
if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_VELOCITY]) {
|
||||
@@ -307,6 +321,132 @@ static int ptcache_totwrite_particle(void *psys_v)
|
||||
return totwrite;
|
||||
}
|
||||
|
||||
//static int ptcache_write_particle_stream(PTCacheFile *pf, PTCacheMem *pm, void *psys_v)
|
||||
//{
|
||||
// ParticleSystem *psys= psys_v;
|
||||
// ParticleData *pa = psys->particles;
|
||||
// BoidParticle *boid = NULL;
|
||||
// float times[3];
|
||||
// int i = 0;
|
||||
//
|
||||
// if(!pf && !pm)
|
||||
// return 0;
|
||||
//
|
||||
// for(i=0; i<psys->totpart; i++, pa++) {
|
||||
//
|
||||
// if(data[BPHYS_DATA_INDEX]) {
|
||||
// int step = psys->pointcache->step;
|
||||
// /* No need to store unborn or died particles */
|
||||
// if(pa->time - step > pa->state.time || pa->dietime + step < pa->state.time)
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// times[0] = pa->time;
|
||||
// times[1] = pa->dietime;
|
||||
// times[2] = pa->lifetime;
|
||||
//
|
||||
// PTCACHE_DATA_FROM(data, BPHYS_DATA_INDEX, &index);
|
||||
// PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, pa->state.co);
|
||||
// PTCACHE_DATA_FROM(data, BPHYS_DATA_VELOCITY, pa->state.vel);
|
||||
// PTCACHE_DATA_FROM(data, BPHYS_DATA_ROTATION, pa->state.rot);
|
||||
// PTCACHE_DATA_FROM(data, BPHYS_DATA_AVELOCITY, pa->state.ave);
|
||||
// PTCACHE_DATA_FROM(data, BPHYS_DATA_SIZE, &pa->size);
|
||||
// PTCACHE_DATA_FROM(data, BPHYS_DATA_TIMES, times);
|
||||
//
|
||||
// boid = (psys->part->phystype == PART_PHYS_BOIDS) ? pa->boid : NULL;
|
||||
// if(boid)
|
||||
// PTCACHE_DATA_FROM(data, BPHYS_DATA_BOIDS, &boid->data);
|
||||
//
|
||||
// if(pf && !ptcache_file_write_data(pf))
|
||||
// return 0;
|
||||
//
|
||||
// if(pm)
|
||||
// BKE_ptcache_mem_incr_pointers(pm);
|
||||
// }
|
||||
//
|
||||
// return 1;
|
||||
//}
|
||||
//static void ptcache_read_particle_stream(PTCacheFile *pf, PTCacheMem *pm, void *psys_v, void **data, float frs_sec, float cfra, float *old_data)
|
||||
//{
|
||||
// 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));
|
||||
//
|
||||
// if(old_data){
|
||||
// /* old format cache */
|
||||
// memcpy(&pa->state, old_data, sizeof(ParticleKey));
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// BKE_ptcache_make_particle_key(&pa->state, 0, data, cfra);
|
||||
//
|
||||
// if(data[BPHYS_DATA_SIZE])
|
||||
// PTCACHE_DATA_TO(data, BPHYS_DATA_SIZE, 0, &pa->size);
|
||||
//
|
||||
// if(data[BPHYS_DATA_TIMES]) {
|
||||
// float times[3];
|
||||
// PTCACHE_DATA_TO(data, BPHYS_DATA_TIMES, 0, ×);
|
||||
// pa->time = times[0];
|
||||
// pa->dietime = times[1];
|
||||
// pa->lifetime = times[2];
|
||||
// }
|
||||
//
|
||||
// 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]) {
|
||||
// if(cfra > pa->prev_state.time) {
|
||||
// VecSubf(pa->state.vel, pa->state.co, pa->prev_state.co);
|
||||
// VecMulf(pa->state.vel, (cfra - pa->prev_state.time) / frs_sec);
|
||||
// }
|
||||
// else {
|
||||
// VecSubf(pa->state.vel, pa->prev_state.co, pa->state.co);
|
||||
// VecMulf(pa->state.vel, (pa->prev_state.time - cfra) / frs_sec);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /* determine rotation from velocity */
|
||||
// if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_ROTATION]) {
|
||||
// vectoquat(pa->state.vel, OB_POSX, OB_POSZ, pa->state.rot);
|
||||
// }
|
||||
//}
|
||||
//static void ptcache_interpolate_particle_stream(int index, void *psys_v, void **data, float frs_sec, float cfra, float cfra1, float cfra2, float *old_data)
|
||||
//{
|
||||
// ParticleSystem *psys= psys_v;
|
||||
// ParticleData *pa = psys->particles + index;
|
||||
// ParticleKey keys[4];
|
||||
// float dfra;
|
||||
//
|
||||
// cfra = MIN2(cfra, pa->dietime);
|
||||
// cfra1 = MIN2(cfra1, pa->dietime);
|
||||
// cfra2 = MIN2(cfra2, pa->dietime);
|
||||
//
|
||||
// if(cfra1 == cfra2)
|
||||
// return;
|
||||
//
|
||||
// memcpy(keys+1, &pa->state, sizeof(ParticleKey));
|
||||
// if(old_data)
|
||||
// memcpy(keys+2, old_data, sizeof(ParticleKey));
|
||||
// else
|
||||
// BKE_ptcache_make_particle_key(keys+2, 0, data, cfra2);
|
||||
//
|
||||
// dfra = cfra2 - cfra1;
|
||||
//
|
||||
// VecMulf(keys[1].vel, dfra / frs_sec);
|
||||
// VecMulf(keys[2].vel, dfra / frs_sec);
|
||||
//
|
||||
// psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, &pa->state, 1);
|
||||
// QuatInterpol(pa->state.rot, keys[1].rot,keys[2].rot, (cfra - cfra1) / dfra);
|
||||
//
|
||||
// VecMulf(pa->state.vel, frs_sec / dfra);
|
||||
//
|
||||
// pa->state.time = cfra;
|
||||
//}
|
||||
//
|
||||
/* Cloth functions */
|
||||
static int ptcache_write_cloth(int index, void *cloth_v, void **data)
|
||||
{
|
||||
@@ -314,9 +454,9 @@ static int ptcache_write_cloth(int index, void *cloth_v, void **data)
|
||||
Cloth *cloth= clmd->clothObject;
|
||||
ClothVertex *vert = cloth->verts + index;
|
||||
|
||||
ptcache_data_from(data, BPHYS_DATA_LOCATION, vert->x);
|
||||
ptcache_data_from(data, BPHYS_DATA_VELOCITY, vert->v);
|
||||
ptcache_data_from(data, BPHYS_DATA_XCONST, vert->xconst);
|
||||
PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, vert->x);
|
||||
PTCACHE_DATA_FROM(data, BPHYS_DATA_VELOCITY, vert->v);
|
||||
PTCACHE_DATA_FROM(data, BPHYS_DATA_XCONST, vert->xconst);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -332,9 +472,9 @@ static void ptcache_read_cloth(int index, void *cloth_v, void **data, float frs_
|
||||
memcpy(vert->v, data + 6, 3 * sizeof(float));
|
||||
}
|
||||
else {
|
||||
ptcache_data_to(data, BPHYS_DATA_LOCATION, 0, vert->x);
|
||||
ptcache_data_to(data, BPHYS_DATA_VELOCITY, 0, vert->v);
|
||||
ptcache_data_to(data, BPHYS_DATA_XCONST, 0, vert->xconst);
|
||||
PTCACHE_DATA_TO(data, BPHYS_DATA_LOCATION, 0, vert->x);
|
||||
PTCACHE_DATA_TO(data, BPHYS_DATA_VELOCITY, 0, vert->v);
|
||||
PTCACHE_DATA_TO(data, BPHYS_DATA_XCONST, 0, vert->xconst);
|
||||
}
|
||||
}
|
||||
static void ptcache_interpolate_cloth(int index, void *cloth_v, void **data, float frs_sec, float cfra, float cfra1, float cfra2, float *old_data)
|
||||
@@ -987,7 +1127,7 @@ static int ptcache_file_read_data(PTCacheFile *pf)
|
||||
int i;
|
||||
|
||||
for(i=0; i<BPHYS_TOT_DATA; i++) {
|
||||
if(pf->data_types & (1<<i) && !ptcache_file_read(pf, pf->cur[i], 1, BKE_ptcache_data_size(i)))
|
||||
if(pf->data_types & (1<<i) && !ptcache_file_read(pf, pf->cur[i], 1, ptcache_data_size[i]))
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -998,7 +1138,7 @@ static int ptcache_file_write_data(PTCacheFile *pf)
|
||||
int i;
|
||||
|
||||
for(i=0; i<BPHYS_TOT_DATA; i++) {
|
||||
if(pf->data_types & (1<<i) && !ptcache_file_write(pf, pf->cur[i], 1, BKE_ptcache_data_size(i)))
|
||||
if(pf->data_types & (1<<i) && !ptcache_file_write(pf, pf->cur[i], 1, ptcache_data_size[i]))
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1045,38 +1185,7 @@ static int ptcache_file_write_header_begin(PTCacheFile *pf)
|
||||
/* Data pointer handling */
|
||||
int BKE_ptcache_data_size(int data_type)
|
||||
{
|
||||
switch(data_type) {
|
||||
case BPHYS_DATA_INDEX:
|
||||
return sizeof(int);
|
||||
case BPHYS_DATA_LOCATION:
|
||||
case BPHYS_DATA_VELOCITY:
|
||||
case BPHYS_DATA_AVELOCITY: /* also BPHYS_DATA_XCONST */
|
||||
case BPHYS_DATA_TIMES:
|
||||
return 3 * sizeof(float);
|
||||
case BPHYS_DATA_ROTATION:
|
||||
return 4 * sizeof(float);
|
||||
case BPHYS_DATA_SIZE:
|
||||
return sizeof(float);
|
||||
case BPHYS_DATA_BOIDS:
|
||||
return sizeof(BoidData);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
static void ptcache_data_to(void **data, int type, int index, void *to)
|
||||
{
|
||||
if(data[type]) {
|
||||
if(index)
|
||||
memcpy(to, (char*)data[type] + index * BKE_ptcache_data_size(type), BKE_ptcache_data_size(type));
|
||||
else
|
||||
memcpy(to, data[type], BKE_ptcache_data_size(type));
|
||||
}
|
||||
}
|
||||
|
||||
static void ptcache_data_from(void **data, int type, void *from)
|
||||
{
|
||||
if(data[type])
|
||||
memcpy(data[type], from, BKE_ptcache_data_size(type));
|
||||
return ptcache_data_size[data_type];
|
||||
}
|
||||
|
||||
static void ptcache_file_init_pointers(PTCacheFile *pf)
|
||||
@@ -1108,7 +1217,7 @@ void BKE_ptcache_mem_incr_pointers(PTCacheMem *pm)
|
||||
|
||||
for(i=0; i<BPHYS_TOT_DATA; i++) {
|
||||
if(pm->cur[i])
|
||||
pm->cur[i] = (char*)pm->cur[i] + BKE_ptcache_data_size(i);
|
||||
pm->cur[i] = (char*)pm->cur[i] + ptcache_data_size[i];
|
||||
}
|
||||
}
|
||||
static void ptcache_alloc_data(PTCacheMem *pm)
|
||||
@@ -1119,7 +1228,7 @@ static void ptcache_alloc_data(PTCacheMem *pm)
|
||||
|
||||
for(i=0; i<BPHYS_TOT_DATA; i++) {
|
||||
if(data_types & (1<<i))
|
||||
pm->data[i] = MEM_callocN(totpoint * BKE_ptcache_data_size(i), "PTCache Data");
|
||||
pm->data[i] = MEM_callocN(totpoint * ptcache_data_size[i], "PTCache Data");
|
||||
}
|
||||
}
|
||||
static void ptcache_free_data(void *data[])
|
||||
@@ -1136,7 +1245,7 @@ static void ptcache_copy_data(void *from[], void *to[])
|
||||
int i;
|
||||
for(i=0; i<BPHYS_TOT_DATA; i++) {
|
||||
if(from[i])
|
||||
memcpy(to[i], from[i], BKE_ptcache_data_size(i));
|
||||
memcpy(to[i], from[i], ptcache_data_size[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3163,6 +3163,8 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
|
||||
psys->pathcachebufs.first = psys->pathcachebufs.last = 0;
|
||||
psys->childcachebufs.first = psys->childcachebufs.last = 0;
|
||||
psys->reactevents.first = psys->reactevents.last = 0;
|
||||
psys->frand = NULL;
|
||||
psys->pdd = NULL;
|
||||
|
||||
direct_link_pointcache_list(fd, &psys->ptcaches, &psys->pointcache);
|
||||
|
||||
|
||||
@@ -1184,6 +1184,9 @@ void PE_update_object(Scene *scene, Object *ob, int useflag)
|
||||
point->flag &= ~PEP_EDIT_RECALC;
|
||||
}
|
||||
|
||||
if(edit->psys)
|
||||
edit->psys->flag &= ~PSYS_HAIR_UPDATED;
|
||||
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
}
|
||||
|
||||
@@ -1761,6 +1764,7 @@ static void rekey_particle(PEData *data, int pa_index)
|
||||
{
|
||||
PTCacheEdit *edit= data->edit;
|
||||
ParticleSystem *psys= edit->psys;
|
||||
ParticleSimulationData sim = {data->scene, data->ob, edit->psys, NULL};
|
||||
ParticleData *pa= psys->particles + pa_index;
|
||||
PTCacheEditPoint *point = edit->points + pa_index;
|
||||
ParticleKey state;
|
||||
@@ -1785,7 +1789,7 @@ static void rekey_particle(PEData *data, int pa_index)
|
||||
/* interpolate new keys from old ones */
|
||||
for(k=1,key++; k<data->totrekey-1; k++,key++) {
|
||||
state.time= (float)k / (float)(data->totrekey-1);
|
||||
psys_get_particle_on_path(data->scene, data->ob, psys, pa_index, &state, 0);
|
||||
psys_get_particle_on_path(&sim, pa_index, &state, 0);
|
||||
VECCOPY(key->co, state.co);
|
||||
key->time= sta + k * dval;
|
||||
}
|
||||
@@ -1853,6 +1857,7 @@ static void rekey_particle_to_time(Scene *scene, Object *ob, int pa_index, float
|
||||
{
|
||||
PTCacheEdit *edit= PE_get_current(scene, ob);
|
||||
ParticleSystem *psys;
|
||||
ParticleSimulationData sim = {scene, ob, edit ? edit->psys : NULL, NULL};
|
||||
ParticleData *pa;
|
||||
ParticleKey state;
|
||||
HairKey *new_keys, *key;
|
||||
@@ -1872,7 +1877,7 @@ static void rekey_particle_to_time(Scene *scene, Object *ob, int pa_index, float
|
||||
/* interpolate new keys from old ones (roots stay the same) */
|
||||
for(k=1, key++; k < pa->totkey; k++, key++) {
|
||||
state.time= path_time * (float)k / (float)(pa->totkey-1);
|
||||
psys_get_particle_on_path(scene, ob, psys, pa_index, &state, 0);
|
||||
psys_get_particle_on_path(&sim, pa_index, &state, 0);
|
||||
VECCOPY(key->co, state.co);
|
||||
}
|
||||
|
||||
@@ -2044,6 +2049,7 @@ static void subdivide_particle(PEData *data, int pa_index)
|
||||
{
|
||||
PTCacheEdit *edit= data->edit;
|
||||
ParticleSystem *psys= edit->psys;
|
||||
ParticleSimulationData sim = {data->scene, data->ob, edit->psys, NULL};
|
||||
ParticleData *pa= psys->particles + pa_index;
|
||||
PTCacheEditPoint *point = edit->points + pa_index;
|
||||
ParticleKey state;
|
||||
@@ -2083,7 +2089,7 @@ static void subdivide_particle(PEData *data, int pa_index)
|
||||
if(ekey->flag & PEK_SELECT && (ekey+1)->flag & PEK_SELECT) {
|
||||
nkey->time= (key->time + (key+1)->time)*0.5f;
|
||||
state.time= (endtime != 0.0f)? nkey->time/endtime: 0.0f;
|
||||
psys_get_particle_on_path(data->scene, data->ob, psys, pa_index, &state, 0);
|
||||
psys_get_particle_on_path(&sim, pa_index, &state, 0);
|
||||
VECCOPY(nkey->co, state.co);
|
||||
|
||||
nekey->co= nkey->co;
|
||||
@@ -2875,12 +2881,13 @@ static void brush_add(PEData *data, short number)
|
||||
ParticleSystem *psys= edit->psys;
|
||||
ParticleData *add_pars= MEM_callocN(number*sizeof(ParticleData),"ParticleData add");
|
||||
ParticleSystemModifierData *psmd= psys_get_modifier(ob,psys);
|
||||
ParticleSimulationData sim = {scene, ob, psys, psmd};
|
||||
ParticleEditSettings *pset= PE_settings(scene);
|
||||
int i, k, n= 0, totpart= psys->totpart;
|
||||
short mco[2];
|
||||
short dmx= 0, dmy= 0;
|
||||
float co1[3], co2[3], min_d, imat[4][4];
|
||||
float framestep, timestep= psys_get_timestep(psys->part);
|
||||
float framestep, timestep= psys_get_timestep(&sim);
|
||||
short size= pset->brush[PE_BRUSH_ADD].size;
|
||||
short size2= size*size;
|
||||
DerivedMesh *dm=0;
|
||||
@@ -2975,8 +2982,8 @@ static void brush_add(PEData *data, short number)
|
||||
}
|
||||
|
||||
pa->size= 1.0f;
|
||||
initialize_particle(pa,i,ob,psys,psmd);
|
||||
reset_particle(scene, pa,psys,psmd,ob,0.0,1.0,0,0,0);
|
||||
initialize_particle(&sim, pa,i);
|
||||
reset_particle(&sim, pa, 0.0, 1.0);
|
||||
point->flag |= PEP_EDIT_RECALC;
|
||||
if(pset->flag & PE_X_MIRROR)
|
||||
point->flag |= PEP_TAG; /* signal for duplicate */
|
||||
@@ -3013,18 +3020,18 @@ static void brush_add(PEData *data, short number)
|
||||
hkey->time= pa->time + k * framestep;
|
||||
|
||||
key[0].time= hkey->time/ 100.0f;
|
||||
psys_get_particle_on_path(scene, ob, psys, ptn[0].index, key, 0);
|
||||
psys_get_particle_on_path(&sim, ptn[0].index, key, 0);
|
||||
VecMulf(key[0].co, weight[0]);
|
||||
|
||||
if(maxw>1) {
|
||||
key[1].time= key[0].time;
|
||||
psys_get_particle_on_path(scene, ob, psys, ptn[1].index, key + 1, 0);
|
||||
psys_get_particle_on_path(&sim, ptn[1].index, key + 1, 0);
|
||||
VecMulf(key[1].co, weight[1]);
|
||||
VECADD(key[0].co, key[0].co, key[1].co);
|
||||
|
||||
if(maxw>2) {
|
||||
key[2].time= key[0].time;
|
||||
psys_get_particle_on_path(scene, ob, psys, ptn[2].index, key + 2, 0);
|
||||
psys_get_particle_on_path(&sim, ptn[2].index, key + 2, 0);
|
||||
VecMulf(key[2].co, weight[2]);
|
||||
VECADD(key[0].co, key[0].co, key[2].co);
|
||||
}
|
||||
|
||||
@@ -2974,13 +2974,6 @@ static void view3d_particle_text_draw(View3D *v3d, ARegion *ar)
|
||||
if(pstrings.first)
|
||||
BLI_freelistN(&pstrings);
|
||||
}
|
||||
typedef struct ParticleDrawData {
|
||||
float *vdata, *vd;
|
||||
float *ndata, *nd;
|
||||
float *cdata, *cd;
|
||||
float *vedata, *ved;
|
||||
float *ma_r, *ma_g, *ma_b;
|
||||
} ParticleDrawData;
|
||||
static void draw_particle(ParticleKey *state, int draw_as, short draw, float pixsize, float imat[4][4], float *draw_line, ParticleBillboardData *bb, ParticleDrawData *pdd)
|
||||
{
|
||||
float vec[3], vec2[3];
|
||||
@@ -3145,7 +3138,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
ParticleData *pars, *pa;
|
||||
ParticleKey state, *states=0;
|
||||
ParticleBillboardData bb;
|
||||
ParticleDrawData pdd;
|
||||
ParticleSimulationData sim = {scene, ob, psys, NULL};
|
||||
ParticleDrawData *pdd = psys->pdd;
|
||||
Material *ma;
|
||||
float vel[3], imat[4][4];
|
||||
float timestep, pixsize=1.0, pa_size, r_tilt, r_length;
|
||||
@@ -3176,9 +3170,11 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
if(part->draw_as==PART_DRAW_NOT) return;
|
||||
|
||||
/* 2. */
|
||||
sim.psmd = psmd = psys_get_modifier(ob,psys);
|
||||
|
||||
if(part->phystype==PART_PHYS_KEYED){
|
||||
if(psys->flag&PSYS_KEYED){
|
||||
psys_count_keyed_targets(ob,psys);
|
||||
psys_count_keyed_targets(&sim);
|
||||
if(psys->totkeyed==0)
|
||||
return;
|
||||
}
|
||||
@@ -3196,8 +3192,6 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
totchild=0;
|
||||
else
|
||||
totchild=psys->totchild*part->disp/100;
|
||||
|
||||
memset(&pdd, 0, sizeof(ParticleDrawData));
|
||||
|
||||
ma= give_current_material(ob,part->omat);
|
||||
|
||||
@@ -3212,18 +3206,16 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
ma_g = ma->g;
|
||||
ma_b = ma->b;
|
||||
|
||||
pdd.ma_r = &ma_r;
|
||||
pdd.ma_g = &ma_g;
|
||||
pdd.ma_b = &ma_b;
|
||||
pdd->ma_r = &ma_r;
|
||||
pdd->ma_g = &ma_g;
|
||||
pdd->ma_b = &ma_b;
|
||||
|
||||
create_cdata = 1;
|
||||
}
|
||||
else
|
||||
cpack(0);
|
||||
|
||||
psmd= psys_get_modifier(ob,psys);
|
||||
|
||||
timestep= psys_get_timestep(part);
|
||||
timestep= psys_get_timestep(&sim);
|
||||
|
||||
if( (base->flag & OB_FROMDUPLI) && (ob->flag & OB_FROMGROUP) ) {
|
||||
float mat[4][4];
|
||||
@@ -3317,54 +3309,65 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
/* 4. */
|
||||
if(draw_as && draw_as!=PART_DRAW_PATH) {
|
||||
int tot_vec_size = (totpart + totchild) * 3 * sizeof(float);
|
||||
|
||||
|
||||
if(!pdd)
|
||||
pdd = psys->pdd = MEM_callocN(sizeof(ParticleDrawData), "ParticlDrawData");
|
||||
|
||||
if(part->draw_as == PART_DRAW_REND && part->trail_count > 1) {
|
||||
tot_vec_size *= part->trail_count;
|
||||
psys_make_temp_pointcache(ob, psys);
|
||||
}
|
||||
|
||||
if(pdd->tot_vec_size != tot_vec_size)
|
||||
psys_free_pdd(psys);
|
||||
|
||||
if(draw_as!=PART_DRAW_CIRC) {
|
||||
switch(draw_as) {
|
||||
case PART_DRAW_AXIS:
|
||||
case PART_DRAW_CROSS:
|
||||
if(draw_as != PART_DRAW_CROSS || create_cdata)
|
||||
pdd.cdata = MEM_callocN(tot_vec_size * 6, "particle_cdata");
|
||||
pdd.vdata = MEM_callocN(tot_vec_size * 6, "particle_vdata");
|
||||
if(!pdd->cdata) pdd->cdata = MEM_callocN(tot_vec_size * 6, "particle_cdata");
|
||||
if(!pdd->vdata) pdd->vdata = MEM_callocN(tot_vec_size * 6, "particle_vdata");
|
||||
break;
|
||||
case PART_DRAW_LINE:
|
||||
if(create_cdata)
|
||||
pdd.cdata = MEM_callocN(tot_vec_size * 2, "particle_cdata");
|
||||
pdd.vdata = MEM_callocN(tot_vec_size * 2, "particle_vdata");
|
||||
if(!pdd->cdata) pdd->cdata = MEM_callocN(tot_vec_size * 2, "particle_cdata");
|
||||
if(!pdd->vdata) pdd->vdata = MEM_callocN(tot_vec_size * 2, "particle_vdata");
|
||||
break;
|
||||
case PART_DRAW_BB:
|
||||
if(create_cdata)
|
||||
pdd.cdata = MEM_callocN(tot_vec_size * 4, "particle_cdata");
|
||||
pdd.vdata = MEM_callocN(tot_vec_size * 4, "particle_vdata");
|
||||
pdd.ndata = MEM_callocN(tot_vec_size * 4, "particle_vdata");
|
||||
if(!pdd->cdata) pdd->cdata = MEM_callocN(tot_vec_size * 4, "particle_cdata");
|
||||
if(!pdd->vdata) pdd->vdata = MEM_callocN(tot_vec_size * 4, "particle_vdata");
|
||||
if(!pdd->ndata) pdd->ndata = MEM_callocN(tot_vec_size * 4, "particle_vdata");
|
||||
break;
|
||||
default:
|
||||
if(create_cdata)
|
||||
pdd.cdata=MEM_callocN(tot_vec_size, "particle_cdata");
|
||||
pdd.vdata=MEM_callocN(tot_vec_size, "particle_vdata");
|
||||
if(!pdd->cdata) pdd->cdata=MEM_callocN(tot_vec_size, "particle_cdata");
|
||||
if(!pdd->vdata) pdd->vdata=MEM_callocN(tot_vec_size, "particle_vdata");
|
||||
}
|
||||
}
|
||||
|
||||
if(part->draw & PART_DRAW_VEL && draw_as != PART_DRAW_LINE) {
|
||||
pdd.vedata = MEM_callocN(tot_vec_size * 2, "particle_vedata");
|
||||
if(!pdd->vedata) pdd->vedata = MEM_callocN(tot_vec_size * 2, "particle_vedata");
|
||||
need_v = 1;
|
||||
}
|
||||
|
||||
pdd.vd= pdd.vdata;
|
||||
pdd.ved= pdd.vedata;
|
||||
pdd.cd= pdd.cdata;
|
||||
pdd.nd= pdd.ndata;
|
||||
pdd->vd= pdd->vdata;
|
||||
pdd->ved= pdd->vedata;
|
||||
pdd->cd= pdd->cdata;
|
||||
pdd->nd= pdd->ndata;
|
||||
pdd->tot_vec_size= tot_vec_size;
|
||||
|
||||
psys->lattice= psys_get_lattice(scene, ob, psys);
|
||||
psys->lattice= psys_get_lattice(&sim);
|
||||
}
|
||||
|
||||
if(draw_as){
|
||||
/* 5. */
|
||||
for(a=0,pa=pars; a<totpart+totchild; a++, pa++){
|
||||
if((pdd->flag & PARTICLE_DRAW_DATA_UPDATED)
|
||||
&& (pdd->vedata || part->draw & (PART_DRAW_SIZE|PART_DRAW_NUM|PART_DRAW_HEALTH))==0) {
|
||||
totpoint = pdd->totpoint; /* draw data is up to date */
|
||||
}
|
||||
else for(a=0,pa=pars; a<totpart+totchild; a++, pa++){
|
||||
/* setup per particle individual stuff */
|
||||
if(a<totpart){
|
||||
if(totchild && (part->draw&PART_DRAW_PARENT)==0) continue;
|
||||
@@ -3374,9 +3377,8 @@ 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) {
|
||||
if(part->phystype==PART_PHYS_BOIDS)
|
||||
pa_health = pa->boid->data.health;
|
||||
}
|
||||
else
|
||||
pa_health = -1.0;
|
||||
|
||||
@@ -3411,10 +3413,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
}
|
||||
#endif // XXX old animation system
|
||||
|
||||
BLI_srandom(psys->seed+a);
|
||||
|
||||
r_tilt = 2.0f*(BLI_frand() - 0.5f);
|
||||
r_length = BLI_frand();
|
||||
r_tilt = 2.0f*(PSYS_FRAND(a + 21) - 0.5f);
|
||||
r_length = PSYS_FRAND(a + 22);
|
||||
}
|
||||
else{
|
||||
ChildParticle *cpa= &psys->child[a-totpart];
|
||||
@@ -3445,8 +3445,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
|
||||
pa_health = -1.0;
|
||||
|
||||
r_tilt = 2.0f * cpa->rand[2];
|
||||
r_length = cpa->rand[1];
|
||||
r_tilt = 2.0f*(PSYS_FRAND(a + 21) - 0.5f);
|
||||
r_length = PSYS_FRAND(a + 22);
|
||||
}
|
||||
|
||||
if(draw_as!=PART_DRAW_PATH){
|
||||
@@ -3468,7 +3468,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
continue;
|
||||
|
||||
state.time = (part->draw & PART_ABS_PATH_TIME) ? -ct : -(pa_birthtime + ct * (pa_dietime - pa_birthtime));
|
||||
psys_get_particle_on_path(scene,ob,psys,a,&state,need_v);
|
||||
psys_get_particle_on_path(&sim,a,&state,need_v);
|
||||
|
||||
if(psys->parent)
|
||||
Mat4MulVecfl(psys->parent->obmat, state.co);
|
||||
@@ -3480,7 +3480,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
bb.time = ct;
|
||||
}
|
||||
|
||||
draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, &pdd);
|
||||
draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, psys->pdd);
|
||||
|
||||
totpoint++;
|
||||
drawn = 1;
|
||||
@@ -3489,7 +3489,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
else
|
||||
{
|
||||
state.time=cfra;
|
||||
if(psys_get_particle_state(scene,ob,psys,a,&state,0)){
|
||||
if(psys_get_particle_state(&sim,a,&state,0)){
|
||||
if(psys->parent)
|
||||
Mat4MulVecfl(psys->parent->obmat, state.co);
|
||||
|
||||
@@ -3500,7 +3500,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
bb.time = pa_time;
|
||||
}
|
||||
|
||||
draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, &pdd);
|
||||
draw_particle(&state, draw_as, part->draw, pixsize, imat, part->draw_line, &bb, pdd);
|
||||
|
||||
totpoint++;
|
||||
drawn = 1;
|
||||
@@ -3510,13 +3510,13 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
if(drawn) {
|
||||
/* additional things to draw for each particle */
|
||||
/* (velocity, size and number) */
|
||||
if(pdd.vedata){
|
||||
VECCOPY(pdd.ved,state.co);
|
||||
pdd.ved+=3;
|
||||
if(pdd->vedata){
|
||||
VECCOPY(pdd->ved,state.co);
|
||||
pdd->ved+=3;
|
||||
VECCOPY(vel,state.vel);
|
||||
VecMulf(vel,timestep);
|
||||
VECADD(pdd.ved,state.co,vel);
|
||||
pdd.ved+=3;
|
||||
VECADD(pdd->ved,state.co,vel);
|
||||
pdd->ved+=3;
|
||||
|
||||
totve++;
|
||||
}
|
||||
@@ -3628,17 +3628,17 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
/* setup created data arrays */
|
||||
if(pdd.vdata){
|
||||
if(pdd->vdata){
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 0, pdd.vdata);
|
||||
glVertexPointer(3, GL_FLOAT, 0, pdd->vdata);
|
||||
}
|
||||
else
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
/* billboards are drawn this way */
|
||||
if(pdd.ndata && ob_dt>OB_WIRE){
|
||||
if(pdd->ndata && ob_dt>OB_WIRE){
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glNormalPointer(GL_FLOAT, 0, pdd.ndata);
|
||||
glNormalPointer(GL_FLOAT, 0, pdd->ndata);
|
||||
glEnable(GL_LIGHTING);
|
||||
}
|
||||
else{
|
||||
@@ -3646,9 +3646,9 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
glDisable(GL_LIGHTING);
|
||||
}
|
||||
|
||||
if(pdd.cdata){
|
||||
if(pdd->cdata){
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glColorPointer(3, GL_FLOAT, 0, pdd.cdata);
|
||||
glColorPointer(3, GL_FLOAT, 0, pdd->cdata);
|
||||
}
|
||||
|
||||
/* draw created data arrays */
|
||||
@@ -3670,14 +3670,17 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
glDrawArrays(GL_POINTS, 0, totpoint);
|
||||
break;
|
||||
}
|
||||
|
||||
pdd->flag |= PARTICLE_DRAW_DATA_UPDATED;
|
||||
pdd->totpoint = totpoint;
|
||||
}
|
||||
|
||||
if(pdd.vedata){
|
||||
if(pdd->vedata){
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
cpack(0xC0C0C0);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 0, pdd.vedata);
|
||||
glVertexPointer(3, GL_FLOAT, 0, pdd->vedata);
|
||||
|
||||
glDrawArrays(GL_LINES, 0, 2*totve);
|
||||
}
|
||||
@@ -3694,14 +3697,6 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
|
||||
if(states)
|
||||
MEM_freeN(states);
|
||||
if(pdd.vdata)
|
||||
MEM_freeN(pdd.vdata);
|
||||
if(pdd.vedata)
|
||||
MEM_freeN(pdd.vedata);
|
||||
if(pdd.cdata)
|
||||
MEM_freeN(pdd.cdata);
|
||||
if(pdd.ndata)
|
||||
MEM_freeN(pdd.ndata);
|
||||
|
||||
psys->flag &= ~PSYS_DRAWING;
|
||||
|
||||
@@ -3728,10 +3723,8 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, RegionView3D *rv3d, Obj
|
||||
float *pathcol = NULL, *pcol;
|
||||
|
||||
|
||||
if(edit->psys && edit->psys->flag & PSYS_HAIR_UPDATED) {
|
||||
if(edit->psys && edit->psys->flag & PSYS_HAIR_UPDATED)
|
||||
PE_update_object(scene, ob, 0);
|
||||
edit->psys->flag &= ~PSYS_HAIR_UPDATED;
|
||||
}
|
||||
|
||||
/* create path and child path cache if it doesn't exist already */
|
||||
if(edit->pathcache==0)
|
||||
|
||||
@@ -67,7 +67,7 @@ typedef struct ChildParticle {
|
||||
int pa[4]; /* nearest particles to the child, used for the interpolation */
|
||||
float w[4]; /* interpolation weights for the above particles */
|
||||
float fuv[4], foffset; /* face vertex weights and offset */
|
||||
float rand[3];
|
||||
float rt;
|
||||
} ChildParticle;
|
||||
|
||||
typedef struct ParticleTarget {
|
||||
@@ -234,13 +234,17 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
|
||||
struct ListBase ptcaches;
|
||||
|
||||
struct KDTree *tree; /* used for interactions with self and other systems */
|
||||
|
||||
struct ParticleDrawData *pdd;
|
||||
|
||||
float *frand; /* array of 1024 random floats for fast lookups */
|
||||
}ParticleSystem;
|
||||
|
||||
/* part->type */
|
||||
/* hair is allways baked static in object/geometry space */
|
||||
/* other types (normal particles) are in global space and not static baked */
|
||||
#define PART_EMITTER 0
|
||||
#define PART_REACTOR 1
|
||||
//#define PART_REACTOR 1
|
||||
#define PART_HAIR 2
|
||||
#define PART_FLUID 3
|
||||
|
||||
@@ -325,7 +329,7 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
|
||||
#define PART_DRAW_EMITTER 8 /* render emitter also */
|
||||
#define PART_DRAW_HEALTH 16
|
||||
#define PART_ABS_PATH_TIME 32
|
||||
//#define PART_DRAW_TRAIL 64
|
||||
//#define PART_DRAW_TRAIL 64 /* deprecated */
|
||||
#define PART_DRAW_BB_LOCK 128
|
||||
#define PART_DRAW_PARENT 256
|
||||
#define PART_DRAW_NUM 512
|
||||
@@ -422,13 +426,13 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
|
||||
#define PSYS_HAIR_DONE 512
|
||||
#define PSYS_KEYED 1024
|
||||
#define PSYS_EDITED 2048
|
||||
//#define PSYS_PROTECT_CACHE 4096
|
||||
//#define PSYS_PROTECT_CACHE 4096 /* deprecated */
|
||||
#define PSYS_DISABLED 8192
|
||||
|
||||
/* pars->flag */
|
||||
#define PARS_UNEXIST 1
|
||||
#define PARS_NO_DISP 2
|
||||
//#define PARS_STICKY 4
|
||||
//#define PARS_STICKY 4 /* deprecated */
|
||||
#define PARS_REKEY 8
|
||||
|
||||
/* pars->alive */
|
||||
|
||||
@@ -312,9 +312,10 @@ static void rna_PartSettings_start_set(struct PointerRNA *ptr, float value)
|
||||
if(value > settings->end)
|
||||
value = settings->end;
|
||||
|
||||
if(settings->type==PART_REACTOR && value < 1.0)
|
||||
value = 1.0;
|
||||
else if (value < MINAFRAMEF)
|
||||
//if(settings->type==PART_REACTOR && value < 1.0)
|
||||
// value = 1.0;
|
||||
//else
|
||||
if (value < MINAFRAMEF)
|
||||
value = MINAFRAMEF;
|
||||
|
||||
settings->sta = value;
|
||||
@@ -522,9 +523,9 @@ static EnumPropertyItem *rna_Particle_from_itemf(bContext *C, PointerRNA *ptr, i
|
||||
return item;
|
||||
}
|
||||
|
||||
if(part->type==PART_REACTOR)
|
||||
return part_reactor_from_items;
|
||||
else
|
||||
//if(part->type==PART_REACTOR)
|
||||
// return part_reactor_from_items;
|
||||
//else
|
||||
return part_from_items;
|
||||
}
|
||||
|
||||
@@ -767,7 +768,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
|
||||
|
||||
static EnumPropertyItem type_items[] = {
|
||||
{PART_EMITTER, "EMITTER", 0, "Emitter", ""},
|
||||
{PART_REACTOR, "REACTOR", 0, "Reactor", ""},
|
||||
//{PART_REACTOR, "REACTOR", 0, "Reactor", ""},
|
||||
{PART_HAIR, "HAIR", 0, "Hair", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
@@ -986,10 +987,10 @@ static void rna_def_particle_settings(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Children", "Apply effectors to children.");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_redo");
|
||||
|
||||
prop= RNA_def_property(srna, "child_seams", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_CHILD_SEAMS);
|
||||
RNA_def_property_ui_text(prop, "Use seams", "Use seams to determine parents");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
|
||||
//prop= RNA_def_property(srna, "child_seams", PROP_BOOLEAN, PROP_NONE);
|
||||
//RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_CHILD_SEAMS);
|
||||
//RNA_def_property_ui_text(prop, "Use seams", "Use seams to determine parents");
|
||||
//RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
|
||||
|
||||
/* TODO: used somewhere? */
|
||||
prop= RNA_def_property(srna, "child_render", PROP_BOOLEAN, PROP_NONE);
|
||||
|
||||
@@ -1484,6 +1484,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
||||
ParticleKey state;
|
||||
ParticleCacheKey *cache=0;
|
||||
ParticleBillboardData bb;
|
||||
ParticleSimulationData sim = {re->scene, ob, psys, NULL};
|
||||
ParticleStrandData sd;
|
||||
StrandBuffer *strandbuf=0;
|
||||
StrandVert *svert=0;
|
||||
@@ -1517,14 +1518,16 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
||||
return 1;
|
||||
|
||||
/* 2. start initialising things */
|
||||
if(part->phystype==PART_PHYS_KEYED)
|
||||
psys_count_keyed_targets(ob,psys);
|
||||
|
||||
/* last possibility to bail out! */
|
||||
psmd= psys_get_modifier(ob,psys);
|
||||
sim.psmd = psmd = psys_get_modifier(ob,psys);
|
||||
if(!(psmd->modifier.mode & eModifierMode_Render))
|
||||
return 0;
|
||||
|
||||
if(part->phystype==PART_PHYS_KEYED)
|
||||
psys_count_keyed_targets(&sim);
|
||||
|
||||
|
||||
if(G.rendering == 0) { /* preview render */
|
||||
totchild = (int)((float)totchild * (float)part->disp / 100.0f);
|
||||
}
|
||||
@@ -1611,14 +1614,14 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
||||
#endif // XXX old animation system
|
||||
cfra = bsystem_time(re->scene, 0, (float)re->scene->r.cfra, 0.0);
|
||||
|
||||
/* 2.4 setup reactors */
|
||||
if(part->type == PART_REACTOR){
|
||||
psys_get_reactor_target(ob, psys, &tob, &tpsys);
|
||||
if(tpsys && (part->from==PART_FROM_PARTICLE || part->phystype==PART_PHYS_NO)){
|
||||
psmd = psys_get_modifier(tob,tpsys);
|
||||
tpart = tpsys->part;
|
||||
}
|
||||
}
|
||||
///* 2.4 setup reactors */
|
||||
// if(part->type == PART_REACTOR){
|
||||
// psys_get_reactor_target(ob, psys, &tob, &tpsys);
|
||||
// if(tpsys && (part->from==PART_FROM_PARTICLE || part->phystype==PART_PHYS_NO)){
|
||||
// psmd = psys_get_modifier(tob,tpsys);
|
||||
// tpart = tpsys->part;
|
||||
// }
|
||||
// }
|
||||
|
||||
/* 2.5 setup matrices */
|
||||
Mat4MulMat4(mat, ob->obmat, re->viewmat);
|
||||
@@ -1695,7 +1698,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
||||
}
|
||||
|
||||
if(path_nbr == 0)
|
||||
psys->lattice = psys_get_lattice(re->scene, ob, psys);
|
||||
psys->lattice = psys_get_lattice(&sim);
|
||||
|
||||
/* 3. start creating renderable things */
|
||||
for(a=0,pa=pars; a<totpart+totchild; a++, pa++, seed++) {
|
||||
@@ -1786,8 +1789,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
||||
|
||||
pa_size = psys_get_child_size(psys, cpa, cfra, &pa_time);
|
||||
|
||||
r_tilt = 2.0f * cpa->rand[2];
|
||||
r_length = cpa->rand[1];
|
||||
r_tilt = 2.0f*(PSYS_FRAND(a + 21) - 0.5f);
|
||||
r_length = PSYS_FRAND(a + 22);
|
||||
|
||||
num = cpa->num;
|
||||
|
||||
@@ -1952,7 +1955,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
||||
continue;
|
||||
|
||||
state.time = (part->draw & PART_ABS_PATH_TIME) ? -ct : ct;
|
||||
psys_get_particle_on_path(re->scene,ob,psys,a,&state,1);
|
||||
psys_get_particle_on_path(&sim,a,&state,1);
|
||||
|
||||
if(psys->parent)
|
||||
Mat4MulVecfl(psys->parent->obmat, state.co);
|
||||
@@ -1971,7 +1974,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
|
||||
else {
|
||||
time=0.0f;
|
||||
state.time=cfra;
|
||||
if(psys_get_particle_state(re->scene,ob,psys,a,&state,0)==0)
|
||||
if(psys_get_particle_state(&sim,a,&state,0)==0)
|
||||
continue;
|
||||
|
||||
if(psys->parent)
|
||||
|
||||
@@ -92,6 +92,7 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa
|
||||
{
|
||||
DerivedMesh* dm;
|
||||
ParticleKey state;
|
||||
ParticleSimulationData sim = {re->scene, ob, psys, NULL};
|
||||
ParticleData *pa=NULL;
|
||||
float cfra = bsystem_time(re->scene, ob, (float)re->scene->r.cfra, 0.0);
|
||||
int i, childexists;
|
||||
@@ -120,7 +121,7 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa
|
||||
Mat4Invert(ob->imat, ob->obmat);
|
||||
|
||||
total_particles = psys->totpart+psys->totchild;
|
||||
psys->lattice=psys_get_lattice(re->scene,ob,psys);
|
||||
psys->lattice=psys_get_lattice(&sim);
|
||||
|
||||
pd->point_tree = BLI_bvhtree_new(total_particles, 0.0, 4, 6);
|
||||
alloc_point_data(pd, total_particles, data_used);
|
||||
@@ -133,7 +134,7 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa
|
||||
for (i=0, pa=psys->particles; i < total_particles; i++, pa++) {
|
||||
|
||||
state.time = cfra;
|
||||
if(psys_get_particle_state(re->scene, ob, psys, i, &state, 0)) {
|
||||
if(psys_get_particle_state(&sim, i, &state, 0)) {
|
||||
|
||||
VECCOPY(partco, state.co);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user