Fix for bug #10894: objects used as particle duplis couldn't be

transformed properly anymore if they had ipo's, same issue also
fixed for dupliframes.
This commit is contained in:
Brecht Van Lommel 2008-05-09 10:26:49 +00:00
parent 55cbcd125d
commit 8d6857b915

@ -337,6 +337,7 @@ static void frames_duplilist(ListBase *lb, Object *ob, int level, int animated)
{ {
extern int enable_cu_speed; /* object.c */ extern int enable_cu_speed; /* object.c */
Object copyob; Object copyob;
DupliObject *dob;
int cfrao, ok; int cfrao, ok;
/* simple preventing of too deep nested groups */ /* simple preventing of too deep nested groups */
@ -360,7 +361,8 @@ static void frames_duplilist(ListBase *lb, Object *ob, int level, int animated)
if(ok) { if(ok) {
do_ob_ipo(ob); do_ob_ipo(ob);
where_is_object_time(ob, (float)G.scene->r.cfra); where_is_object_time(ob, (float)G.scene->r.cfra);
new_dupli_object(lb, ob, ob->obmat, ob->lay, G.scene->r.cfra, OB_DUPLIFRAMES, animated); dob= new_dupli_object(lb, ob, ob->obmat, ob->lay, G.scene->r.cfra, OB_DUPLIFRAMES, animated);
Mat4CpyMat4(dob->omat, copyob.obmat);
} }
} }
@ -723,7 +725,7 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_ma
static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], ParticleSystem *psys, int level, int animated) static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], ParticleSystem *psys, int level, int animated)
{ {
GroupObject *go; GroupObject *go;
Object *ob=0, **oblist=0; Object *ob=0, **oblist=0, obcopy, *obcopylist=0;
DupliObject *dob; DupliObject *dob;
ParticleSettings *part; ParticleSettings *part;
ParticleData *pa; ParticleData *pa;
@ -733,7 +735,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
ParticleSystemModifierData *psmd; ParticleSystemModifierData *psmd;
float ctime, pa_time, scale = 1.0f; float ctime, pa_time, scale = 1.0f;
float tmat[4][4], mat[4][4], obrotmat[4][4], pamat[4][4], size=0.0; float tmat[4][4], mat[4][4], obrotmat[4][4], pamat[4][4], size=0.0;
float (*obmat)[4]; float (*obmat)[4], (*oldobmat)[4];
float xvec[3] = {-1.0, 0.0, 0.0}, q[4]; float xvec[3] = {-1.0, 0.0, 0.0}, q[4];
int lay, a, b, k, step_nbr = 0, counter, hair = 0; int lay, a, b, k, step_nbr = 0, counter, hair = 0;
int totpart, totchild, totgroup=0, pa_num; int totpart, totchild, totgroup=0, pa_num;
@ -778,49 +780,55 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
psys->lattice = psys_get_lattice(par, psys); psys->lattice = psys_get_lattice(par, psys);
/* gather list of objects or single object */
if(part->draw_as==PART_DRAW_GR) { if(part->draw_as==PART_DRAW_GR) {
group_handle_recalc_and_update(par, part->dup_group); group_handle_recalc_and_update(par, part->dup_group);
go= part->dup_group->gobject.first; for(go=part->dup_group->gobject.first; go; go=go->next)
while(go) {
go=go->next;
totgroup++; totgroup++;
}
oblist= MEM_callocN(totgroup*sizeof(Object *), "dupgroup object list"); /* we also copy the actual objects to restore afterwards, since
go= part->dup_group->gobject.first; * where_is_object_time will change the object which breaks transform */
for(a=0; a<totgroup; a++, go=go->next) oblist = MEM_callocN(totgroup*sizeof(Object *), "dupgroup object list");
oblist[a]=go->ob; obcopylist = MEM_callocN(totgroup*sizeof(Object), "dupgroup copy list");
go = part->dup_group->gobject.first;
for(a=0; a<totgroup; a++, go=go->next) {
oblist[a] = go->ob;
obcopylist[a] = *go->ob;
}
} }
else else {
ob = part->dup_ob; ob = part->dup_ob;
obcopy = *ob;
}
if(totchild==0 || part->draw & PART_DRAW_PARENT) if(totchild==0 || part->draw & PART_DRAW_PARENT)
a=0; a = 0;
else else
a=totpart; a = totpart;
for(pa=psys->particles,counter=0; a<totpart+totchild; a++,pa++,counter++) { for(pa=psys->particles,counter=0; a<totpart+totchild; a++,pa++,counter++) {
if(a<totpart) { if(a<totpart) {
/* handle parent particle */
if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP))
continue; continue;
pa_num=pa->num; pa_num = pa->num;
pa_time = pa->time;
pa_time=pa->time; size = pa->size;
size=pa->size;
} }
else { else {
/* TODO: figure these two out */ /* handle child particle */
cpa= &psys->child[a - totpart]; cpa = &psys->child[a - totpart];
pa_num = a; pa_num = a;
pa_time = psys->particles[cpa->parent].time; pa_time = psys->particles[cpa->parent].time;
size = psys_get_child_size(psys, cpa, ctime, 0);
size=psys_get_child_size(psys, cpa, ctime, 0);
} }
if(part->draw_as==PART_DRAW_GR) { if(part->draw_as==PART_DRAW_GR) {
/* for groups, pick the object based on settings */
if(part->draw&PART_DRAW_RAND_GR) if(part->draw&PART_DRAW_RAND_GR)
b= BLI_rand() % totgroup; b= BLI_rand() % totgroup;
else if(part->from==PART_FROM_PARTICLE) else if(part->from==PART_FROM_PARTICLE)
@ -829,13 +837,17 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
b= a % totgroup; b= a % totgroup;
ob = oblist[b]; ob = oblist[b];
obmat= oblist[b]->obmat; obmat = oblist[b]->obmat;
oldobmat = obcopylist[b].obmat;
} }
else else {
obmat= ob->obmat; obmat= ob->obmat;
oldobmat= obcopy.obmat;
}
for(k=0; k<=step_nbr; k++, counter++) { for(k=0; k<=step_nbr; k++, counter++) {
if(hair) { if(hair) {
/* hair we handle separate and compute transform based on hair keys */
if(a < totpart) { if(a < totpart) {
cache = psys->pathcache[a]; cache = psys->pathcache[a];
psys_get_dupli_path_transform(par, psys, psmd, pa, 0, cache, pamat, &scale); psys_get_dupli_path_transform(par, psys, psmd, pa, 0, cache, pamat, &scale);
@ -848,6 +860,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
VECCOPY(pamat[3], cache->co); VECCOPY(pamat[3], cache->co);
} }
else if(step_nbr) { else if(step_nbr) {
/* other keys */
state.time = (float)k / (float)step_nbr; state.time = (float)k / (float)step_nbr;
psys_get_particle_on_path(par, psys, a, &state, 0); psys_get_particle_on_path(par, psys, a, &state, 0);
@ -856,6 +869,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
pamat[3][3]= 1.0f; pamat[3][3]= 1.0f;
} }
else { else {
/* first key */
state.time = -1.0; state.time = -1.0;
if(psys_get_particle_state(par, psys, a, &state, 0) == 0) if(psys_get_particle_state(par, psys, a, &state, 0) == 0)
continue; continue;
@ -876,6 +890,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
Mat4CpyMat4(mat, tmat); Mat4CpyMat4(mat, tmat);
dob= new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS, animated); dob= new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS, animated);
Mat4CpyMat4(dob->omat, oldobmat);
if(G.rendering) if(G.rendering)
psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco); psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco);
} }
@ -901,14 +916,27 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
Mat4CpyMat4(mat, tmat); Mat4CpyMat4(mat, tmat);
dob= new_dupli_object(lb, ob, mat, par->lay, counter, OB_DUPLIPARTS, animated); dob= new_dupli_object(lb, ob, mat, par->lay, counter, OB_DUPLIPARTS, animated);
Mat4CpyMat4(dob->omat, oldobmat);
if(G.rendering) if(G.rendering)
psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco); psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco);
} }
} }
} }
/* restore objects since they were changed in where_is_object_time */
if(part->draw_as==PART_DRAW_GR) {
for(a=0; a<totgroup; a++)
*(oblist[a])= obcopylist[a];
}
else
*ob= obcopy;
} }
/* clean up */
if(oblist) if(oblist)
MEM_freeN(oblist); MEM_freeN(oblist);
if(obcopylist)
MEM_freeN(obcopylist);
if(psys->lattice) { if(psys->lattice) {
end_latt_deform(); end_latt_deform();