diff options
author | Janne Karhu <jhkarh@gmail.com> | 2011-02-06 18:50:00 +0300 |
---|---|---|
committer | Janne Karhu <jhkarh@gmail.com> | 2011-02-06 18:50:00 +0300 |
commit | 0ea9271f43e7e8ef914d33244d658ad7b5720f1f (patch) | |
tree | 3b307bc11ae557d91d06d001dadd552d35e006e2 /source/blender | |
parent | d9aa3f66a65161f324148ecb68b847bbbebee235 (diff) |
Bug fix: Particles in dupligroups were mostly drawn properly in 3d view, but rendering them was a real mess.
* After countless different bugs particles should now render correctly inside dupligroups.
* Only particles with metaball visualization are still problematic, this is mostly due to the ancient metaball code.
* I'll also add a test file for some of the situations, so that hopefully these cases stay fixed :)
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/intern/anim.c | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle.c | 19 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_particle_types.h | 2 | ||||
-rw-r--r-- | source/blender/render/intern/source/convertblender.c | 21 |
4 files changed, 32 insertions, 16 deletions
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 68a949ed25a..ab1da04e683 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -1156,7 +1156,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa dm->release(dm); } -static void new_particle_duplilist(ListBase *lb, ID *UNUSED(id), Scene *scene, Object *par, float par_space_mat[][4], ParticleSystem *psys, int level, int animated) +static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], ParticleSystem *psys, int level, int animated) { GroupObject *go; Object *ob=0, **oblist=0, obcopy, *obcopylist=0; @@ -1375,7 +1375,7 @@ static void new_particle_duplilist(ListBase *lb, ID *UNUSED(id), Scene *scene, O /* Normal particles and cached hair live in global space so we need to * remove the real emitter's transformation before 2nd order duplication. */ - if(par_space_mat) + if(par_space_mat && GS(id->name) != ID_GR) mul_m4_m4m4(mat, pamat, psys->imat); else copy_m4_m4(mat, pamat); @@ -1391,7 +1391,7 @@ static void new_particle_duplilist(ListBase *lb, ID *UNUSED(id), Scene *scene, O if(part->draw & PART_DRAW_GLOBAL_OB) VECADD(mat[3], mat[3], vec); - dob= new_dupli_object(lb, ob, mat, ob->lay, counter, OB_DUPLIPARTS, animated); + dob= new_dupli_object(lb, ob, mat, ob->lay, counter, GS(id->name) == ID_GR ? OB_DUPLIGROUP : OB_DUPLIPARTS, animated); copy_m4_m4(dob->omat, oldobmat); if(G.rendering) psys_get_dupli_texture(par, part, sim.psmd, pa, cpa, dob->uv, dob->orco); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 11ea82803eb..f6b97dcb78e 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -1194,12 +1194,12 @@ static void mvert_to_particle(ParticleKey *key, MVert *mvert, HairKey *hkey) key->time = hkey->time; } -static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData *pa, float t, float frs_sec, ParticleInterpolationData *pind, ParticleKey *result) +static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData *pa, float t, ParticleInterpolationData *pind, ParticleKey *result) { PTCacheEditPoint *point = pind->epoint; ParticleKey keys[4]; int point_vel = (point && point->keys->vel); - float real_t, dfra, keytime; + float real_t, dfra, keytime, invdt; /* billboards wont fill in all of these, so start cleared */ memset(keys, 0, sizeof(keys)); @@ -1338,11 +1338,12 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData dfra = keys[2].time - keys[1].time; keytime = (real_t - keys[1].time) / dfra; + invdt = dfra * 0.04f * psys->part->timetweak; /* convert velocity to timestep size */ if(pind->keyed || pind->cache || point_vel){ - mul_v3_fl(keys[1].vel, dfra / frs_sec); - mul_v3_fl(keys[2].vel, dfra / frs_sec); + mul_v3_fl(keys[1].vel, invdt); + mul_v3_fl(keys[2].vel, invdt); interp_qt_qtqt(result->rot,keys[1].rot,keys[2].rot,keytime); } @@ -1353,7 +1354,7 @@ static void do_particle_interpolation(ParticleSystem *psys, int p, ParticleData /* the velocity needs to be converted back from cubic interpolation */ if(pind->keyed || pind->cache || point_vel) - mul_v3_fl(result->vel, frs_sec / dfra); + mul_v3_fl(result->vel, 1.f/invdt); } /************************************************/ /* Particles on a dm */ @@ -2954,7 +2955,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra) time = (float)k / (float)steps; t = birthtime + time * (dietime - birthtime); result.time = -t; - do_particle_interpolation(psys, p, pa, t, frs_sec, &pind, &result); + do_particle_interpolation(psys, p, pa, t, &pind, &result); copy_v3_v3(ca->co, result.co); /* dynamic hair is in object space */ @@ -3133,7 +3134,7 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf time = (float)k / (float)steps; t = birthtime + time * (dietime - birthtime); result.time = -t; - do_particle_interpolation(psys, i, pa, t, frs_sec, &pind, &result); + do_particle_interpolation(psys, i, pa, t, &pind, &result); copy_v3_v3(ca->co, result.co); /* non-hair points are already in global space */ @@ -3954,7 +3955,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey * ParticleThreadContext ctx; /* fake thread context for child modifiers */ ParticleInterpolationData pind; - float t, frs_sec = sim->scene->r.frs_sec; + float t; float co[3], orco[3]; float hairmat[4][4]; int totpart = psys->totpart; @@ -3982,7 +3983,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey * * account when subdividing for instance */ pind.dm = psys_in_edit_mode(sim->scene, psys) ? NULL : psys->hair_out_dm; init_particle_interpolation(sim->ob, psys, pa, &pind); - do_particle_interpolation(psys, p, pa, t, frs_sec, &pind, state); + do_particle_interpolation(psys, p, pa, t, &pind, state); if(!keyed && !cached) { if((pa->flag & PARS_REKEY)==0) { diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 9ead2a3f572..a3a44976fcd 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -459,7 +459,7 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in #define PSYS_ENABLED 16 /* deprecated */ #define PSYS_HAIR_UPDATED 32 /* signal for updating hair particle mode */ #define PSYS_DRAWING 64 -//#define PSYS_SOFT_BAKE 128 +#define PSYS_USE_IMAT 128 #define PSYS_DELETE 256 /* remove particlesystem as soon as possible */ #define PSYS_HAIR_DONE 512 #define PSYS_KEYED 1024 diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 550a063c298..14f80986ba3 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -1492,13 +1492,13 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem StrandBound *sbound= 0; StrandRen *strand=0; RNG *rng= 0; - float loc[3],loc1[3],loc0[3],mat[4][4],nmat[3][3],co[3],nor[3]; + float loc[3],loc1[3],loc0[3],mat[4][4],nmat[3][3],co[3],nor[3],duplimat[4][4]; float strandlen=0.0f, curlen=0.0f; float hasize, pa_size, r_tilt, r_length; float pa_time, pa_birthtime, pa_dietime; float random, simplify[2], pa_co[3]; const float cfra= BKE_curframe(re->scene); - int i, a, k, max_k=0, totpart, dosimplify = 0, dosurfacecache = 0; + int i, a, k, max_k=0, totpart, dosimplify = 0, dosurfacecache = 0, use_duplimat = 0; int totchild=0; int seed, path_nbr=0, orco1=0, num; int totface, *origindex = 0; @@ -1638,6 +1638,12 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem copy_m3_m4(nmat, ob->imat); transpose_m3(nmat); + if(psys->flag & PSYS_USE_IMAT) { + /* psys->imat is the original emitter's inverse matrix, ob->obmat is the duplicated object's matrix */ + mul_m4_m4m4(duplimat, psys->imat, ob->obmat); + use_duplimat = 1; + } + /* 2.6 setup strand rendering */ if(part->ren_as == PART_DRAW_PATH && psys->pathcache){ path_nbr=(int)pow(2.0,(double) part->ren_step); @@ -1949,6 +1955,9 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem if(psys->parent) mul_m4_v3(psys->parent->obmat, state.co); + if(use_duplimat) + mul_m4_v4(duplimat, state.co); + if(part->ren_as == PART_DRAW_BB) { bb.random = random; bb.size = pa_size; @@ -1971,6 +1980,9 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem if(psys->parent) mul_m4_v3(psys->parent->obmat, state.co); + if(use_duplimat) + mul_m4_v4(duplimat, state.co); + if(part->ren_as == PART_DRAW_BB) { bb.random = random; bb.size = pa_size; @@ -4345,7 +4357,7 @@ static void init_render_object_data(Render *re, ObjectRen *obr, int timeoffset) int i; if(obr->psysindex) { - if((!obr->prev || obr->prev->ob != ob) && ob->type==OB_MESH) { + if((!obr->prev || obr->prev->ob != ob || (obr->prev->flag & R_INSTANCEABLE)==0) && ob->type==OB_MESH) { /* the emitter mesh wasn't rendered so the modifier stack wasn't * evaluated with render settings */ DerivedMesh *dm; @@ -4437,8 +4449,11 @@ static void add_render_object(Render *re, Object *ob, Object *par, DupliObject * } if(obr->lay & vectorlay) obr->flag |= R_NEED_VECTORS; + if(dob) + psys->flag |= PSYS_USE_IMAT; init_render_object_data(re, obr, timeoffset); psys_render_restore(ob, psys); + psys->flag &= ~PSYS_USE_IMAT; /* only add instance for objects that have not been used for dupli */ if(!(ob->transflag & OB_RENDER_DUPLI)) { |