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:
Janne Karhu 2009-09-17 22:00:49 +00:00
parent 69e919530e
commit 08e2da590f
18 changed files with 1283 additions and 1244 deletions

View File

@ -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")

View File

@ -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;

View File

@ -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 */

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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) */

View File

@ -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;

View File

@ -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;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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, &times);
PTCACHE_DATA_TO(data, BPHYS_DATA_TIMES, 0, &times);
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, &times);
// 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]);
}
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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)

View File

@ -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 */

View File

@ -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);

View File

@ -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)

View File

@ -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);