diff options
Diffstat (limited to 'source/blender/modifiers/intern/MOD_particlesystem.c')
-rw-r--r-- | source/blender/modifiers/intern/MOD_particlesystem.c | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c new file mode 100644 index 00000000000..02480b8d2a3 --- /dev/null +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -0,0 +1,232 @@ +/* +* $Id$ +* +* ***** BEGIN GPL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +* The Original Code is Copyright (C) 2005 by the Blender Foundation. +* All rights reserved. +* +* Contributor(s): Daniel Dunbar +* Ton Roosendaal, +* Ben Batt, +* Brecht Van Lommel, +* Campbell Barton +* +* ***** END GPL LICENSE BLOCK ***** +* +*/ + +#include "stddef.h" + +#include "DNA_material_types.h" + +#include "BKE_cdderivedmesh.h" +#include "BKE_material.h" +#include "BKE_modifier.h" +#include "BKE_particle.h" + +#include "MOD_util.h" + + +static void initData(ModifierData *md) +{ + ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md; + psmd->psys= 0; + psmd->dm=0; + psmd->totdmvert= psmd->totdmedge= psmd->totdmface= 0; +} +static void freeData(ModifierData *md) +{ + ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md; + + if(psmd->dm){ + psmd->dm->needsFree = 1; + psmd->dm->release(psmd->dm); + psmd->dm=0; + } + + /* ED_object_modifier_remove may have freed this first before calling + * modifier_free (which calls this function) */ + if(psmd->psys) + psmd->psys->flag |= PSYS_DELETE; +} +static void copyData(ModifierData *md, ModifierData *target) +{ + ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md; + ParticleSystemModifierData *tpsmd= (ParticleSystemModifierData*) target; + + tpsmd->dm = 0; + tpsmd->totdmvert = tpsmd->totdmedge = tpsmd->totdmface = 0; + //tpsmd->facepa = 0; + tpsmd->flag = psmd->flag; + /* need to keep this to recognise a bit later in copy_object */ + tpsmd->psys = psmd->psys; +} + +static CustomDataMask requiredDataMask(Object *ob, ModifierData *md) +{ + ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md; + CustomDataMask dataMask = 0; + Material *ma; + MTex *mtex; + int i; + + if(!psmd->psys->part) + return 0; + + 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]){ + dataMask |= (1 << CD_MDEFORMVERT); + break; + } + } + + /* particles only need this if they are after a non deform modifier, and + * the modifier stack will only create them in that case. */ + dataMask |= CD_MASK_ORIGSPACE; + + dataMask |= CD_MASK_ORCO; + + return dataMask; +} + +/* saves the current emitter state for a particle system and calculates particles */ +static void deformVerts( + ModifierData *md, Object *ob, DerivedMesh *derivedData, + float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc) +{ + DerivedMesh *dm = derivedData; + ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md; + ParticleSystem * psys=0; + int needsFree=0; + + if(ob->particlesystem.first) + psys=psmd->psys; + else + return; + + if(!psys_check_enabled(ob, psys)) + return; + + if(dm==0) { + dm= get_dm(md->scene, ob, NULL, NULL, vertexCos, 1); + + if(!dm) + return; + + needsFree= 1; + } + + /* clear old dm */ + if(psmd->dm){ + psmd->dm->needsFree = 1; + psmd->dm->release(psmd->dm); + } + + /* make new dm */ + psmd->dm=CDDM_copy(dm); + CDDM_apply_vert_coords(psmd->dm, vertexCos); + CDDM_calc_normals(psmd->dm); + + if(needsFree){ + dm->needsFree = 1; + dm->release(dm); + } + + /* protect dm */ + psmd->dm->needsFree = 0; + + /* report change in mesh structure */ + if(psmd->dm->getNumVerts(psmd->dm)!=psmd->totdmvert || + psmd->dm->getNumEdges(psmd->dm)!=psmd->totdmedge || + psmd->dm->getNumFaces(psmd->dm)!=psmd->totdmface){ + /* in file read dm hasn't really changed but just wasn't saved in file */ + + psys->recalc |= PSYS_RECALC_RESET; + psmd->flag |= eParticleSystemFlag_DM_changed; + + psmd->totdmvert= psmd->dm->getNumVerts(psmd->dm); + psmd->totdmedge= psmd->dm->getNumEdges(psmd->dm); + psmd->totdmface= psmd->dm->getNumFaces(psmd->dm); + } + + if(psys) { + psmd->flag &= ~eParticleSystemFlag_psys_updated; + particle_system_update(md->scene, ob, psys); + psmd->flag |= eParticleSystemFlag_psys_updated; + psmd->flag &= ~eParticleSystemFlag_DM_changed; + } +} + +/* disabled particles in editmode for now, until support for proper derivedmesh + * updates is coded */ +#if 0 +static void deformVertsEM( + ModifierData *md, Object *ob, EditMesh *editData, + DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) +{ + DerivedMesh *dm = derivedData; + + if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data); + + deformVerts(md, ob, dm, vertexCos, numVerts); + + if(!derivedData) dm->release(dm); +} +#endif + + +ModifierTypeInfo modifierType_ParticleSystem = { + /* name */ "ParticleSystem", + /* structName */ "ParticleSystemModifierData", + /* structSize */ sizeof(ParticleSystemModifierData), + /* type */ eModifierTypeType_OnlyDeform, + /* flags */ eModifierTypeFlag_AcceptsMesh + | eModifierTypeFlag_SupportsMapping + | eModifierTypeFlag_UsesPointCache /* + | eModifierTypeFlag_SupportsEditmode + | eModifierTypeFlag_EnableInEditmode */, + + /* copyData */ copyData, + /* deformVerts */ deformVerts, + /* deformVertsEM */ 0 /* deformVertsEM */ , + /* deformMatricesEM */ 0, + /* applyModifier */ 0, + /* applyModifierEM */ 0, + /* initData */ initData, + /* requiredDataMask */ requiredDataMask, + /* freeData */ freeData, + /* isDisabled */ 0, + /* updateDepgraph */ 0, + /* dependsOnTime */ 0, + /* foreachObjectLink */ 0, + /* foreachIDLink */ 0, +}; |