diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-06-15 15:48:42 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-06-15 15:48:42 +0400 |
commit | b8d0f62fd2a9088034fa7da1d7e5e82ca845b728 (patch) | |
tree | aaca69c449efd862de8e2c581db92514d5102ffa | |
parent | afaa3768e655bb7cfc7f89fd5fdd08a69ac4f132 (diff) |
Fix for bug #18924: OpenGL performance issue with particle modifiers,
actually two modifier datamask optimizations that were never done.
* Don't use modifier data mask for disabled modifiers.
* Check if UV data is needed for particle system instead of always
requesting it.
-rw-r--r-- | source/blender/blenkernel/BKE_modifier.h | 9 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 26 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 80 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle.c | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle_system.c | 5 |
5 files changed, 78 insertions, 46 deletions
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index a41716ed1ff..e6d83793f94 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -202,7 +202,7 @@ typedef struct ModifierTypeInfo { * * This function is optional. */ - CustomDataMask (*requiredDataMask)(struct ModifierData *md); + CustomDataMask (*requiredDataMask)(struct Object *ob, struct ModifierData *md); /* Free internal modifier data variables, this function should * not free the md variable itself. @@ -270,6 +270,7 @@ int modifier_dependsOnTime(struct ModifierData *md); int modifier_supportsMapping(struct ModifierData *md); int modifier_couldBeCage(struct ModifierData *md); int modifier_isDeformer(struct ModifierData *md); +int modifier_isEnabled(struct ModifierData *md, int required_mode); void modifier_setError(struct ModifierData *md, char *format, ...); void modifiers_foreachObjectLink(struct Object *ob, @@ -300,8 +301,10 @@ int modifiers_indexInObject(struct Object *ob, struct ModifierData *md * evaluation, assuming the data indicated by dataMask is required at the * end of the stack. */ -struct LinkNode *modifiers_calcDataMasks(struct ModifierData *md, - CustomDataMask dataMask); +struct LinkNode *modifiers_calcDataMasks(struct Object *ob, + struct ModifierData *md, + CustomDataMask dataMask, + int required_mode); struct ModifierData *modifiers_getVirtualModifierList(struct Object *ob); #endif diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index ddb7d853f2f..1d0d91c4208 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -2134,18 +2134,18 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], modifiers_clearErrors(ob); + if(useRenderParams) required_mode = eModifierMode_Render; + else required_mode = eModifierMode_Realtime; + /* we always want to keep original indices */ dataMask |= CD_MASK_ORIGINDEX; - datamasks = modifiers_calcDataMasks(md, dataMask); + datamasks = modifiers_calcDataMasks(ob, md, dataMask, required_mode); curr = datamasks; if(deform_r) *deform_r = NULL; *final_r = NULL; - if(useRenderParams) required_mode = eModifierMode_Render; - else required_mode = eModifierMode_Realtime; - if(useDeform) { if(useDeform > 0 && do_ob_key(ob)) /* shape key makes deform verts */ deformedVerts = mesh_getVertexCos(me, &numVerts); @@ -2156,8 +2156,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], for(;md; md = md->next, curr = curr->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); - if((md->mode & required_mode) != required_mode) continue; - if(mti->isDisabled && mti->isDisabled(md)) continue; + if(!modifier_isEnabled(md, required_mode)) continue; if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue; if(mti->type == eModifierTypeType_OnlyDeform) { @@ -2221,19 +2220,18 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], for(;md; md = md->next, curr = curr->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); - if((md->mode & required_mode) != required_mode) continue; + if(!modifier_isEnabled(md, required_mode)) continue; if(mti->type == eModifierTypeType_OnlyDeform && !useDeform) continue; if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) { modifier_setError(md, "Modifier requires original data, bad stack position."); continue; } - if(mti->isDisabled && mti->isDisabled(md)) continue; if(needMapping && !modifier_supportsMapping(md)) continue; if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue; /* add an orco layer if needed by this modifier */ if(dm && mti->requiredDataMask) { - mask = mti->requiredDataMask(md); + mask = mti->requiredDataMask(ob, md); if(mask & CD_MASK_ORCO) add_orco_dm(ob, NULL, dm, orcodm); } @@ -2405,14 +2403,11 @@ static int editmesh_modifier_is_enabled(ModifierData *md, DerivedMesh *dm) ModifierTypeInfo *mti = modifierType_getInfo(md->type); int required_mode = eModifierMode_Realtime | eModifierMode_Editmode; - if((md->mode & required_mode) != required_mode) return 0; + if(!modifier_isEnabled(md, required_mode)) return 0; if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) { modifier_setError(md, "Modifier requires original data, bad stack position."); return 0; } - if(mti->isDisabled && mti->isDisabled(md)) return 0; - if(!(mti->flags & eModifierTypeFlag_SupportsEditmode)) return 0; - if(md->mode & eModifierMode_DisableTemporary) return 0; return 1; } @@ -2429,6 +2424,7 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh *dm, *orcodm = NULL; int i, numVerts = 0, cageIndex = modifiers_getCageIndex(ob, NULL); LinkNode *datamasks, *curr; + int required_mode = eModifierMode_Realtime | eModifierMode_Editmode; modifiers_clearErrors(ob); @@ -2442,7 +2438,7 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, /* we always want to keep original indices */ dataMask |= CD_MASK_ORIGINDEX; - datamasks = modifiers_calcDataMasks(md, dataMask); + datamasks = modifiers_calcDataMasks(ob, md, dataMask, required_mode); curr = datamasks; for(i = 0; md; i++, md = md->next, curr = curr->next) { @@ -2453,7 +2449,7 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, /* add an orco layer if needed by this modifier */ if(dm && mti->requiredDataMask) { - mask = mti->requiredDataMask(md); + mask = mti->requiredDataMask(ob, md); if(mask & CD_MASK_ORCO) add_orco_dm(ob, em, dm, orcodm); } diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 29930b3eb58..fa2f857cc8b 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -206,7 +206,7 @@ static void curveModifier_copyData(ModifierData *md, ModifierData *target) strncpy(tcmd->name, cmd->name, 32); } -CustomDataMask curveModifier_requiredDataMask(ModifierData *md) +CustomDataMask curveModifier_requiredDataMask(Object *ob, ModifierData *md) { CurveModifierData *cmd = (CurveModifierData *)md; CustomDataMask dataMask = 0; @@ -282,7 +282,7 @@ static void latticeModifier_copyData(ModifierData *md, ModifierData *target) strncpy(tlmd->name, lmd->name, 32); } -CustomDataMask latticeModifier_requiredDataMask(ModifierData *md) +CustomDataMask latticeModifier_requiredDataMask(Object *ob, ModifierData *md) { LatticeModifierData *lmd = (LatticeModifierData *)md; CustomDataMask dataMask = 0; @@ -665,7 +665,7 @@ static void maskModifier_copyData(ModifierData *md, ModifierData *target) strcpy(tmmd->vgroup, mmd->vgroup); } -static CustomDataMask maskModifier_requiredDataMask(ModifierData *md) +static CustomDataMask maskModifier_requiredDataMask(Object *ob, ModifierData *md) { return (1 << CD_MDEFORMVERT); } @@ -3393,7 +3393,7 @@ static void bevelModifier_copyData(ModifierData *md, ModifierData *target) strncpy(tbmd->defgrp_name, bmd->defgrp_name, 32); } -CustomDataMask bevelModifier_requiredDataMask(ModifierData *md) +CustomDataMask bevelModifier_requiredDataMask(Object *ob, ModifierData *md) { BevelModifierData *bmd = (BevelModifierData *)md; CustomDataMask dataMask = 0; @@ -3473,7 +3473,7 @@ static void displaceModifier_copyData(ModifierData *md, ModifierData *target) strncpy(tdmd->uvlayer_name, dmd->uvlayer_name, 32); } -CustomDataMask displaceModifier_requiredDataMask(ModifierData *md) +CustomDataMask displaceModifier_requiredDataMask(Object *ob, ModifierData *md) { DisplaceModifierData *dmd = (DisplaceModifierData *)md; CustomDataMask dataMask = 0; @@ -3816,7 +3816,7 @@ static void uvprojectModifier_copyData(ModifierData *md, ModifierData *target) tumd->aspecty = umd->aspecty; } -CustomDataMask uvprojectModifier_requiredDataMask(ModifierData *md) +CustomDataMask uvprojectModifier_requiredDataMask(Object *ob, ModifierData *md) { CustomDataMask dataMask = 0; @@ -4276,7 +4276,7 @@ int smoothModifier_isDisabled(ModifierData *md) return 0; } -CustomDataMask smoothModifier_requiredDataMask(ModifierData *md) +CustomDataMask smoothModifier_requiredDataMask(Object *ob, ModifierData *md) { SmoothModifierData *smd = (SmoothModifierData *)md; CustomDataMask dataMask = 0; @@ -4505,7 +4505,7 @@ int castModifier_isDisabled(ModifierData *md) return 0; } -CustomDataMask castModifier_requiredDataMask(ModifierData *md) +CustomDataMask castModifier_requiredDataMask(Object *ob, ModifierData *md) { CastModifierData *cmd = (CastModifierData *)md; CustomDataMask dataMask = 0; @@ -5136,7 +5136,7 @@ static void waveModifier_updateDepgraph( } } -CustomDataMask waveModifier_requiredDataMask(ModifierData *md) +CustomDataMask waveModifier_requiredDataMask(Object *ob, ModifierData *md) { WaveModifierData *wmd = (WaveModifierData *)md; CustomDataMask dataMask = 0; @@ -5473,7 +5473,7 @@ static void armatureModifier_copyData(ModifierData *md, ModifierData *target) strncpy(tamd->defgrp_name, amd->defgrp_name, 32); } -CustomDataMask armatureModifier_requiredDataMask(ModifierData *md) +CustomDataMask armatureModifier_requiredDataMask(Object *ob, ModifierData *md) { CustomDataMask dataMask = 0; @@ -5587,7 +5587,7 @@ static void hookModifier_copyData(ModifierData *md, ModifierData *target) strncpy(thmd->name, hmd->name, 32); } -CustomDataMask hookModifier_requiredDataMask(ModifierData *md) +CustomDataMask hookModifier_requiredDataMask(Object *ob, ModifierData *md) { HookModifierData *hmd = (HookModifierData *)md; CustomDataMask dataMask = 0; @@ -5846,7 +5846,7 @@ static void clothModifier_updateDepgraph( } } -CustomDataMask clothModifier_requiredDataMask(ModifierData *md) +CustomDataMask clothModifier_requiredDataMask(Object *ob, ModifierData *md) { CustomDataMask dataMask = 0; @@ -6230,7 +6230,7 @@ static DerivedMesh *booleanModifier_applyModifier( return derivedData; } -CustomDataMask booleanModifier_requiredDataMask(ModifierData *md) +CustomDataMask booleanModifier_requiredDataMask(Object *ob, ModifierData *md) { CustomDataMask dataMask = (1 << CD_MTFACE) + (1 << CD_MEDGE); @@ -6278,12 +6278,27 @@ static void particleSystemModifier_copyData(ModifierData *md, ModifierData *targ tpsmd->psys = psmd->psys; } -CustomDataMask particleSystemModifier_requiredDataMask(ModifierData *md) +CustomDataMask particleSystemModifier_requiredDataMask(Object *ob, ModifierData *md) { ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md; - CustomDataMask dataMask = (1 << CD_MTFACE) + (1 << CD_MEDGE); + CustomDataMask dataMask = 0; + Material *ma; + MTex *mtex; int i; + ma= give_current_material(ob, psmd->psys->part->omat); + if(ma) { + for(i=0; i<MAX_MTEX; i++) { + mtex=ma->mtex[i]; + if(mtex && (ma->septex & (1<<i))==0) + if(mtex->pmapto && (mtex->texco & TEXCO_UV)) + dataMask |= (1 << CD_MTFACE); + } + } + + if(psmd->psys->part->tanfac!=0.0) + dataMask |= (1 << CD_MTFACE); + /* ask for vertexgroups if we need them */ for(i=0; i<PSYS_TOT_VG; i++){ if(psmd->psys->vgroup[i]){ @@ -6638,7 +6653,7 @@ static int explodeModifier_dependsOnTime(ModifierData *md) { return 1; } -CustomDataMask explodeModifier_requiredDataMask(ModifierData *md) +CustomDataMask explodeModifier_requiredDataMask(Object *ob, ModifierData *md) { ExplodeModifierData *emd= (ExplodeModifierData*) md; CustomDataMask dataMask = 0; @@ -7552,7 +7567,7 @@ static void meshdeformModifier_copyData(ModifierData *md, ModifierData *target) tmmd->object = mmd->object; } -CustomDataMask meshdeformModifier_requiredDataMask(ModifierData *md) +CustomDataMask meshdeformModifier_requiredDataMask(Object *ob, ModifierData *md) { MeshDeformModifierData *mmd = (MeshDeformModifierData *)md; CustomDataMask dataMask = 0; @@ -7876,7 +7891,7 @@ static void shrinkwrapModifier_copyData(ModifierData *md, ModifierData *target) tsmd->subsurfLevels = smd->subsurfLevels; } -CustomDataMask shrinkwrapModifier_requiredDataMask(ModifierData *md) +CustomDataMask shrinkwrapModifier_requiredDataMask(Object *ob, ModifierData *md) { ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md; CustomDataMask dataMask = 0; @@ -7910,7 +7925,7 @@ static void shrinkwrapModifier_foreachObjectLink(ModifierData *md, Object *ob, O static void shrinkwrapModifier_deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm = NULL; - CustomDataMask dataMask = shrinkwrapModifier_requiredDataMask(md); + CustomDataMask dataMask = shrinkwrapModifier_requiredDataMask(ob, md); /* We implement requiredDataMask but thats not really usefull since mesh_calc_modifiers pass a NULL derivedData or without the modified vertexs applied */ if(dataMask) @@ -7936,7 +7951,7 @@ static void shrinkwrapModifier_deformVerts(ModifierData *md, Object *ob, Derived static void shrinkwrapModifier_deformVertsEM(ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm = NULL; - CustomDataMask dataMask = shrinkwrapModifier_requiredDataMask(md); + CustomDataMask dataMask = shrinkwrapModifier_requiredDataMask(ob, md); if(dataMask) { @@ -7995,7 +8010,7 @@ static void simpledeformModifier_copyData(ModifierData *md, ModifierData *target memcpy(tsmd->limit, smd->limit, sizeof(tsmd->limit)); } -static CustomDataMask simpledeformModifier_requiredDataMask(ModifierData *md) +static CustomDataMask simpledeformModifier_requiredDataMask(Object *ob, ModifierData *md) { SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md; CustomDataMask dataMask = 0; @@ -8024,7 +8039,7 @@ static void simpledeformModifier_updateDepgraph(ModifierData *md, DagForest *for static void simpledeformModifier_deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm = NULL; - CustomDataMask dataMask = simpledeformModifier_requiredDataMask(md); + CustomDataMask dataMask = simpledeformModifier_requiredDataMask(ob, md); /* We implement requiredDataMask but thats not really usefull since mesh_calc_modifiers pass a NULL derivedData or without the modified vertexs applied */ if(dataMask) @@ -8051,7 +8066,7 @@ static void simpledeformModifier_deformVerts(ModifierData *md, Object *ob, Deriv static void simpledeformModifier_deformVertsEM(ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm = NULL; - CustomDataMask dataMask = simpledeformModifier_requiredDataMask(md); + CustomDataMask dataMask = simpledeformModifier_requiredDataMask(ob, md); /* We implement requiredDataMask but thats not really usefull since mesh_calc_modifiers pass a NULL derivedData or without the modified vertexs applied */ if(dataMask) @@ -8658,7 +8673,20 @@ int modifiers_isParticleEnabled(Object *ob) return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render)); } -LinkNode *modifiers_calcDataMasks(ModifierData *md, CustomDataMask dataMask) +int modifier_isEnabled(ModifierData *md, int required_mode) +{ + ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + if((md->mode & required_mode) != required_mode) return 0; + if(mti->isDisabled && mti->isDisabled(md)) return 0; + if(md->mode & eModifierMode_DisableTemporary) return 0; + if(required_mode & eModifierMode_Editmode) + if(!(mti->flags & eModifierTypeFlag_SupportsEditmode)) return 0; + + return 1; +} + +LinkNode *modifiers_calcDataMasks(Object *ob, ModifierData *md, CustomDataMask dataMask, int required_mode) { LinkNode *dataMasks = NULL; LinkNode *curr, *prev; @@ -8668,7 +8696,9 @@ LinkNode *modifiers_calcDataMasks(ModifierData *md, CustomDataMask dataMask) ModifierTypeInfo *mti = modifierType_getInfo(md->type); CustomDataMask mask = 0; - if(mti->requiredDataMask) mask = mti->requiredDataMask(md); + if(modifier_isEnabled(md, required_mode)) + if(mti->requiredDataMask) + mask = mti->requiredDataMask(ob, md); BLI_linklist_prepend(&dataMasks, (void *)mask); } diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 41ce23347a3..b5b2c07af9c 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -3182,7 +3182,7 @@ static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float if(ma) for(m=0; m<MAX_MTEX; m++){ mtex=ma->mtex[m]; - if(mtex && (ma->septex & (1<<m))==0){ + if(mtex && (ma->septex & (1<<m))==0 && mtex->pmapto){ float def=mtex->def_var; float var=mtex->varfac; short blend=mtex->blendtype; @@ -3231,7 +3231,7 @@ void psys_get_texture(Object *ob, Material *ma, ParticleSystemModifierData *psmd if(ma) for(m=0; m<MAX_MTEX; m++){ mtex=ma->mtex[m]; - if(mtex && (ma->septex & (1<<m))==0){ + if(mtex && (ma->septex & (1<<m))==0 && mtex->pmapto){ float var=mtex->varfac; float def=mtex->def_var; short blend=mtex->blendtype; diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 31e246f66b9..6ac57934670 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -1762,7 +1762,10 @@ void reset_particle(ParticleData *pa, ParticleSystem *psys, ParticleSystemModifi where_is_object_time(ob,pa->time); /* get birth location from object */ - psys_particle_on_emitter(psmd,part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0); + if(part->tanfac!=0.0) + psys_particle_on_emitter(psmd,part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0); + else + psys_particle_on_emitter(psmd,part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,0,0,0,0); /* save local coordinates for later */ VECCOPY(tloc,loc); |