Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/particle.c')
-rw-r--r--source/blender/blenkernel/intern/particle.c284
1 files changed, 206 insertions, 78 deletions
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 44ee5c236fa..7d998a481f6 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -1,7 +1,7 @@
/* particle.c
*
*
- * $Id: particle.c $
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -46,7 +46,7 @@
#include "DNA_object_types.h"
#include "DNA_curve_types.h"
#include "DNA_key_types.h"
-#include "DNA_ipo_types.h"
+#include "DNA_ipo_types.h" // XXX old animation system stuff to remove!
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
@@ -65,20 +65,17 @@
#include "BKE_displist.h"
#include "BKE_particle.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_ipo.h"
#include "BKE_object.h"
#include "BKE_softbody.h"
#include "BKE_material.h"
#include "BKE_key.h"
#include "BKE_library.h"
#include "BKE_depsgraph.h"
-#include "BKE_bad_level_calls.h"
#include "BKE_modifier.h"
#include "BKE_mesh.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_pointcache.h"
-#include "blendef.h"
#include "RE_render_ext.h"
static void key_from_object(Object *ob, ParticleKey *key);
@@ -242,11 +239,11 @@ void psys_change_act(void *ob_v, void *act_v)
npsys->flag |= PSYS_CURRENT;
}
}
-Object *psys_get_lattice(Object *ob, ParticleSystem *psys)
+Object *psys_get_lattice(Scene *scene, Object *ob, ParticleSystem *psys)
{
Object *lattice=0;
- if(psys_in_edit_mode(psys)==0){
+ if(psys_in_edit_mode(scene, psys)==0){
ModifierData *md = (ModifierData*)psys_get_modifier(ob,psys);
@@ -287,9 +284,9 @@ int psys_ob_has_hair(Object *ob)
return 0;
}
-int psys_in_edit_mode(ParticleSystem *psys)
+int psys_in_edit_mode(Scene *scene, ParticleSystem *psys)
{
- return ((G.f & G_PARTICLEEDIT) && psys==psys_get_current(OBACT) && psys->edit);
+ return ((G.f & G_PARTICLEEDIT) && psys==psys_get_current((scene->basact)->object) && psys->edit);
}
int psys_check_enabled(Object *ob, ParticleSystem *psys)
{
@@ -394,7 +391,8 @@ void psys_free(Object *ob, ParticleSystem * psys)
free_keyed_keys(psys);
- PE_free_particle_edit(psys);
+ if(psys->edit && psys->free_edit)
+ psys->free_edit(psys);
if(psys->particles){
MEM_freeN(psys->particles);
@@ -1410,6 +1408,7 @@ static float vert_weight(MDeformVert *dvert, int group)
}
return 0.0;
}
+
static void do_prekink(ParticleKey *state, ParticleKey *par, float *par_rot, float time, float freq, float shape, float amplitude, short type, short axis, float obmat[][4])
{
float vec[3]={0.0,0.0,0.0}, q1[4]={1,0,0,0},q2[4];
@@ -1461,7 +1460,7 @@ static void do_prekink(ParticleKey *state, ParticleKey *par, float *par_rot, flo
case PART_KINK_WAVE:
vec[axis]=1.0;
if(obmat)
- Mat4MulVecfl(obmat,vec);
+ Mat4Mul3Vecfl(obmat,vec);
if(par_rot)
QuatMulVecf(par_rot,vec);
@@ -1544,6 +1543,7 @@ static void do_prekink(ParticleKey *state, ParticleKey *par, float *par_rot, flo
break;
}
}
+
static void do_clump(ParticleKey *state, ParticleKey *par, float time, float clumpfac, float clumppow, float pa_clump)
{
if(par && clumpfac!=0.0){
@@ -1561,7 +1561,8 @@ static void do_clump(ParticleKey *state, ParticleKey *par, float time, float clu
VecLerpf(state->co,state->co,par->co,clump);
}
}
-int do_guide(ParticleKey *state, int pa_num, float time, ListBase *lb)
+
+int do_guide(Scene *scene, ParticleKey *state, int pa_num, float time, ListBase *lb)
{
PartDeflect *pd;
ParticleEffectorCache *ec;
@@ -1644,7 +1645,7 @@ int do_guide(ParticleKey *state, int pa_num, float time, ListBase *lb)
/* curve taper */
if(cu->taperobj)
- VecMulf(pa_loc,calc_taper(cu->taperobj,(int)(f_force*guidetime*100.0),100));
+ VecMulf(pa_loc, calc_taper(scene, cu->taperobj, (int)(f_force*guidetime*100.0), 100));
/* TODO */
//else{
///* curve size*/
@@ -1719,7 +1720,7 @@ static void do_rough_end(float *loc, float t, float fac, float shape, ParticleKe
VECADD(state->co,state->co,rough);
}
-static void do_path_effectors(Object *ob, ParticleSystem *psys, int i, ParticleCacheKey *ca, int k, int steps, float *rootco, float effector, float dfra, float cfra, float *length, float *vec)
+static void do_path_effectors(Scene *scene, Object *ob, ParticleSystem *psys, int i, ParticleCacheKey *ca, int k, int steps, float *rootco, float effector, float dfra, float cfra, float *length, float *vec)
{
float force[3] = {0.0f,0.0f,0.0f}, vel[3] = {0.0f,0.0f,0.0f};
ParticleKey eff_key;
@@ -1730,7 +1731,7 @@ static void do_path_effectors(Object *ob, ParticleSystem *psys, int i, ParticleC
QUATCOPY(eff_key.rot,(ca-1)->rot);
pa= psys->particles+i;
- do_effectors(i, pa, &eff_key, ob, psys, rootco, force, vel, dfra, cfra);
+ do_effectors(i, pa, &eff_key, scene, ob, psys, rootco, force, vel, dfra, cfra);
VecMulf(force, effector*pow((float)k / (float)steps, 100.0f * psys->part->eff_hair) / (float)steps);
@@ -1805,10 +1806,13 @@ void psys_find_parents(Object *ob, ParticleSystemModifierData *psmd, ParticleSys
int from=PART_FROM_FACE;
totparent=(int)(totchild*part->parents*0.3);
+ if(G.rendering && part->child_nbr && part->ren_child_nbr)
+ totparent*=(float)part->child_nbr/(float)part->ren_child_nbr;
+
tree=BLI_kdtree_new(totparent);
for(p=0,cpa=psys->child; p<totparent; p++,cpa++){
- psys_particle_on_emitter(psmd,from,cpa->num,-1,cpa->fuv,cpa->foffset,co,0,0,0,orco,0);
+ psys_particle_on_emitter(psmd,from,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co,0,0,0,orco,0);
BLI_kdtree_insert(tree, p, orco, NULL);
}
@@ -1853,25 +1857,29 @@ static void get_strand_normal(Material *ma, float *surfnor, float surfdist, floa
VECCOPY(nor, vnor);
}
-int psys_threads_init_path(ParticleThread *threads, float cfra, int editupdate)
+int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, int editupdate)
{
ParticleThreadContext *ctx= threads[0].ctx;
Object *ob= ctx->ob;
ParticleSystem *psys= ctx->psys;
ParticleSettings *part = psys->part;
- ParticleEditSettings *pset = &G.scene->toolsettings->particle;
+ ParticleEditSettings *pset = &scene->toolsettings->particle;
int totparent=0, between=0;
int steps = (int)pow(2.0,(double)part->draw_step);
int totchild = psys->totchild;
int i, seed, totthread= threads[0].tot;
/*---start figuring out what is actually wanted---*/
- if(psys_in_edit_mode(psys))
+ if(psys_in_edit_mode(scene, psys))
if(psys->renderdata==0 && (psys->edit==NULL || pset->flag & PE_SHOW_CHILD)==0)
totchild=0;
if(totchild && part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
totparent=(int)(totchild*part->parents*0.3);
+
+ if(G.rendering && part->child_nbr && part->ren_child_nbr)
+ totparent*=(float)part->child_nbr/(float)part->ren_child_nbr;
+
/* part->parents could still be 0 so we can't test with totparent */
between=1;
}
@@ -1904,9 +1912,10 @@ int psys_threads_init_path(ParticleThread *threads, float cfra, int editupdate)
ctx->steps= steps;
ctx->totchild= totchild;
ctx->totparent= totparent;
+ ctx->parent_pass= 0;
ctx->cfra= cfra;
- psys->lattice = psys_get_lattice(ob, psys);
+ psys->lattice = psys_get_lattice(scene, ob, psys);
/* cache all relevant vertex groups if they exist */
if(part->from!=PART_FROM_PARTICLE){
@@ -1921,10 +1930,12 @@ int psys_threads_init_path(ParticleThread *threads, float cfra, int editupdate)
}
/* set correct ipo timing */
+#if 0 // XXX old animation system
if(part->flag&PART_ABS_TIME && part->ipo){
calc_ipo(part->ipo, cfra);
execute_ipo((ID *)part, part->ipo);
}
+#endif // XXX old animation system
return 1;
}
@@ -1941,14 +1952,14 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
ParticleCacheKey *state, *par = NULL, *key[4];
ParticleData *pa=NULL;
ParticleTexture ptex;
- float *cpa_fuv=0;
+ float *cpa_fuv=0, *par_rot=0;
float co[3], orco[3], ornor[3], t, rough_t, cpa_1st[3], dvec[3];
float branch_begin, branch_end, branch_prob, branchfac, rough_rand;
float pa_rough1, pa_rough2, pa_roughe;
float length, pa_length, pa_clump, pa_kink, pa_effector;
float max_length = 1.0f, cur_length = 0.0f;
float eff_length, eff_vec[3];
- int k, cpa_num, guided=0;
+ int k, cpa_num, guided = 0;
short cpa_from;
if(part->flag & PART_BRANCHING) {
@@ -2039,20 +2050,23 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
keys->steps = ctx->steps;
/* correct child ipo timing */
+#if 0 // XXX old animation system
if((part->flag&PART_ABS_TIME)==0 && part->ipo){
float dsta=part->end-part->sta;
calc_ipo(part->ipo, 100.0f*(ctx->cfra-(part->sta+dsta*cpa->rand[1]))/(part->lifetime*(1.0f - part->randlife*cpa->rand[0])));
execute_ipo((ID *)part, part->ipo);
}
+#endif // XXX old animation system
/* get different child parameters from textures & vgroups */
ptex.length=part->length*(1.0f - part->randlength*cpa->rand[0]);
ptex.clump=1.0;
ptex.kink=1.0;
ptex.rough= 1.0;
+ ptex.exist= 1.0;
get_cpa_texture(ctx->dm,ctx->ma,cpa_num,cpa_fuv,orco,&ptex,
- MAP_PA_LENGTH|MAP_PA_CLUMP|MAP_PA_KINK|MAP_PA_ROUGH);
+ MAP_PA_DENS|MAP_PA_LENGTH|MAP_PA_CLUMP|MAP_PA_KINK|MAP_PA_ROUGH);
pa_length=ptex.length;
pa_clump=ptex.clump;
@@ -2062,6 +2076,11 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
pa_roughe=ptex.rough;
pa_effector= 1.0f;
+ if(ptex.exist < cpa->rand[1]) {
+ keys->steps = -1;
+ return;
+ }
+
if(ctx->vg_length)
pa_length*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_length);
if(ctx->vg_clump)
@@ -2119,7 +2138,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
if(part->flag & PART_CHILD_EFFECT) {
for(k=0,state=keys; k<=ctx->steps; k++,state++) {
if(k) {
- do_path_effectors(ob, psys, cpa->pa[0], state, k, ctx->steps, keys->co, pa_effector, 0.0f, ctx->cfra, &eff_length, eff_vec);
+ do_path_effectors(ctx->scene, ob, psys, cpa->pa[0], state, k, ctx->steps, keys->co, pa_effector, 0.0f, ctx->cfra, &eff_length, eff_vec);
}
else {
VecSubf(eff_vec,(state+1)->co,state->co);
@@ -2132,25 +2151,26 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
t=(float)k/(float)ctx->steps;
if(ctx->totparent){
- if(i>=ctx->totparent)
- /* this is not threadsafe, but should only happen for
- * branching particles particles, which are not threaded */
+ if(i>=ctx->totparent) {
+ /* this is now threadsafe, virtual parents are calculated before rest of children */
par = cache[cpa->parent] + k;
+ }
else
par=0;
}
else if(cpa->parent>=0){
par=pcache[cpa->parent]+k;
+ par_rot = par->rot;
}
/* apply different deformations to the child path */
if(part->flag & PART_CHILD_EFFECT)
/* state is safe to cast, since only co and vel are used */
- guided = do_guide((ParticleKey*)state, cpa->parent, t, &(psys->effectors));
+ guided = do_guide(ctx->scene, (ParticleKey*)state, cpa->parent, t, &(psys->effectors));
if(guided==0){
if(part->kink)
- do_prekink((ParticleKey*)state, (ParticleKey*)par, par->rot, t,
+ do_prekink((ParticleKey*)state, (ParticleKey*)par, par_rot, t,
part->kink_freq * pa_kink, part->kink_shape, part->kink_amp, part->kink, part->kink_axis, ob->obmat);
do_clump((ParticleKey*)state, (ParticleKey*)par, t, part->clumpfac, part->clumppow, pa_clump);
@@ -2249,16 +2269,21 @@ static void *exec_child_path_cache(void *data)
ParticleSystem *psys= ctx->psys;
ParticleCacheKey **cache= psys->childcache;
ChildParticle *cpa;
- int i, totchild= ctx->totchild;
+ int i, totchild= ctx->totchild, first= 0;
+
+ if(thread->tot > 1){
+ first= ctx->parent_pass? 0 : ctx->totparent;
+ totchild= ctx->parent_pass? ctx->totparent : ctx->totchild;
+ }
- cpa= psys->child + thread->num;
- for(i=thread->num; i<totchild; i+=thread->tot, cpa+=thread->tot)
+ cpa= psys->child + first + thread->num;
+ for(i=first+thread->num; i<totchild; i+=thread->tot, cpa+=thread->tot)
psys_thread_create_path(thread, cpa, cache[i], i);
return 0;
}
-void psys_cache_child_paths(Object *ob, ParticleSystem *psys, float cfra, int editupdate)
+void psys_cache_child_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra, int editupdate)
{
ParticleSettings *part = psys->part;
ParticleThread *pthreads;
@@ -2267,9 +2292,9 @@ void psys_cache_child_paths(Object *ob, ParticleSystem *psys, float cfra, int ed
ListBase threads;
int i, totchild, totparent, totthread;
- pthreads= psys_threads_create(ob, psys);
+ pthreads= psys_threads_create(scene, ob, psys);
- if(!psys_threads_init_path(pthreads, cfra, editupdate)) {
+ if(!psys_threads_init_path(pthreads, scene, cfra, editupdate)) {
psys_threads_free(pthreads);
return;
}
@@ -2291,6 +2316,22 @@ void psys_cache_child_paths(Object *ob, ParticleSystem *psys, float cfra, int ed
totthread= pthreads[0].tot;
if(totthread > 1) {
+
+ /* make virtual child parents thread safe by calculating them first */
+ if(totparent) {
+ BLI_init_threads(&threads, exec_child_path_cache, totthread);
+
+ for(i=0; i<totthread; i++) {
+ pthreads[i].ctx->parent_pass = 1;
+ BLI_insert_thread(&threads, &pthreads[i]);
+ }
+
+ BLI_end_threads(&threads);
+
+ for(i=0; i<totthread; i++)
+ pthreads[i].ctx->parent_pass = 0;
+ }
+
BLI_init_threads(&threads, exec_child_path_cache, totthread);
for(i=0; i<totthread; i++)
@@ -2308,11 +2349,11 @@ void psys_cache_child_paths(Object *ob, ParticleSystem *psys, float cfra, int ed
/* -Usefull for making use of opengl vertex arrays for super fast strand drawing. */
/* -Makes child strands possible and creates them too into the cache. */
/* -Cached path data is also used to determine cut position for the editmode tool. */
-void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupdate)
+void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra, int editupdate)
{
ParticleCacheKey *ca, **cache=psys->pathcache;
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
- ParticleEditSettings *pset = &G.scene->toolsettings->particle;
+ ParticleEditSettings *pset = &scene->toolsettings->particle;
ParticleSettings *part = psys->part;
ParticleData *pa;
@@ -2328,13 +2369,12 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda
Material *ma;
float birthtime = 0.0, dietime = 0.0;
- float t, time = 0.0, keytime = 0.0, dfra = 1.0, frs_sec = G.scene->r.frs_sec;
+ float t, time = 0.0, keytime = 0.0, dfra = 1.0, frs_sec = scene->r.frs_sec;
float col[3] = {0.5f, 0.5f, 0.5f};
float prev_tangent[3], hairmat[4][4];
int k,i;
int steps = (int)pow(2.0, (double)psys->part->draw_step);
int totpart = psys->totpart;
- char nosel[4], sel[4];
float sel_col[3];
float nosel_col[3];
float length, vec[3];
@@ -2346,25 +2386,25 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda
if((psys->flag & PSYS_HAIR_DONE)==0 && (psys->flag & PSYS_KEYED)==0)
return;
- if(psys->renderdata)
+ if(psys->renderdata) {
steps = (int)pow(2.0, (double)psys->part->ren_step);
- else if(psys_in_edit_mode(psys)){
+ }
+ else if(psys_in_edit_mode(scene, psys)) {
edit=psys->edit;
//timed = edit->draw_timed;
- PE_get_colors(sel,nosel);
- if(pset->brushtype == PE_BRUSH_WEIGHT){
+ if(pset->brushtype == PE_BRUSH_WEIGHT) {
sel_col[0] = sel_col[1] = sel_col[2] = 1.0f;
nosel_col[0] = nosel_col[1] = nosel_col[2] = 0.0f;
}
else{
- sel_col[0] = (float)sel[0] / 255.0f;
- sel_col[1] = (float)sel[1] / 255.0f;
- sel_col[2] = (float)sel[2] / 255.0f;
- nosel_col[0] = (float)nosel[0] / 255.0f;
- nosel_col[1] = (float)nosel[1] / 255.0f;
- nosel_col[2] = (float)nosel[2] / 255.0f;
+ sel_col[0] = (float)edit->sel_col[0] / 255.0f;
+ sel_col[1] = (float)edit->sel_col[1] / 255.0f;
+ sel_col[2] = (float)edit->sel_col[2] / 255.0f;
+ nosel_col[0] = (float)edit->nosel_col[0] / 255.0f;
+ nosel_col[1] = (float)edit->nosel_col[1] / 255.0f;
+ nosel_col[2] = (float)edit->nosel_col[2] / 255.0f;
}
}
@@ -2384,7 +2424,7 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda
soft= NULL;
}
- psys->lattice = psys_get_lattice(ob, psys);
+ psys->lattice = psys_get_lattice(scene, ob, psys);
ma= give_current_material(ob, psys->part->omat);
if(ma && (psys->part->draw & PART_DRAW_MAT_COL))
VECCOPY(col, &ma->r)
@@ -2577,16 +2617,16 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda
for(k=0, ca=cache[i]; k<=steps; k++, ca++) {
/* apply effectors */
if(!(psys->part->flag & PART_CHILD_EFFECT) && edit==0 && k)
- do_path_effectors(ob, psys, i, ca, k, steps, cache[i]->co, effector, dfra, cfra, &length, vec);
+ do_path_effectors(scene, ob, psys, i, ca, k, steps, cache[i]->co, effector, dfra, cfra, &length, vec);
/* apply guide curves to path data */
if(edit==0 && psys->effectors.first && (psys->part->flag & PART_CHILD_EFFECT)==0)
/* ca is safe to cast, since only co and vel are used */
- do_guide((ParticleKey*)ca, i, (float)k/(float)steps, &psys->effectors);
+ do_guide(scene, (ParticleKey*)ca, i, (float)k/(float)steps, &psys->effectors);
/* apply lattice */
if(psys->lattice && edit==0)
- calc_latt_deform(ca->co, 1.0f);
+ calc_latt_deform(psys->lattice, ca->co, 1.0f);
/* figure out rotation */
@@ -2666,8 +2706,8 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda
psys->totcached = totpart;
if(psys && psys->lattice){
- end_latt_deform();
- psys->lattice=0;
+ end_latt_deform(psys->lattice);
+ psys->lattice= NULL;
}
if(vg_effector)
@@ -2921,7 +2961,9 @@ static void default_particle_settings(ParticleSettings *part)
part->boidfac[i]=0.5;
}
+#if 0 // XXX old animation system
part->ipo = NULL;
+#endif // XXX old animation system
part->simplify_refsize= 1920;
part->simplify_rate= 1.0f;
@@ -3011,7 +3053,7 @@ void make_local_particlesettings(ParticleSettings *part)
}
/* should be integrated to depgraph signals */
-void psys_flush_settings(ParticleSettings *part, int event, int hair_recalc)
+void psys_flush_settings(struct Scene *scene, ParticleSettings *part, int event, int hair_recalc)
{
Base *base;
Object *ob, *tob;
@@ -3019,7 +3061,7 @@ void psys_flush_settings(ParticleSettings *part, int event, int hair_recalc)
int flush;
/* update all that have same particle settings */
- for(base = G.scene->base.first; base; base= base->next) {
+ for(base = scene->base.first; base; base= base->next) {
if(base->object->particlesystem.first) {
ob=base->object;
flush=0;
@@ -3044,12 +3086,12 @@ void psys_flush_settings(ParticleSettings *part, int event, int hair_recalc)
}
}
if(flush)
- DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
}
}
}
-LinkNode *psys_using_settings(ParticleSettings *part, int flush_update)
+LinkNode *psys_using_settings(struct Scene *scene, ParticleSettings *part, int flush_update)
{
Object *ob, *tob;
ParticleSystem *psys, *tpsys;
@@ -3077,7 +3119,7 @@ LinkNode *psys_using_settings(ParticleSettings *part, int flush_update)
}
if(flush_update && found)
- DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
}
return node;
@@ -3165,6 +3207,8 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float
ptex->kink= texture_value_blend(def,ptex->kink,value,var,blend,neg & MAP_PA_KINK);
if((event & mtex->pmapto) & MAP_PA_ROUGH)
ptex->rough= texture_value_blend(def,ptex->rough,value,var,blend,neg & MAP_PA_ROUGH);
+ if((event & mtex->pmapto) & MAP_PA_DENS)
+ ptex->exist= texture_value_blend(def,ptex->exist,value,var,blend,neg & MAP_PA_DENS);
}
}
if(event & MAP_PA_TIME) { CLAMP(ptex->time,0.0,1.0); }
@@ -3172,6 +3216,7 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float
if(event & MAP_PA_CLUMP) { CLAMP(ptex->clump,0.0,1.0); }
if(event & MAP_PA_KINK) { CLAMP(ptex->kink,0.0,1.0); }
if(event & MAP_PA_ROUGH) { CLAMP(ptex->rough,0.0,1.0); }
+ if(event & MAP_PA_DENS) { CLAMP(ptex->exist,0.0,1.0); }
}
void psys_get_texture(Object *ob, Material *ma, ParticleSystemModifierData *psmd, ParticleSystem *psys, ParticleData *pa, ParticleTexture *ptex, int event)
{
@@ -3256,10 +3301,12 @@ float psys_get_size(Object *ob, Material *ma, ParticleSystemModifierData *psmd,
size=ptex.size;
}
+#if 0 // XXX old animation system
if(icu_size){
calc_icu(icu_size,pa->time);
size*=icu_size->curval;
}
+#endif // XXX old animation system
if(vg_size)
size*=psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_size);
@@ -3292,11 +3339,12 @@ float psys_get_child_time(ParticleSystem *psys, ChildParticle *cpa, float cfra)
float psys_get_child_size(ParticleSystem *psys, ChildParticle *cpa, float cfra, float *pa_time)
{
ParticleSettings *part = psys->part;
- float size, time;
+ float size; // time XXX
if(part->childtype==PART_CHILD_FACES){
size=part->size;
+#if 0 // XXX old animation system
if((part->flag&PART_ABS_TIME)==0 && part->ipo){
IpoCurve *icu;
@@ -3313,6 +3361,7 @@ float psys_get_child_size(ParticleSystem *psys, ChildParticle *cpa, float cfra,
size = icu->curval;
}
}
+#endif // XXX old animation system
}
else
size=psys->particles[cpa->parent].size;
@@ -3325,7 +3374,7 @@ float psys_get_child_size(ParticleSystem *psys, ChildParticle *cpa, float cfra,
return size;
}
/* get's hair (or keyed) particles state at the "path time" specified in state->time */
-void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, int p, ParticleKey *state, int vel)
+void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, int p, ParticleKey *state, int vel)
{
ParticleSettings *part = psys->part;
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
@@ -3337,7 +3386,7 @@ void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, int p, Particle
HairKey *hkey[2] = {NULL, NULL};
ParticleKey *par=0, keys[4];
- float t, real_t, dfra, keytime, frs_sec = G.scene->r.frs_sec;
+ float t, real_t, dfra, keytime, frs_sec = scene->r.frs_sec;
float co[3], orco[3];
float hairmat[4][4];
float pa_clump = 0.0, pa_kink = 0.0;
@@ -3348,7 +3397,7 @@ void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, int p, Particle
float *cpa_fuv; int cpa_num; short cpa_from;
- //if(psys_in_edit_mode(psys)){
+ //if(psys_in_edit_mode(scene, psys)){
// if((psys->edit_path->flag & PSYS_EP_SHOW_CHILD)==0)
// totchild=0;
// edit=1;
@@ -3432,7 +3481,7 @@ void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, int p, Particle
}
//}
- //psys_get_particle_on_path(bsys,p,t,bkey,ckey[0]);
+ //psys_get_particle_on_path(scene, bsys,p,t,bkey,ckey[0]);
//if(part->rotfrom==PART_ROT_KEYS)
// QuatInterpol(state->rot,k2.rot,k3.rot,keytime);
@@ -3470,12 +3519,12 @@ void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, int p, Particle
Mat4Mul3Vecfl(hairmat, state->vel);
if(psys->effectors.first && (part->flag & PART_CHILD_GUIDE)==0) {
- do_guide(state, p, state->time, &psys->effectors);
+ do_guide(scene, state, p, state->time, &psys->effectors);
/* TODO: proper velocity handling */
}
if(psys->lattice && edit==0)
- calc_latt_deform(state->co,1.0f);
+ calc_latt_deform(psys->lattice, state->co,1.0f);
}
}
}
@@ -3486,6 +3535,10 @@ void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, int p, Particle
if(totchild && part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
totparent=(int)(totchild*part->parents*0.3);
+
+ if(G.rendering && part->child_nbr && part->ren_child_nbr)
+ totparent*=(float)part->child_nbr/(float)part->ren_child_nbr;
+
/* part->parents could still be 0 so we can't test with totparent */
between=1;
}
@@ -3496,7 +3549,7 @@ void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, int p, Particle
/* get parent states */
while(w<4 && cpa->pa[w]>=0){
keys[w].time = t;
- psys_get_particle_on_path(ob, psys, cpa->pa[w], keys+w, 1);
+ psys_get_particle_on_path(scene, ob, psys, cpa->pa[w], keys+w, 1);
w++;
}
@@ -3522,7 +3575,7 @@ void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, int p, Particle
/* get the parent state */
keys->time = t;
- psys_get_particle_on_path(ob,psys,cpa->parent,keys,1);
+ psys_get_particle_on_path(scene, ob, psys, cpa->parent, keys,1);
/* get the original coordinates (orco) for texture usage */
pa=psys->particles+cpa->parent;
@@ -3535,11 +3588,13 @@ void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, int p, Particle
}
/* correct child ipo timing */
+#if 0 // XXX old animation system
if((part->flag&PART_ABS_TIME)==0 && part->ipo){
calc_ipo(part->ipo, 100.0f*t);
execute_ipo((ID *)part, part->ipo);
}
-
+#endif // XXX old animation system
+
/* get different child parameters from textures & vgroups */
ptex.clump=1.0;
ptex.kink=1.0;
@@ -3608,19 +3663,19 @@ void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, int p, Particle
//if(vel){
// if(t>=0.001f){
// tstate.time=t-0.001f;
- // psys_get_particle_on_path(ob,psys,p,&tstate,0);
+ // psys_get_particle_on_path(scene,ob,psys,p,&tstate,0);
// VECSUB(state->vel,state->co,tstate.co);
// }
// else{
// tstate.time=t+0.001f;
- // psys_get_particle_on_path(ob,psys,p,&tstate,0);
+ // psys_get_particle_on_path(scene, ob,psys,p,&tstate,0);
// VECSUB(state->vel,tstate.co,state->co);
// }
//}
}
}
/* gets particle's state at a time, returns 1 if particle exists and can be seen and 0 if not */
-int psys_get_particle_state(Object *ob, ParticleSystem *psys, int p, ParticleKey *state, int always){
+int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psys, int p, ParticleKey *state, int always){
ParticleSettings *part=psys->part;
ParticleData *pa=0;
float cfra;
@@ -3630,7 +3685,7 @@ int psys_get_particle_state(Object *ob, ParticleSystem *psys, int p, ParticleKey
if(state->time>0)
cfra=state->time;
else
- cfra=bsystem_time(0,(float)G.scene->r.cfra,0.0);
+ cfra= bsystem_time(scene, 0, (float)scene->r.cfra,0.0);
if(psys->totchild && p>=totpart){
if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
@@ -3666,7 +3721,7 @@ int psys_get_particle_state(Object *ob, ParticleSystem *psys, int p, ParticleKey
else
state->time= (cfra-pa->time)/(pa->dietime-pa->time);
- psys_get_particle_on_path(ob,psys,p,state,1);
+ psys_get_particle_on_path(scene, ob, psys, p, state,1);
return 1;
}
else{
@@ -3698,7 +3753,7 @@ int psys_get_particle_state(Object *ob, ParticleSystem *psys, int p, ParticleKey
do_clump(state,key1,t,part->clumpfac,part->clumppow,1.0);
if(psys->lattice)
- calc_latt_deform(state->co,1.0f);
+ calc_latt_deform(psys->lattice, state->co,1.0f);
}
else{
if (pa) { /* TODO PARTICLE - should this ever be NULL? - Campbell */
@@ -3710,7 +3765,7 @@ int psys_get_particle_state(Object *ob, ParticleSystem *psys, int p, ParticleKey
/* let's interpolate to try to be as accurate as possible */
if(pa->state.time + 1.0f > state->time && pa->prev_state.time - 1.0f < state->time) {
ParticleKey keys[4];
- float dfra, keytime, frs_sec = G.scene->r.frs_sec;
+ float dfra, keytime, frs_sec = scene->r.frs_sec;
if(pa->prev_state.time >= pa->state.time) {
/* prev_state is wrong so let's not use it, this can happen at frame 1 or particle birth */
@@ -3750,7 +3805,7 @@ int psys_get_particle_state(Object *ob, ParticleSystem *psys, int p, ParticleKey
}
if(psys->lattice)
- calc_latt_deform(state->co,1.0f);
+ calc_latt_deform(psys->lattice, state->co,1.0f);
}
}
@@ -3860,3 +3915,76 @@ void psys_get_dupli_path_transform(Object *ob, ParticleSystem *psys, ParticleSys
*scale= len;
}
+void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3], float zvec[3], float center[3])
+{
+ float onevec[3] = {0.0f,0.0f,0.0f}, tvec[3], tvec2[3];
+
+ xvec[0] = 1.0f; xvec[1] = 0.0f; xvec[2] = 0.0f;
+ yvec[0] = 0.0f; yvec[1] = 1.0f; yvec[2] = 0.0f;
+
+ if(bb->align < PART_BB_VIEW)
+ onevec[bb->align]=1.0f;
+
+ if(bb->lock && (bb->align == PART_BB_VIEW)) {
+ VECCOPY(xvec, bb->ob->obmat[0]);
+ Normalize(xvec);
+
+ VECCOPY(yvec, bb->ob->obmat[1]);
+ Normalize(yvec);
+
+ VECCOPY(zvec, bb->ob->obmat[2]);
+ Normalize(zvec);
+ }
+ else if(bb->align == PART_BB_VEL) {
+ float temp[3];
+
+ VECCOPY(temp, bb->vel);
+ Normalize(temp);
+
+ VECSUB(zvec, bb->ob->obmat[3], bb->vec);
+
+ if(bb->lock) {
+ float fac = -Inpf(zvec, temp);
+
+ VECADDFAC(zvec, zvec, temp, fac);
+ }
+ Normalize(zvec);
+
+ Crossf(xvec,temp,zvec);
+ Normalize(xvec);
+
+ Crossf(yvec,zvec,xvec);
+ }
+ else {
+ VECSUB(zvec, bb->ob->obmat[3], bb->vec);
+ if(bb->lock)
+ zvec[bb->align] = 0.0f;
+ Normalize(zvec);
+
+ if(bb->align < PART_BB_VIEW)
+ Crossf(xvec, onevec, zvec);
+ else
+ Crossf(xvec, bb->ob->obmat[1], zvec);
+ Normalize(xvec);
+
+ Crossf(yvec,zvec,xvec);
+ }
+
+ VECCOPY(tvec, xvec);
+ VECCOPY(tvec2, yvec);
+
+ VecMulf(xvec, cos(bb->tilt * (float)M_PI));
+ VecMulf(tvec2, sin(bb->tilt * (float)M_PI));
+ VECADD(xvec, xvec, tvec2);
+
+ VecMulf(yvec, cos(bb->tilt * (float)M_PI));
+ VecMulf(tvec, -sin(bb->tilt * (float)M_PI));
+ VECADD(yvec, yvec, tvec);
+
+ VecMulf(xvec, bb->size);
+ VecMulf(yvec, bb->size);
+
+ VECADDFAC(center, bb->vec, xvec, bb->offset[0]);
+ VECADDFAC(center, center, yvec, bb->offset[1]);
+}
+