diff options
Diffstat (limited to 'source/blender/blenkernel/intern/anim.c')
-rw-r--r-- | source/blender/blenkernel/intern/anim.c | 126 |
1 files changed, 70 insertions, 56 deletions
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 1aceca454d2..e943d92a0b5 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -87,15 +87,16 @@ void free_path(Path *path) void calc_curvepath(Object *ob) { BevList *bl; - BevPoint *bevp, *bevpn, *bevpfirst, *bevplast, *tempbevp; + BevPoint *bevp, *bevpn, *bevpfirst, *bevplast; + PathPoint *pp; Curve *cu; Nurb *nu; Path *path; - float *fp, *dist, *maxdist, x, y, z; + float *fp, *dist, *maxdist, xyz[3]; float fac, d=0, fac1, fac2; int a, tot, cycl=0; - float *ft; + /* in a path vertices are with equal differences: path->len = number of verts */ /* NOW WITH BEVELCURVE!!! */ @@ -132,19 +133,12 @@ void calc_curvepath(Object *ob) *fp= 0; for(a=0; a<tot; a++) { fp++; - if(cycl && a==tot-1) { - x= bevpfirst->x - bevp->x; - y= bevpfirst->y - bevp->y; - z= bevpfirst->z - bevp->z; - } - else { - tempbevp = bevp+1; - x= (tempbevp)->x - bevp->x; - y= (tempbevp)->y - bevp->y; - z= (tempbevp)->z - bevp->z; - } - *fp= *(fp-1)+ (float)sqrt(x*x+y*y+z*z); + if(cycl && a==tot-1) + VecSubf(xyz, bevpfirst->vec, bevp->vec); + else + VecSubf(xyz, (bevp+1)->vec, bevp->vec); + *fp= *(fp-1)+VecLength(xyz); bevp++; } @@ -152,7 +146,7 @@ void calc_curvepath(Object *ob) /* the path verts in path->data */ /* now also with TILT value */ - ft= path->data = (float *)MEM_callocN(16*path->len, "pathdata"); + pp= path->data = (PathPoint *)MEM_callocN(sizeof(PathPoint)*4*path->len, "pathdata"); // XXX - why *4? - in 2.4x each element was 4 and the size was 16, so better leave for now - Campbell bevp= bevpfirst; bevpn= bevp+1; @@ -182,13 +176,13 @@ void calc_curvepath(Object *ob) fac1= fac2/fac1; fac2= 1.0f-fac1; - ft[0]= fac1*bevp->x+ fac2*(bevpn)->x; - ft[1]= fac1*bevp->y+ fac2*(bevpn)->y; - ft[2]= fac1*bevp->z+ fac2*(bevpn)->z; - ft[3]= fac1*bevp->alfa+ fac2*(bevpn)->alfa; + VecLerpf(pp->vec, bevp->vec, bevpn->vec, fac2); + pp->vec[3]= fac1*bevp->alfa + fac2*bevpn->alfa; + pp->radius= fac1*bevp->radius + fac2*bevpn->radius; + QuatInterpol(pp->quat, bevp->quat, bevpn->quat, fac2); + NormalQuat(pp->quat); - ft+= 4; - + pp++; } MEM_freeN(dist); @@ -212,13 +206,14 @@ int interval_test(int min, int max, int p1, int cycl) /* warning, *vec needs FOUR items! */ /* ctime is normalized range <0-1> */ -int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK */ +int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius) /* returns OK */ { Curve *cu; Nurb *nu; BevList *bl; Path *path; - float *fp, *p0, *p1, *p2, *p3, fac; + PathPoint *pp, *p0, *p1, *p2, *p3; + float fac; float data[4]; int cycl=0, s0, s1, s2, s3; @@ -229,7 +224,7 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK return 0; } path= cu->path; - fp= path->data; + pp= path->data; /* test for cyclic */ bl= cu->bev.first; @@ -248,19 +243,19 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK s2= interval_test(0, path->len-1-cycl, s1+1, cycl); s3= interval_test(0, path->len-1-cycl, s1+2, cycl); - p0= fp + 4*s0; - p1= fp + 4*s1; - p2= fp + 4*s2; - p3= fp + 4*s3; + p0= pp + s0; + p1= pp + s1; + p2= pp + s2; + p3= pp + s3; /* note, commented out for follow constraint */ //if(cu->flag & CU_FOLLOW) { - set_afgeleide_four_ipo(1.0f-fac, data, KEY_BSPLINE); + key_curve_tangent_weights(1.0f-fac, data, KEY_BSPLINE); - dir[0]= data[0]*p0[0] + data[1]*p1[0] + data[2]*p2[0] + data[3]*p3[0] ; - dir[1]= data[0]*p0[1] + data[1]*p1[1] + data[2]*p2[1] + data[3]*p3[1] ; - dir[2]= data[0]*p0[2] + data[1]*p1[2] + data[2]*p2[2] + data[3]*p3[2] ; + dir[0]= data[0]*p0->vec[0] + data[1]*p1->vec[0] + data[2]*p2->vec[0] + data[3]*p3->vec[0] ; + dir[1]= data[0]*p0->vec[1] + data[1]*p1->vec[1] + data[2]*p2->vec[1] + data[3]*p3->vec[1] ; + dir[2]= data[0]*p0->vec[2] + data[1]*p1->vec[2] + data[2]*p2->vec[2] + data[3]*p3->vec[2] ; /* make compatible with vectoquat */ dir[0]= -dir[0]; @@ -271,16 +266,35 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK nu= cu->nurb.first; /* make sure that first and last frame are included in the vectors here */ - if((nu->type & 7)==CU_POLY) set_four_ipo(1.0f-fac, data, KEY_LINEAR); - else if((nu->type & 7)==CU_BEZIER) set_four_ipo(1.0f-fac, data, KEY_LINEAR); - else if(s0==s1 || p2==p3) set_four_ipo(1.0f-fac, data, KEY_CARDINAL); - else set_four_ipo(1.0f-fac, data, KEY_BSPLINE); - - vec[0]= data[0]*p0[0] + data[1]*p1[0] + data[2]*p2[0] + data[3]*p3[0] ; - vec[1]= data[0]*p0[1] + data[1]*p1[1] + data[2]*p2[1] + data[3]*p3[1] ; - vec[2]= data[0]*p0[2] + data[1]*p1[2] + data[2]*p2[2] + data[3]*p3[2] ; + if(nu->type == CU_POLY) key_curve_position_weights(1.0f-fac, data, KEY_LINEAR); + else if(nu->type == CU_BEZIER) key_curve_position_weights(1.0f-fac, data, KEY_LINEAR); + else if(s0==s1 || p2==p3) key_curve_position_weights(1.0f-fac, data, KEY_CARDINAL); + else key_curve_position_weights(1.0f-fac, data, KEY_BSPLINE); + + vec[0]= data[0]*p0->vec[0] + data[1]*p1->vec[0] + data[2]*p2->vec[0] + data[3]*p3->vec[0] ; /* X */ + vec[1]= data[0]*p0->vec[1] + data[1]*p1->vec[1] + data[2]*p2->vec[1] + data[3]*p3->vec[1] ; /* Y */ + vec[2]= data[0]*p0->vec[2] + data[1]*p1->vec[2] + data[2]*p2->vec[2] + data[3]*p3->vec[2] ; /* Z */ + vec[3]= data[0]*p0->vec[3] + data[1]*p1->vec[3] + data[2]*p2->vec[3] + data[3]*p3->vec[3] ; /* Tilt, should not be needed since we have quat still used */ + /* Need to verify the quat interpolation is correct - XXX */ + + if (quat) { + float totfac, q1[4], q2[4]; + + totfac= data[0]+data[1]; + QuatInterpol(q1, p0->quat, p1->quat, data[0] / totfac); + NormalQuat(q1); + + totfac= data[2]+data[3]; + QuatInterpol(q2, p2->quat, p3->quat, data[2] / totfac); + NormalQuat(q2); + + totfac = data[0]+data[1]+data[2]+data[3]; + QuatInterpol(quat, q1, q2, (data[0]+data[1]) / totfac); + NormalQuat(quat); + } - vec[3]= data[0]*p0[3] + data[1]*p1[3] + data[2]*p2[3] + data[3]*p3[3] ; + if(radius) + *radius= data[0]*p0->radius + data[1]*p1->radius + data[2]*p2->radius + data[3]*p3->radius; return 1; } @@ -752,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]; @@ -770,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; @@ -786,8 +799,9 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p BLI_srandom(31415926 + psys->seed); lay= scene->lay; - if((part->draw_as == PART_DRAW_OB && part->dup_ob) || - (part->draw_as == PART_DRAW_GR && part->dup_group && part->dup_group->gobject.first)) { + if((psys->renderdata || part->draw_as==PART_DRAW_REND) && + ((part->ren_as == PART_DRAW_OB && part->dup_ob) || + (part->ren_as == PART_DRAW_GR && part->dup_group && part->dup_group->gobject.first))) { /* if we have a hair particle system, use the path cache */ if(part->type == PART_HAIR) { @@ -801,10 +815,10 @@ 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->draw_as==PART_DRAW_GR) { + if(part->ren_as==PART_DRAW_GR) { group_handle_recalc_and_update(scene, par, part->dup_group); for(go=part->dup_group->gobject.first; go; go=go->next) @@ -850,7 +864,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p size = psys_get_child_size(psys, cpa, ctime, 0); } - if(part->draw_as==PART_DRAW_GR) { + if(part->ren_as==PART_DRAW_GR) { /* for groups, pick the object based on settings */ if(part->draw&PART_DRAW_RAND_GR) b= BLI_rand() % totgroup; @@ -872,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); @@ -886,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); @@ -894,7 +908,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p pamat[3][3]= 1.0f; } - if(part->draw_as==PART_DRAW_GR && psys->part->draw & PART_DRAW_WHOLE_GR) { + if(part->ren_as==PART_DRAW_GR && psys->part->draw & PART_DRAW_WHOLE_GR) { for(go= part->dup_group->gobject.first, b=0; go; go= go->next, b++) { Mat4MulMat4(tmat, oblist[b]->obmat, pamat); Mat4MulFloat3((float *)tmat, size*scale); @@ -906,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 { @@ -925,12 +939,12 @@ 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); } } /* restore objects since they were changed in where_is_object_time */ - if(part->draw_as==PART_DRAW_GR) { + if(part->ren_as==PART_DRAW_GR) { for(a=0; a<totgroup; a++) *(oblist[a])= obcopylist[a]; } |