forked from bartvdbraak/blender
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:
parent
69e919530e
commit
08e2da590f
@ -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 ) );
|
||||
tspring2 = search2->link;
|
||||
|
||||
// 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 ) )
|
||||
{
|
||||
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;
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
@ -3197,8 +3193,6 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
else
|
||||
totchild=psys->totchild*part->disp/100;
|
||||
|
||||
memset(&pdd, 0, sizeof(ParticleDrawData));
|
||||
|
||||
ma= give_current_material(ob,part->omat);
|
||||
|
||||
if(v3d->zbuf) glDepthMask(1);
|
||||
@ -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];
|
||||
@ -3318,53 +3310,64 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
|
||||
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user