diff options
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_particle.h | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_pointcache.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/anim.c | 13 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cloth.c | 9 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/depsgraph.c | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/fluidsim.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/lattice.c | 105 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 95 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/packedFile.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle.c | 547 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle_system.c | 42 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pointcache.c | 30 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/sequence.c | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 1 |
14 files changed, 498 insertions, 362 deletions
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 73f0195d1d8..aa24706077d 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -91,7 +91,8 @@ typedef struct ParticleTexture{ float ivel; /* used in reset */ float time, life, exist, size; /* used in init */ float pvel[3]; /* used in physics */ - float length, clump, kink, rough; /* used in path caching */ + float length, clump, kink, effector;/* used in path caching */ + float rough1, rough2, roughe; /* used in path caching */ } ParticleTexture; typedef struct BoidVecFunc{ @@ -270,7 +271,7 @@ void psys_update_world_cos(struct Object *ob, struct ParticleSystem *psys); 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_child_time(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra); +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); diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h index 3f1c45d28ec..c5d423c13ba 100644 --- a/source/blender/blenkernel/BKE_pointcache.h +++ b/source/blender/blenkernel/BKE_pointcache.h @@ -114,6 +114,7 @@ typedef struct PTCacheBaker { struct Scene *scene; int bake; int render; + int anim_init; int quick_step; struct PTCacheID *pid; int (*break_test)(void *data); diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 1aceca454d2..6c1b8eb9000 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -786,8 +786,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) { @@ -804,7 +805,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p psys->lattice = psys_get_lattice(scene, par, psys); /* 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 +851,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; @@ -894,7 +895,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); @@ -930,7 +931,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p } /* 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]; } diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 08caea565aa..089dafeb8c7 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -341,24 +341,27 @@ void bvhselftree_update_from_cloth(ClothModifierData *clmd, int moving) } int modifiers_indexInObject(Object *ob, ModifierData *md_seek); -static void cloth_write_state(int index, Cloth *cloth, float *data) +static void cloth_write_state(int index, void *cloth_v, float *data) { + Cloth *cloth= cloth_v; ClothVertex *vert = cloth->verts + index; memcpy(data, vert->x, 3 * sizeof(float)); memcpy(data + 3, vert->xconst, 3 * sizeof(float)); memcpy(data + 6, vert->v, 3 * sizeof(float)); } -static void cloth_read_state(int index, Cloth *cloth, float *data) +static void cloth_read_state(int index, void *cloth_v, float *data) { + Cloth *cloth= cloth_v; ClothVertex *vert = cloth->verts + index; memcpy(vert->x, data, 3 * sizeof(float)); memcpy(vert->xconst, data + 3, 3 * sizeof(float)); memcpy(vert->v, data + 6, 3 * sizeof(float)); } -static void cloth_cache_interpolate(int index, Cloth *cloth, float frs_sec, float cfra, float cfra1, float cfra2, float *data1, float *data2) +static void cloth_cache_interpolate(int index, void *cloth_v, float frs_sec, float cfra, float cfra1, float cfra2, float *data1, float *data2) { + Cloth *cloth= cloth_v; ClothVertex *vert = cloth->verts + index; ParticleKey keys[4]; float dfra; diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index a36b825293e..de036e25d82 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -568,14 +568,14 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA, "Particle Keyed Physics"); } - if(part->draw_as == PART_DRAW_OB && part->dup_ob) { + if(part->ren_as == PART_DRAW_OB && part->dup_ob) { node2 = dag_get_node(dag, part->dup_ob); dag_add_relation(dag, node, node2, DAG_RL_OB_OB, "Particle Object Visualisation"); if(part->dup_ob->type == OB_MBALL) dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA, "Particle Object Visualisation"); } - if(part->draw_as == PART_DRAW_GR && part->dup_group) { + if(part->ren_as == PART_DRAW_GR && part->dup_group) { for(go=part->dup_group->gobject.first; go; go=go->next) { node2 = dag_get_node(dag, go->ob); dag_add_relation(dag, node, node2, DAG_RL_OB_OB, "Particle Group Visualisation"); diff --git a/source/blender/blenkernel/intern/fluidsim.c b/source/blender/blenkernel/intern/fluidsim.c index 6eba64cf33d..2b4032af503 100644 --- a/source/blender/blenkernel/intern/fluidsim.c +++ b/source/blender/blenkernel/intern/fluidsim.c @@ -114,7 +114,7 @@ void fluidsim_init(FluidsimModifierData *fluidmd) // no bounding box needed // todo - reuse default init from elbeem! - fss->typeFlags = 0; + fss->typeFlags = OB_FSBND_NOSLIP; fss->domainNovecgen = 0; fss->volumeInitType = 1; // volume fss->partSlipValue = 0.0; diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 5cf52d09314..67d63d527cb 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -232,8 +232,8 @@ void free_lattice(Lattice *lt) if(lt->def) MEM_freeN(lt->def); if(lt->dvert) free_dverts(lt->dvert, lt->pntsu*lt->pntsv*lt->pntsw); if(lt->editlatt) { - if(lt->def) MEM_freeN(lt->def); - if(lt->dvert) free_dverts(lt->dvert, lt->pntsu*lt->pntsv*lt->pntsw); + if(lt->editlatt->def) MEM_freeN(lt->editlatt->def); + if(lt->editlatt->dvert) free_dverts(lt->editlatt->dvert, lt->pntsu*lt->pntsv*lt->pntsw); MEM_freeN(lt->editlatt); } } @@ -817,59 +817,68 @@ void outside_lattice(Lattice *lt) int u, v, w; float fac1, du=0.0, dv=0.0, dw=0.0; - bp= lt->def; + if(lt->flag & LT_OUTSIDE) { + bp= lt->def; - if(lt->pntsu>1) du= 1.0f/((float)lt->pntsu-1); - if(lt->pntsv>1) dv= 1.0f/((float)lt->pntsv-1); - if(lt->pntsw>1) dw= 1.0f/((float)lt->pntsw-1); - - for(w=0; w<lt->pntsw; w++) { - - for(v=0; v<lt->pntsv; v++) { - - for(u=0; u<lt->pntsu; u++, bp++) { - if(u==0 || v==0 || w==0 || u==lt->pntsu-1 || v==lt->pntsv-1 || w==lt->pntsw-1); - else { - - bp->hide= 1; - bp->f1 &= ~SELECT; - - /* u extrema */ - bp1= latt_bp(lt, 0, v, w); - bp2= latt_bp(lt, lt->pntsu-1, v, w); - - fac1= du*u; - bp->vec[0]= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0]; - bp->vec[1]= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1]; - bp->vec[2]= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2]; - - /* v extrema */ - bp1= latt_bp(lt, u, 0, w); - bp2= latt_bp(lt, u, lt->pntsv-1, w); - - fac1= dv*v; - bp->vec[0]+= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0]; - bp->vec[1]+= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1]; - bp->vec[2]+= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2]; - - /* w extrema */ - bp1= latt_bp(lt, u, v, 0); - bp2= latt_bp(lt, u, v, lt->pntsw-1); - - fac1= dw*w; - bp->vec[0]+= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0]; - bp->vec[1]+= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1]; - bp->vec[2]+= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2]; - - VecMulf(bp->vec, 0.3333333f); + if(lt->pntsu>1) du= 1.0f/((float)lt->pntsu-1); + if(lt->pntsv>1) dv= 1.0f/((float)lt->pntsv-1); + if(lt->pntsw>1) dw= 1.0f/((float)lt->pntsw-1); + + for(w=0; w<lt->pntsw; w++) { + + for(v=0; v<lt->pntsv; v++) { + + for(u=0; u<lt->pntsu; u++, bp++) { + if(u==0 || v==0 || w==0 || u==lt->pntsu-1 || v==lt->pntsv-1 || w==lt->pntsw-1); + else { + bp->hide= 1; + bp->f1 &= ~SELECT; + + /* u extrema */ + bp1= latt_bp(lt, 0, v, w); + bp2= latt_bp(lt, lt->pntsu-1, v, w); + + fac1= du*u; + bp->vec[0]= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0]; + bp->vec[1]= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1]; + bp->vec[2]= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2]; + + /* v extrema */ + bp1= latt_bp(lt, u, 0, w); + bp2= latt_bp(lt, u, lt->pntsv-1, w); + + fac1= dv*v; + bp->vec[0]+= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0]; + bp->vec[1]+= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1]; + bp->vec[2]+= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2]; + + /* w extrema */ + bp1= latt_bp(lt, u, v, 0); + bp2= latt_bp(lt, u, v, lt->pntsw-1); + + fac1= dw*w; + bp->vec[0]+= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0]; + bp->vec[1]+= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1]; + bp->vec[2]+= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2]; + + VecMulf(bp->vec, 0.3333333f); + + } } + } } - } - + else { + bp= lt->def; + + for(w=0; w<lt->pntsw; w++) + for(v=0; v<lt->pntsv; v++) + for(u=0; u<lt->pntsu; u++, bp++) + bp->hide= 0; + } } float (*lattice_getVertexCos(struct Object *ob, int *numVerts_r))[3] diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 9ecf3a32c2b..046dfcc9f87 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -6390,6 +6390,7 @@ static void particleSystemModifier_deformVerts( } if(psys){ + psmd->flag &= ~eParticleSystemFlag_psys_updated; particle_system_update(md->scene, ob, psys); psmd->flag |= eParticleSystemFlag_psys_updated; psmd->flag &= ~eParticleSystemFlag_DM_changed; @@ -6421,6 +6422,8 @@ static void particleInstanceModifier_initData(ModifierData *md) pimd->flag = eParticleInstanceFlag_Parents|eParticleInstanceFlag_Unborn| eParticleInstanceFlag_Alive|eParticleInstanceFlag_Dead; pimd->psys = 1; + pimd->position = 1.0f; + pimd->axis = 2; } static void particleInstanceModifier_copyData(ModifierData *md, ModifierData *target) @@ -6431,6 +6434,8 @@ static void particleInstanceModifier_copyData(ModifierData *md, ModifierData *ta tpimd->ob = pimd->ob; tpimd->psys = pimd->psys; tpimd->flag = pimd->flag; + tpimd->position = pimd->position; + tpimd->random_position = pimd->random_position; } static int particleInstanceModifier_dependsOnTime(ModifierData *md) @@ -6470,8 +6475,9 @@ static DerivedMesh * particleInstanceModifier_applyModifier( MFace *mface, *orig_mface; MVert *mvert, *orig_mvert; int i,totvert, totpart=0, totface, maxvert, maxface, first_particle=0; - short track=ob->trackflag%3, trackneg; + short track=ob->trackflag%3, trackneg, axis = pimd->axis; float max_co=0.0, min_co=0.0, temp_co[3], cross[3]; + float *size=NULL; trackneg=((ob->trackflag>2)?1:0); @@ -6498,6 +6504,25 @@ static DerivedMesh * particleInstanceModifier_applyModifier( if(totpart==0) return derivedData; + if(pimd->flag & eParticleInstanceFlag_UseSize) { + int p; + float *si; + si = size = MEM_callocN(totpart * sizeof(float), "particle size array"); + + if(pimd->flag & eParticleInstanceFlag_Parents) { + for(p=0, pa= psys->particles; p<psys->totpart; p++, pa++, si++) + *si = pa->size; + } + + if(pimd->flag & eParticleInstanceFlag_Children) { + ChildParticle *cpa = psys->child; + + for(p=0; p<psys->totchild; p++, cpa++, si++) { + *si = psys_get_child_size(psys, cpa, 0.0f, NULL); + } + } + } + pars=psys->particles; totvert=dm->getNumVerts(dm); @@ -6508,7 +6533,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier( psys->lattice=psys_get_lattice(md->scene, ob, psys); - if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED)){ + if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED){ float min_r[3], max_r[3]; INIT_MINMAX(min_r, max_r); @@ -6533,40 +6558,59 @@ static DerivedMesh * particleInstanceModifier_applyModifier( /*change orientation based on object trackflag*/ VECCOPY(temp_co,mv->co); - mv->co[0]=temp_co[track]; - mv->co[1]=temp_co[(track+1)%3]; - mv->co[2]=temp_co[(track+2)%3]; - - if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) && pimd->flag & eParticleInstanceFlag_Path){ - state.time=(mv->co[0]-min_co)/(max_co-min_co); - if(trackneg) - state.time=1.0f-state.time; - psys_get_particle_on_path(md->scene, pimd->ob, psys,first_particle + i/totvert, &state,1); + mv->co[axis]=temp_co[track]; + mv->co[(axis+1)%3]=temp_co[(track+1)%3]; + mv->co[(axis+2)%3]=temp_co[(track+2)%3]; + + if((psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) && pimd->flag & eParticleInstanceFlag_Path){ + float ran = 0.0f; + if(pimd->random_position != 0.0f) { + /* just use some static collection of random numbers */ + /* TODO: use something else that's unique to each instanced object */ + pa = psys->particles + (i/totvert)%totpart; + ran = pimd->random_position * 0.5 * (1.0f + pa->r_ave[0]); + } - mv->co[0] = 0.0; + if(pimd->flag & eParticleInstanceFlag_KeepShape) { + state.time = pimd->position * (1.0f - ran); + } + else { + state.time=(mv->co[axis]-min_co)/(max_co-min_co) * pimd->position * (1.0f - ran); + + if(trackneg) + state.time=1.0f-state.time; + + mv->co[axis] = 0.0; + } + + psys_get_particle_on_path(md->scene, pimd->ob, psys,first_particle + i/totvert, &state,1); Normalize(state.vel); - if(state.vel[0] < -0.9999 || state.vel[0] > 0.9999) { - state.rot[0] = 1.0; + /* TODO: incremental rotations somehow */ + if(state.vel[axis] < -0.9999 || state.vel[axis] > 0.9999) { + state.rot[0] = 1; state.rot[1] = state.rot[2] = state.rot[3] = 0.0f; } else { - /* a cross product of state.vel and a unit vector in x-direction */ - cross[0] = 0.0f; - cross[1] = -state.vel[2]; - cross[2] = state.vel[1]; + float temp[3] = {0.0f,0.0f,0.0f}; + temp[axis] = 1.0f; + + Crossf(cross, temp, state.vel); - /* state.vel[0] is the only component surviving from a dot product with a vector in x-direction*/ - VecRotToQuat(cross,saacos(state.vel[0]),state.rot); + /* state.vel[axis] is the only component surviving from a dot product with the axis */ + VecRotToQuat(cross,saacos(state.vel[axis]),state.rot); } + } else{ state.time=-1.0; - psys_get_particle_state(md->scene, pimd->ob, psys, i/totvert, &state,1); + psys_get_particle_state(md->scene, pimd->ob, psys, first_particle + i/totvert, &state,1); } QuatMulVecf(state.rot,mv->co); + if(pimd->flag & eParticleInstanceFlag_UseSize) + VecMulf(mv->co, size[i/totvert]); VECADD(mv->co,mv->co,state.co); } @@ -6619,6 +6663,9 @@ static DerivedMesh * particleInstanceModifier_applyModifier( psys->lattice= NULL; } + if(size) + MEM_freeN(size); + return result; } static DerivedMesh *particleInstanceModifier_applyModifierEM( @@ -7257,10 +7304,10 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd, timestep= psys_get_timestep(part); - if(part->flag & PART_GLOB_TIME) + //if(part->flag & PART_GLOB_TIME) cfra=bsystem_time(scene, 0,(float)scene->r.cfra,0.0); - else - cfra=bsystem_time(scene, ob,(float)scene->r.cfra,0.0); + //else + // cfra=bsystem_time(scene, ob,(float)scene->r.cfra,0.0); /* hash table for vertice <-> particle relations */ vertpahash= BLI_edgehash_new(); diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c index 4d88556d8bf..02b0f6a45a0 100644 --- a/source/blender/blenkernel/intern/packedFile.c +++ b/source/blender/blenkernel/intern/packedFile.c @@ -377,8 +377,6 @@ there was an error or when the user desides to cancel the operation. char *unpackFile(ReportList *reports, char *abs_name, char *local_name, PackedFile *pf, int how) { - char menu[6 *(FILE_MAXDIR + FILE_MAXFILE + 100)]; - char line[FILE_MAXDIR + FILE_MAXFILE + 100]; char *newname = NULL, *temp = NULL; // char newabs[FILE_MAXDIR + FILE_MAXFILE]; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 5bf9335d211..4488f8cdffd 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -81,6 +81,10 @@ static void key_from_object(Object *ob, ParticleKey *key); static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float *fuv, float *orco, ParticleTexture *ptex, int event); +static void get_child_modifier_parameters(ParticleSettings *part, ParticleThreadContext *ctx, + ChildParticle *cpa, short cpa_from, int cpa_num, float *cpa_fuv, float *orco, ParticleTexture *ptex); +static void do_child_modifiers(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSettings *part, + ParticleTexture *ptex, ParticleKey *par, float *par_rot, ChildParticle *cpa, float *orco, ParticleKey *state, float t); /* few helpers for countall etc. */ int count_particles(ParticleSystem *psys){ @@ -452,7 +456,7 @@ void psys_free(Object *ob, ParticleSystem * psys) for(tpsys=ob->particlesystem.first; tpsys; tpsys=tpsys->next){ if(tpsys->part) { - if(ELEM(tpsys->part->draw_as,PART_DRAW_OB,PART_DRAW_GR)) + if(ELEM(tpsys->part->ren_as,PART_DRAW_OB,PART_DRAW_GR)) { nr++; break; @@ -491,6 +495,7 @@ typedef struct ParticleRenderData { ChildParticle *child; ParticleCacheKey **pathcache; ParticleCacheKey **childcache; + ListBase pathcachebufs, childcachebufs; int totchild, totcached, totchildcache; DerivedMesh *dm; int totdmvert, totdmedge, totdmface; @@ -577,8 +582,12 @@ void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[][4], float data->child= psys->child; data->totchild= psys->totchild; data->pathcache= psys->pathcache; + data->pathcachebufs.first = psys->pathcachebufs.first; + data->pathcachebufs.last = psys->pathcachebufs.last; data->totcached= psys->totcached; data->childcache= psys->childcache; + data->childcachebufs.first = psys->childcachebufs.first; + data->childcachebufs.last = psys->childcachebufs.last; data->totchildcache= psys->totchildcache; if(psmd->dm) @@ -591,6 +600,8 @@ void psys_render_set(Object *ob, ParticleSystem *psys, float viewmat[][4], float psys->pathcache= NULL; psys->childcache= NULL; psys->totchild= psys->totcached= psys->totchildcache= 0; + psys->pathcachebufs.first = psys->pathcachebufs.last = NULL; + psys->childcachebufs.first = psys->childcachebufs.last = NULL; Mat4CpyMat4(data->winmat, winmat); Mat4MulMat4(data->viewmat, ob->obmat, viewmat); @@ -631,8 +642,12 @@ void psys_render_restore(Object *ob, ParticleSystem *psys) psys->child= data->child; psys->totchild= data->totchild; psys->pathcache= data->pathcache; + psys->pathcachebufs.first = data->pathcachebufs.first; + psys->pathcachebufs.last = data->pathcachebufs.last; psys->totcached= data->totcached; psys->childcache= data->childcache; + psys->childcachebufs.first = data->childcachebufs.first; + psys->childcachebufs.last = data->childcachebufs.last; psys->totchildcache= data->totchildcache; psmd->dm= data->dm; @@ -663,7 +678,7 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot) int *origindex, *facetotvert; int a, b, totorigface, totface, newtot, skipped; - if(part->draw_as!=PART_DRAW_PATH || !(part->draw & PART_DRAW_REN_STRAND)) + if(part->ren_as!=PART_DRAW_PATH || !(part->draw & PART_DRAW_REN_STRAND)) return tot; if(!ctx->psys->renderdata) return tot; @@ -1992,13 +2007,11 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, ParticleData *pa=NULL; ParticleTexture ptex; 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 co[3], orco[3], ornor[3], t, cpa_1st[3], dvec[3]; + float branch_begin, branch_end, branch_prob, rough_rand; + float length, max_length = 1.0f, cur_length = 0.0f; float eff_length, eff_vec[3]; - int k, cpa_num, guided = 0; + int k, cpa_num; short cpa_from; if(part->flag & PART_BRANCHING) { @@ -2059,9 +2072,11 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, psys_particle_on_emitter(ctx->psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa->fuv,foffset,co,ornor,0,0,orco,0); - /* we need to save the actual root position of the child for positioning it accurately to the surface of the emitter */ - VECCOPY(cpa_1st,co); - Mat4MulVecfl(ob->obmat,cpa_1st); + if(part->path_start==0.0f) { + /* we need to save the actual root position of the child for positioning it accurately to the surface of the emitter */ + VECCOPY(cpa_1st,co); + Mat4MulVecfl(ob->obmat,cpa_1st); + } pa=0; } @@ -2098,43 +2113,13 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, #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_DENS|MAP_PA_LENGTH|MAP_PA_CLUMP|MAP_PA_KINK|MAP_PA_ROUGH); - - pa_length=ptex.length; - pa_clump=ptex.clump; - pa_kink=ptex.kink; - pa_rough1=ptex.rough; - pa_rough2=ptex.rough; - pa_roughe=ptex.rough; - pa_effector= 1.0f; + get_child_modifier_parameters(part, ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex); 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) - pa_clump*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_clump); - if(ctx->vg_kink) - pa_kink*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_kink); - if(ctx->vg_rough1) - pa_rough1*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_rough1); - if(ctx->vg_rough2) - pa_rough2*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_rough2); - if(ctx->vg_roughe) - pa_roughe*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_roughe); - if(ctx->vg_effector) - pa_effector*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_effector); - /* create the child path */ for(k=0,state=keys; k<=ctx->steps; k++,state++){ if(ctx->between){ @@ -2158,12 +2143,14 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, key[w]++; w++; } - if(k==0){ - /* calculate the offset between actual child root position and first position interpolated from parents */ - VECSUB(cpa_1st,cpa_1st,state->co); + if(part->path_start==0.0f) { + if(k==0){ + /* calculate the offset between actual child root position and first position interpolated from parents */ + VECSUB(cpa_1st,cpa_1st,state->co); + } + /* apply offset for correct positioning */ + VECADD(state->co,state->co,cpa_1st); } - /* apply offset for correct positioning */ - VECADD(state->co,state->co,cpa_1st); } else{ /* offset the child from the parent position */ @@ -2177,7 +2164,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(ctx->scene, 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, ptex.effector, 0.0f, ctx->cfra, &eff_length, eff_vec); } else { VecSubf(eff_vec,(state+1)->co,state->co); @@ -2203,67 +2190,50 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, } /* 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(ctx->scene, (ParticleKey*)state, cpa->parent, t, &(psys->effectors)); - - if(guided==0){ - if(part->kink) - 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); - } - - if(part->flag & PART_BRANCHING && ctx->between == 0 && part->flag & PART_ANIM_BRANCHING) - rough_t = t * rough_rand; - else - rough_t = t; + do_child_modifiers(ctx->scene, ob, psys, part, &ptex, (ParticleKey *)par, par_rot, cpa, orco, (ParticleKey *)state, t); - if(part->rough1 != 0.0 && pa_rough1 != 0.0) - do_rough(orco, rough_t, pa_rough1*part->rough1, part->rough1_size, 0.0, (ParticleKey*)state); - - if(part->rough2 != 0.0 && pa_rough2 != 0.0) - do_rough(cpa->rand, rough_t, pa_rough2*part->rough2, part->rough2_size, part->rough2_thres, (ParticleKey*)state); - - if(part->rough_end != 0.0 && pa_roughe != 0.0) - do_rough_end(cpa->rand, rough_t, pa_roughe*part->rough_end, part->rough_end_shape, (ParticleKey*)state, (ParticleKey*)par); - - if(part->flag & PART_BRANCHING && ctx->between==0){ - if(branch_prob > part->branch_thres){ - branchfac=0.0f; - } - else{ - if(part->flag & PART_SYMM_BRANCHING){ - if(t < branch_begin || t > branch_end) - branchfac=0.0f; - else{ - if((t-branch_begin)/(branch_end-branch_begin)<0.5) - branchfac=2.0f*(t-branch_begin)/(branch_end-branch_begin); - else - branchfac=2.0f*(branch_end-t)/(branch_end-branch_begin); + /* TODO: better branching */ + //if(part->flag & PART_BRANCHING && ctx->between == 0 && part->flag & PART_ANIM_BRANCHING) + // rough_t = t * rough_rand; + //else + // rough_t = t; - CLAMP(branchfac,0.0f,1.0f); - } - } - else{ - if(t < branch_begin){ - branchfac=0.0f; - } - else{ - branchfac=(t-branch_begin)/((1.0f-branch_begin)*0.5f); - CLAMP(branchfac,0.0f,1.0f); - } - } - } + /* TODO: better branching */ + //if(part->flag & PART_BRANCHING && ctx->between==0){ + // if(branch_prob > part->branch_thres){ + // branchfac=0.0f; + // } + // else{ + // if(part->flag & PART_SYMM_BRANCHING){ + // if(t < branch_begin || t > branch_end) + // branchfac=0.0f; + // else{ + // if((t-branch_begin)/(branch_end-branch_begin)<0.5) + // branchfac=2.0f*(t-branch_begin)/(branch_end-branch_begin); + // else + // branchfac=2.0f*(branch_end-t)/(branch_end-branch_begin); + + // CLAMP(branchfac,0.0f,1.0f); + // } + // } + // else{ + // if(t < branch_begin){ + // branchfac=0.0f; + // } + // else{ + // branchfac=(t-branch_begin)/((1.0f-branch_begin)*0.5f); + // CLAMP(branchfac,0.0f,1.0f); + // } + // } + // } - if(i<psys->totpart) - VecLerpf(state->co, (pcache[i] + k)->co, state->co, branchfac); - else - /* this is not threadsafe, but should only happen for - * branching particles particles, which are not threaded */ - VecLerpf(state->co, (cache[i - psys->totpart] + k)->co, state->co, branchfac); - } + // if(i<psys->totpart) + // VecLerpf(state->co, (pcache[i] + k)->co, state->co, branchfac); + // else + // /* this is not threadsafe, but should only happen for + // * branching particles particles, which are not threaded */ + // VecLerpf(state->co, (cache[i - psys->totpart] + k)->co, state->co, branchfac); + //} /* we have to correct velocity because of kink & clump */ if(k>1){ @@ -2287,9 +2257,9 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, else{ /* initialize length calculation */ if(part->flag&PART_ABS_LENGTH) - max_length= part->abslength*pa_length; + max_length= part->abslength*ptex.length; else - max_length= pa_length; + max_length= ptex.length; cur_length= 0.0f; } @@ -2383,7 +2353,36 @@ void psys_cache_child_paths(Scene *scene, Object *ob, ParticleSystem *psys, floa psys_threads_free(pthreads); } +static void get_pointcache_keys_for_time(ParticleSystem *psys, int index, float t, ParticleKey *key1, ParticleKey *key2) +{ + PointCache *cache = psys->pointcache; + static PTCacheMem *pm = NULL; + + if(cache->flag & PTCACHE_DISK_CACHE) { + /* TODO */ + } + else { + if(index < 0) { /* initialize */ + pm = cache->mem_cache.first; + if(pm) + pm = pm->next; + } + else { + if(pm) { + while(pm && pm->next && (float)pm->frame < t) + pm = pm->next; + copy_particle_key(key2, ((ParticleKey *)pm->data) + index, 1); + copy_particle_key(key1, ((ParticleKey *)(pm->prev)->data) + index, 1); + } + else if(cache->mem_cache.first) { + pm = cache->mem_cache.first; + copy_particle_key(key2, ((ParticleKey *)pm->data) + index, 1); + copy_particle_key(key1, ((ParticleKey *)pm->data) + index, 1); + } + } + } +} /* Calculates paths ready for drawing/rendering. */ /* -Usefull for making use of opengl vertex arrays for super fast strand drawing. */ /* -Makes child strands possible and creates them too into the cache. */ @@ -2409,7 +2408,7 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra float birthtime = 0.0, dietime = 0.0; 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 col[4] = {0.5f, 0.5f, 0.5f, 1.0f}; float prev_tangent[3], hairmat[4][4]; int k,i; int steps = (int)pow(2.0, (double)psys->part->draw_step); @@ -2418,13 +2417,18 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra float nosel_col[3]; float length, vec[3]; float *vg_effector= NULL, effector=0.0f; - float *vg_length= NULL, pa_length=1.0f, max_length=1.0f, cur_length=0.0f; - float len, dvec[3]; + float *vg_length= NULL, pa_length=1.0f; + int keyed, baked; /* we don't have anything valid to create paths from so let's quit here */ - if((psys->flag & PSYS_HAIR_DONE)==0 && (psys->flag & PSYS_KEYED)==0) + if((psys->flag & PSYS_HAIR_DONE)==0 && (psys->flag & PSYS_KEYED)==0 && (psys->pointcache->flag & PTCACHE_BAKED)==0) return; + BLI_srandom(psys->seed); + + keyed = psys->flag & PSYS_KEYED; + baked = psys->pointcache->flag & PTCACHE_BAKED; + if(psys->renderdata) { steps = (int)pow(2.0, (double)psys->part->ren_step); } @@ -2488,7 +2492,8 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra else memset(cache[i], 0, sizeof(*cache[i])*(steps+1)); if(!edit && !psys->totchild) { - pa_length = part->length * (1.0f - part->randlength*pa->r_ave[0]); + //pa_length = part->length * (1.0f - part->randlength*pa->r_ave[0]); + pa_length = 1.0f - part->randlength * 0.5 * (1.0f + pa->r_ave[0]); if(vg_length) pa_length *= psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_length); } @@ -2499,13 +2504,19 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra ekey = edit->keys[i]; /*--get the first data points--*/ - if(psys->flag & PSYS_KEYED) { + if(keyed) { kkey[0] = pa->keys; kkey[1] = kkey[0] + 1; birthtime = kkey[0]->time; dietime = kkey[0][pa->totkey-1].time; } + else if(baked) { + get_pointcache_keys_for_time(psys, -1, 0.0f, NULL, NULL); + + birthtime = pa->time; + dietime = pa->dietime; + } else { hkey[0] = pa->hair; hkey[1] = hkey[0] + 1; @@ -2516,6 +2527,25 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat); } + if(!edit) { + if(part->draw & PART_ABS_PATH_TIME) { + birthtime = MAX2(birthtime, part->path_start); + dietime = MIN2(dietime, part->path_end); + } + else { + float tb = birthtime; + birthtime = tb + part->path_start * (dietime - tb); + dietime = tb + part->path_end * (dietime - tb); + } + + if(birthtime >= dietime) { + cache[i]->steps = -1; + continue; + } + + dietime = birthtime + pa_length * (dietime - birthtime); + } + if(soft){ bp[0] = soft->bpoint + pa->bpi; bp[1] = bp[0] + 1; @@ -2527,13 +2557,16 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra t = birthtime + time * (dietime - birthtime); - if(psys->flag & PSYS_KEYED) { + if(keyed) { while(kkey[1]->time < t) { kkey[1]++; } kkey[0] = kkey[1] - 1; } + else if(baked) { + get_pointcache_keys_for_time(psys, i, t, keys+1, keys+2); + } else { while(hkey[1]->time < t) { hkey[1]++; @@ -2548,17 +2581,19 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra bp_to_particle(keys + 1, bp[0], hkey[0]); bp_to_particle(keys + 2, bp[1], hkey[1]); } - else if(psys->flag & PSYS_KEYED) { + else if(keyed) { memcpy(keys + 1, kkey[0], sizeof(ParticleKey)); memcpy(keys + 2, kkey[1], sizeof(ParticleKey)); } + else if(baked) + ; /* keys already set */ else { hair_to_particle(keys + 1, hkey[0]); hair_to_particle(keys + 2, hkey[1]); } - if((psys->flag & PSYS_KEYED)==0) { + if(!keyed && !baked) { if(soft) { if(hkey[0] != pa->hair) bp_to_particle(keys, bp[0] - 1, hkey[0] - 1); @@ -2591,18 +2626,18 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra keytime = (t - keys[1].time) / dfra; /* convert velocity to timestep size */ - if(psys->flag & PSYS_KEYED){ + if(keyed || baked){ VecMulf(keys[1].vel, dfra / frs_sec); VecMulf(keys[2].vel, dfra / frs_sec); } /* now we should have in chronologiacl order k1<=k2<=t<=k3<=k4 with keytime between [0,1]->[k2,k3] (k1 & k4 used for cardinal & bspline interpolation)*/ - psys_interpolate_particle((psys->flag & PSYS_KEYED) ? -1 /* signal for cubic interpolation */ + psys_interpolate_particle((keyed || baked) ? -1 /* signal for cubic interpolation */ : ((psys->part->flag & PART_HAIR_BSPLINE) ? KEY_BSPLINE : KEY_CARDINAL) ,keys, keytime, &result, 0); /* the velocity needs to be converted back from cubic interpolation */ - if(psys->flag & PSYS_KEYED){ + if(keyed || baked){ VecMulf(result.vel, frs_sec / dfra); } else if(soft==NULL) { /* softbody and keyed are allready in global space */ @@ -2717,28 +2752,6 @@ void psys_cache_paths(Scene *scene, Object *ob, ParticleSystem *psys, float cfra } } - - if(!edit && !psys->totchild) { - /* check if path needs to be cut before actual end of data points */ - if(k){ - VECSUB(dvec,ca->co,(ca-1)->co); - if(part->flag&PART_ABS_LENGTH) - len=VecLength(dvec); - else - len=1.0f/(float)steps; - - k=check_path_length(k,cache[i],ca,max_length,&cur_length,len,dvec); - } - else{ - /* initialize length calculation */ - if(part->flag&PART_ABS_LENGTH) - max_length= part->abslength*pa_length; - else - max_length= pa_length; - - cur_length= 0.0f; - } - } } } @@ -2990,7 +3003,8 @@ static void default_particle_settings(ParticleSettings *part) part->type= PART_EMITTER; part->distr= PART_DISTR_JIT; - part->draw_as=PART_DRAW_DOT; + part->draw_as = PART_DRAW_REND; + part->ren_as = PART_DRAW_HALO; part->bb_uv_split=1; part->bb_align=PART_BB_VIEW; part->bb_split_offset=PART_BB_OFF_LINEAR; @@ -3046,6 +3060,8 @@ static void default_particle_settings(ParticleSettings *part) part->rough_end_shape=1.0; part->draw_line[0]=0.5; + part->path_start = 0.0f; + part->path_end = 1.0f; part->banking=1.0; part->max_bank=1.0; @@ -3282,7 +3298,7 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float if((event & mtex->pmapto) & MAP_PA_KINK) 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); + ptex->rough1= ptex->rough2= ptex->roughe= texture_value_blend(def,ptex->rough1,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); } @@ -3291,7 +3307,11 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float if(event & MAP_PA_LENGTH) { CLAMP(ptex->length,0.0,1.0); } 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_ROUGH) { + CLAMP(ptex->rough1,0.0,1.0); + CLAMP(ptex->rough2,0.0,1.0); + CLAMP(ptex->roughe,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) @@ -3392,12 +3412,12 @@ float psys_get_size(Object *ob, Material *ma, ParticleSystemModifierData *psmd, return size*part->size; } -float psys_get_child_time(ParticleSystem *psys, ChildParticle *cpa, float cfra) +float psys_get_child_time(ParticleSystem *psys, ChildParticle *cpa, float cfra, float *birthtime, float *dietime) { ParticleSettings *part = psys->part; + float time, life; if(part->childtype==PART_CHILD_FACES){ - float time; int w=0; time=0.0; while(w<4 && cpa->pa[w]>=0){ @@ -3405,12 +3425,21 @@ float psys_get_child_time(ParticleSystem *psys, ChildParticle *cpa, float cfra) w++; } - return (cfra-time)/(part->lifetime*(1.0f-part->randlife*cpa->rand[1])); + life = part->lifetime*(1.0f-part->randlife*cpa->rand[1]); } else{ ParticleData *pa = psys->particles + cpa->parent; - return (cfra-pa->time)/pa->lifetime; + + time = pa->time; + life = pa->lifetime; } + + if(birthtime) + *birthtime = time; + if(dietime) + *dietime = time+life; + + return (cfra-time)/life; } float psys_get_child_size(ParticleSystem *psys, ChildParticle *cpa, float cfra, float *pa_time) { @@ -3427,7 +3456,7 @@ float psys_get_child_size(ParticleSystem *psys, ChildParticle *cpa, float cfra, if(pa_time) time=*pa_time; else - time=psys_get_child_time(psys,cpa,cfra); + time=psys_get_child_time(psys,cpa,cfra,NULL,NULL); /* correction for lifetime */ calc_ipo(part->ipo, 100*time); @@ -3449,6 +3478,64 @@ float psys_get_child_size(ParticleSystem *psys, ChildParticle *cpa, float cfra, return size; } +static void get_child_modifier_parameters(ParticleSettings *part, ParticleThreadContext *ctx, ChildParticle *cpa, short cpa_from, int cpa_num, float *cpa_fuv, float *orco, ParticleTexture *ptex) +{ + ptex->length=part->length*(1.0f - part->randlength*cpa->rand[0]); + ptex->clump=1.0; + ptex->kink=1.0; + ptex->rough1= 1.0; + ptex->rough2= 1.0; + ptex->roughe= 1.0; + ptex->exist= 1.0; + ptex->effector= 1.0; + + get_cpa_texture(ctx->dm,ctx->ma,cpa_num,cpa_fuv,orco,ptex, + MAP_PA_DENS|MAP_PA_LENGTH|MAP_PA_CLUMP|MAP_PA_KINK|MAP_PA_ROUGH); + + + if(ptex->exist < cpa->rand[1]) + return; + + if(ctx->vg_length) + ptex->length*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_length); + if(ctx->vg_clump) + ptex->clump*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_clump); + if(ctx->vg_kink) + ptex->kink*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_kink); + if(ctx->vg_rough1) + ptex->rough1*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_rough1); + if(ctx->vg_rough2) + ptex->rough2*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_rough2); + if(ctx->vg_roughe) + ptex->roughe*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_roughe); + if(ctx->vg_effector) + ptex->effector*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_effector); +} +static void do_child_modifiers(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSettings *part, ParticleTexture *ptex, ParticleKey *par, float *par_rot, ChildParticle *cpa, float *orco, ParticleKey *state, float t) +{ + int guided = 0; + + if(part->flag & PART_CHILD_EFFECT) + /* state is safe to cast, since only co and vel are used */ + guided = do_guide(scene, (ParticleKey*)state, cpa->parent, t, &(psys->effectors)); + + if(guided==0){ + if(part->kink) + do_prekink(state, par, par_rot, t, part->kink_freq * ptex->kink, part->kink_shape, + part->kink_amp, part->kink, part->kink_axis, ob->obmat); + + do_clump(state, par, t, part->clumpfac, part->clumppow, ptex->clump); + } + + if(part->rough1 != 0.0 && ptex->rough1 != 0.0) + do_rough(orco, t, ptex->rough1*part->rough1, part->rough1_size, 0.0, state); + + if(part->rough2 != 0.0 && ptex->rough2 != 0.0) + do_rough(cpa->rand, t, ptex->rough2*part->rough2, part->rough2_size, part->rough2_thres, state); + + if(part->rough_end != 0.0 && ptex->roughe != 0.0) + do_rough_end(cpa->rand, t, ptex->roughe*part->rough_end, part->rough_end_shape, state, par); +} /* get's hair (or keyed) particles state at the "path time" specified in state->time */ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, int p, ParticleKey *state, int vel) { @@ -3460,17 +3547,20 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i ParticleTexture ptex; ParticleKey *kkey[2] = {NULL, NULL}; HairKey *hkey[2] = {NULL, NULL}; - ParticleKey *par=0, keys[4]; + ParticleKey *par=0, keys[4], tstate; + ParticleThreadContext ctx; /* fake thread context for child modifiers */ 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; int totparent = 0; int totpart = psys->totpart; int totchild = psys->totchild; short between = 0, edit = 0; + int keyed = psys->flag & PSYS_KEYED; + int cached = !keyed && part->type != PART_HAIR; + float *cpa_fuv; int cpa_num; short cpa_from; //if(psys_in_edit_mode(scene, psys)){ @@ -3479,12 +3569,6 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i // edit=1; //} - /* user want's cubic interpolation but only without sb it possible */ - //if(interpolation==PART_INTER_CUBIC && baked && psys->softflag==OB_SB_ENABLE) - // interpolation=PART_INTER_BSPLINE; - //else if(baked==0) /* it doesn't make sense to use other types for keyed */ - // interpolation=PART_INTER_CUBIC; - t=state->time; CLAMP(t, 0.0, 1.0); @@ -3497,20 +3581,29 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i return; } - if(psys->flag & PSYS_KEYED) { + if(keyed) { kkey[0] = pa->keys; kkey[1] = kkey[0] + 1; - real_t = kkey[0]->time + t * (kkey[0][pa->totkey-1].time - kkey[0]->time); + if(state->time < 0.0f) + real_t = -state->time; + else + real_t = kkey[0]->time + t * (kkey[0][pa->totkey-1].time - kkey[0]->time); + } + else if(cached) { + get_pointcache_keys_for_time(psys, -1, 0.0f, NULL, NULL); } else { hkey[0] = pa->hair; hkey[1] = pa->hair + 1; - real_t = hkey[0]->time + (hkey[0][pa->totkey-1].time - hkey[0]->time) * t; + if(state->time < 0.0f) + real_t = -state->time; + else + real_t = hkey[0]->time + t * (hkey[0][pa->totkey-1].time - hkey[0]->time); } - if(psys->flag & PSYS_KEYED) { + if(keyed) { while(kkey[1]->time < real_t) { kkey[1]++; } @@ -3519,6 +3612,14 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i memcpy(keys + 1, kkey[0], sizeof(ParticleKey)); memcpy(keys + 2, kkey[1], sizeof(ParticleKey)); } + else if(cached) { + if(state->time < 0.0f) /* flag for time in frames */ + real_t = -state->time; + else + real_t = pa->time + t * (pa->dietime - pa->time); + + get_pointcache_keys_for_time(psys, p, real_t, keys+1, keys+2); + } else { while(hkey[1]->time < real_t) hkey[1]++; @@ -3529,63 +3630,35 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i hair_to_particle(keys + 2, hkey[1]); } - if((psys->flag & PSYS_KEYED)==0) { - //if(soft){ - // if(key[0] != sbel.keys) - // DB_copy_key(&k1,key[0]-1); - // else - // DB_copy_key(&k1,&k2); - //} - //else{ + if(!keyed && !cached) { if(hkey[0] != pa->hair) hair_to_particle(keys, hkey[0] - 1); else hair_to_particle(keys, hkey[0]); - //} - //if(soft){ - // if(key[1] != sbel.keys + sbel.totkey-1) - // DB_copy_key(&k4,key[1]+1); - // else - // DB_copy_key(&k4,&k3); - //} - //else { if(hkey[1] != pa->hair + pa->totkey - 1) hair_to_particle(keys + 3, hkey[1] + 1); else hair_to_particle(keys + 3, hkey[1]); } - //} - - //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); - //else{ - // /* TODO: different rotations */ - // float nvel[3]; - // VECCOPY(nvel,state->vel); - // VecMulf(nvel,-1.0f); - // vectoquat(nvel, OB_POSX, OB_POSZ, state->rot); - //} dfra = keys[2].time - keys[1].time; keytime = (real_t - keys[1].time) / dfra; /* convert velocity to timestep size */ - if(psys->flag & PSYS_KEYED){ + if(keyed || cached){ VecMulf(keys[1].vel, dfra / frs_sec); VecMulf(keys[2].vel, dfra / frs_sec); QuatInterpol(state->rot,keys[1].rot,keys[2].rot,keytime); } - psys_interpolate_particle((psys->flag & PSYS_KEYED) ? -1 /* signal for cubic interpolation */ + psys_interpolate_particle((keyed || cached) ? -1 /* signal for cubic interpolation */ : ((psys->part->flag & PART_HAIR_BSPLINE) ? KEY_BSPLINE : KEY_CARDINAL) ,keys, keytime, state, 1); /* the velocity needs to be converted back from cubic interpolation */ - if(psys->flag & PSYS_KEYED){ + if(keyed || cached){ VecMulf(state->vel, frs_sec / dfra); } else { @@ -3606,8 +3679,11 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i } else if(totchild){ //Mat4Invert(imat,ob->obmat); - + cpa=psys->child+p-totpart; + + if(state->time < 0.0f) + t = psys_get_child_time(psys, cpa, -state->time, NULL, NULL); if(totchild && part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){ totparent=(int)(totchild*part->parents*0.3); @@ -3624,7 +3700,7 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i /* get parent states */ while(w<4 && cpa->pa[w]>=0){ - keys[w].time = t; + keys[w].time = state->time; psys_get_particle_on_path(scene, ob, psys, cpa->pa[w], keys+w, 1); w++; } @@ -3650,7 +3726,7 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i else{ /* get the parent state */ - keys->time = t; + keys->time = state->time; psys_get_particle_on_path(scene, ob, psys, cpa->parent, keys,1); /* get the original coordinates (orco) for texture usage */ @@ -3672,15 +3748,11 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i #endif // XXX old animation system /* get different child parameters from textures & vgroups */ - ptex.clump=1.0; - ptex.kink=1.0; - - get_cpa_texture(psmd->dm,ma,cpa_num,cpa_fuv,orco,&ptex,MAP_PA_CLUMP|MAP_PA_KINK); - - pa_clump=ptex.clump; - pa_kink=ptex.kink; - - /* TODO: vertex groups */ + memset(&ctx, 0, sizeof(ParticleThreadContext)); + ctx.dm = psmd->dm; + ctx.ma = ma; + /* TODO: assign vertex groups */ + get_child_modifier_parameters(part, &ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex); if(between){ int w=0; @@ -3708,46 +3780,33 @@ void psys_get_particle_on_path(Scene *scene, Object *ob, ParticleSystem *psys, i } par = keys; - //if(totparent){ - // if(p-totpart>=totparent){ - // key.time=t; - // psys_get_particle_on_path(ob,psys,totpart+cpa->parent,&key,1); - // bti->convert_dynamic_key(bsys,&key,par,cpar); - // } - // else - // par=0; - //} - //else - // DB_get_key_on_path(bsys,cpa->parent,t,par,cpar); - - /* apply different deformations to the child path */ - if(part->kink) - do_prekink(state, par, par->rot, t, part->kink_freq * pa_kink, part->kink_shape, - part->kink_amp, part->kink, part->kink_axis, ob->obmat); - - do_clump(state, par, t, part->clumpfac, part->clumppow, 1.0f); - - if(part->rough1 != 0.0) - do_rough(orco, t, part->rough1, part->rough1_size, 0.0, state); - if(part->rough2 != 0.0) - do_rough(cpa->rand, t, part->rough2, part->rough2_size, part->rough2_thres, state); + if(vel) + copy_particle_key(&tstate, state, 1); - if(part->rough_end != 0.0) - do_rough_end(cpa->rand, t, part->rough_end, part->rough_end_shape, state, par); + /* apply different deformations to the child path */ + do_child_modifiers(scene, ob, psys, part, &ptex, par, par->rot, cpa, orco, state, t); + + /* try to estimate correct velocity */ + if(vel){ + ParticleKey tstate; + float length = VecLength(state->vel); + + if(t>=0.001f){ + tstate.time=t-0.001f; + psys_get_particle_on_path(scene,ob,psys,p,&tstate,0); + VECSUB(state->vel,state->co,tstate.co); + Normalize(state->vel); + } + else{ + tstate.time=t+0.001f; + psys_get_particle_on_path(scene, ob,psys,p,&tstate,0); + VECSUB(state->vel,tstate.co,state->co); + Normalize(state->vel); + } - //if(vel){ - // if(t>=0.001f){ - // tstate.time=t-0.001f; - // 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(scene, ob,psys,p,&tstate,0); - // VECSUB(state->vel,tstate.co,state->co); - // } - //} + VecMulf(state->vel, length); + } } } /* gets particle's state at a time, returns 1 if particle exists and can be seen and 0 if not */ @@ -3774,7 +3833,7 @@ int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psy pa=psys->particles+p; if(between){ - state->time = psys_get_child_time(psys,&psys->child[p-totpart],cfra); + state->time = psys_get_child_time(psys,&psys->child[p-totpart],cfra,NULL,NULL); if(always==0) if((state->time<0.0 && (part->flag & PART_UNBORN)==0) diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 591b6ca9be5..07e0e82a86d 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2205,8 +2205,10 @@ void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra *sfra = MAX2(1, (int)part->sta); *efra = MIN2((int)(part->end + part->lifetime + 1.0), scene->r.efra); } -static void particle_write_state(int index, ParticleSystem *psys, float *data) +static void particle_write_state(int index, void *psys_ptr, float *data) { + ParticleSystem *psys= psys_ptr; + memcpy(data, (float *)(&(psys->particles+index)->state), sizeof(ParticleKey)); } static void particle_read_state(int index, void *psys_ptr, float *data) @@ -2225,7 +2227,7 @@ static void particle_cache_interpolate(int index, void *psys_ptr, float frs_sec, ParticleSystem *psys= psys_ptr; ParticleData *pa = psys->particles + index; ParticleKey keys[4]; - float dfra, cfra1f = (float)cfra1, cfra2f(float); + float dfra; cfra = MIN2(cfra, pa->dietime); cfra1 = MIN2(cfra1, pa->dietime); @@ -4254,7 +4256,7 @@ static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModif } } - if((part->type==PART_HAIR || psys->flag&PSYS_KEYED) && ( psys_in_edit_mode(scene, psys) || (part->type==PART_HAIR + if((part->type==PART_HAIR || psys->flag&PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED) && ( psys_in_edit_mode(scene, psys) || (part->type==PART_HAIR || (part->ren_as == PART_DRAW_PATH && (part->draw_as == PART_DRAW_REND || psys->renderdata))))){ psys_cache_paths(scene, ob, psys, cfra, 0); @@ -4371,8 +4373,10 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps dietime = birthtime + (1 + pa->loop) * (pa->dietime - pa->time); /* update alive status and push events */ - if(pa->time > cfra) + if(pa->time > cfra) { pa->alive = PARS_UNBORN; + reset_particle(scene, pa, psys, psmd, ob, 0.0f, cfra, NULL, NULL, NULL); + } else if(dietime <= cfra){ if(dietime > psys->cfra){ state.time = dietime; @@ -4406,6 +4410,8 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps distribute_particles(scene, ob, psys, PART_FROM_CHILD); } + psys_update_path_cache(scene, ob,psmd,psys,cfra); + if(vg_size) MEM_freeN(vg_size); } @@ -4433,10 +4439,17 @@ void psys_changed_type(ParticleSystem *psys) if(ELEM3(part->draw_as, PART_DRAW_NOT, PART_DRAW_REND, PART_DRAW_PATH)==0) part->draw_as = PART_DRAW_REND; + + CLAMP(part->path_start, 0.0f, 100.0f); + CLAMP(part->path_end, 0.0f, 100.0f); } - else + else { free_hair(psys, 1); + CLAMP(part->path_start, part->sta, part->end + part->lifetime); + CLAMP(part->path_end, part->sta, part->end + part->lifetime); + } + psys->softflag= 0; psys_reset(psys, PSYS_RESET_ALL); @@ -4629,9 +4642,8 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle totpart = psys->part->totpart; totchild = get_psys_tot_child(scene, psys); - if(oldtotpart != totpart || (psys->part->childtype && oldtotchild != totchild)) { + if(oldtotpart != totpart || oldtotchild != totchild) { only_children_changed = (oldtotpart == totpart); - realloc_particles(ob, psys, totpart); alloc = 1; distr= 1; init= 1; @@ -4647,11 +4659,12 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle if(alloc) { realloc_particles(ob, psys, totpart); - if(usecache) + if(usecache && !only_children_changed) BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0); } - distribute_particles(scene, ob, psys, part->from); + if(!only_children_changed) + distribute_particles(scene, ob, psys, part->from); if((psys->part->type == PART_HAIR) && !(psys->flag & PSYS_HAIR_DONE)) /* don't generate children while growing hair - waste of time */ @@ -4660,7 +4673,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle distribute_particles(scene, ob, psys, PART_FROM_CHILD); } - if(only_children_changed==0) { + if(!only_children_changed) { free_keyed_keys(psys); initialize_all_particles(ob, psys, psmd); @@ -4680,19 +4693,10 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle int result = get_particles_from_cache(scene, ob, psys, (float)framenr, &old_framenr); if(result == PTCACHE_READ_EXACT || result == PTCACHE_READ_INTERPOLATED) { - //if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED) { - // psys_count_keyed_targets(ob,psys); - // set_keyed_keys(scene, ob, psys); - //} - cached_step(scene, ob, psmd, psys, cfra); psys->cfra=cfra; psys->recalc = 0; - //if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED) { - // psys_update_path_cache(scene, ob, psmd, psys, framenr); - //} - cache->simframe= framenr; cache->flag |= PTCACHE_SIMULATION_VALID; diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 64473d07151..2fe46be7a89 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -643,8 +643,8 @@ int BKE_ptcache_write_cache(PTCacheWriter *writer) return 0; for(i=0; i<writer->totelem; i++) { - writer->set_elem(i, writer->calldata, &temp); - BKE_ptcache_file_write_floats(pf, &temp, incr); + writer->set_elem(i, writer->calldata, temp); + BKE_ptcache_file_write_floats(pf, temp, incr); } } } @@ -677,8 +677,8 @@ int BKE_ptcache_write_cache(PTCacheWriter *writer) pmdata = pm->data; for(i=0; i<writer->totelem; i++, pmdata+=incr) { - writer->set_elem(i, writer->calldata, &temp); - memcpy(pmdata, &temp, elemsize); + writer->set_elem(i, writer->calldata, temp); + memcpy(pmdata, temp, elemsize); } pm->frame = writer->cfra; @@ -689,8 +689,8 @@ int BKE_ptcache_write_cache(PTCacheWriter *writer) pmdata = pm->data; for(i=0; i<writer->totelem; i++, pmdata+=incr) { - writer->set_elem(i, writer->calldata, &temp); - memcpy(pmdata, &temp, elemsize); + writer->set_elem(i, writer->calldata, temp); + memcpy(pmdata, temp, elemsize); } pm->frame = writer->cfra; @@ -1154,6 +1154,7 @@ void BKE_ptcache_quick_cache_all(Scene *scene) baker.progressbar=NULL; baker.progresscontext=NULL; baker.render=0; + baker.anim_init = 0; baker.scene=scene; if(count_quick_cache(scene, &baker.quick_step)) @@ -1171,7 +1172,7 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker) float frameleno = scene->r.framelen; int cfrao = CFRA; int startframe = MAXFRAME; - int endframe = CFRA; + int endframe = baker->anim_init ? scene->r.sfra : CFRA; int bake = baker->bake; int render = baker->render; int step = baker->quick_step; @@ -1209,8 +1210,13 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker) for(pid=pidlist.first; pid; pid=pid->next) { cache = pid->cache; if((cache->flag & PTCACHE_BAKED)==0) { - if(pid->type==PTCACHE_TYPE_PARTICLES) + if(pid->type==PTCACHE_TYPE_PARTICLES) { + /* skip hair particles */ + if(((ParticleSystem*)pid->data)->part->type == PART_HAIR) + continue; + psys_get_pointcache_start_end(scene, pid->data, &cache->startframe, &cache->endframe); + } if((cache->flag & PTCACHE_REDO_NEEDED || (cache->flag & PTCACHE_SIMULATION_VALID)==0) && ((cache->flag & PTCACHE_QUICK_CACHE)==0 || render || bake)) @@ -1265,6 +1271,10 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker) BKE_ptcache_ids_from_object(&pidlist, base->object); for(pid=pidlist.first; pid; pid=pid->next) { + /* skip hair particles */ + if(pid->type==PTCACHE_TYPE_PARTICLES && ((ParticleSystem*)pid->data)->part->type == PART_HAIR) + continue; + cache = pid->cache; if(step > 1) @@ -1282,7 +1292,9 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker) scene->r.framelen = frameleno; CFRA = cfrao; - scene_update_for_newframe(scene, scene->lay); + + if(bake) /* already on cfra unless baking */ + scene_update_for_newframe(scene, scene->lay); /* TODO: call redraw all windows somehow */ } diff --git a/source/blender/blenkernel/intern/sequence.c b/source/blender/blenkernel/intern/sequence.c index 7fc262b4796..c8d95929027 100644 --- a/source/blender/blenkernel/intern/sequence.c +++ b/source/blender/blenkernel/intern/sequence.c @@ -184,11 +184,11 @@ void seq_free_sequence(Editing *ed, Sequence *seq) if(seq->anim) IMB_free_anim(seq->anim); //XXX if(seq->hdaudio) sound_close_hdaudio(seq->hdaudio); - /* XXX if (seq->type & SEQ_EFFECT) { + if (seq->type & SEQ_EFFECT) { struct SeqEffectHandle sh = get_sequence_effect(seq); sh.free(seq); - }*/ + } if (ed->act_seq==seq) ed->act_seq= NULL; diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 15969fc9ab9..6e95fe7ebc7 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -60,6 +60,7 @@ #include "BLI_edgehash.h" #include "BIF_gl.h" +#include "BIF_glutil.h" #include "GPU_draw.h" #include "GPU_extensions.h" |