Blender  V2.59
MOD_particlesystem.c
Go to the documentation of this file.
00001 /*
00002 * $Id: MOD_particlesystem.c 35817 2011-03-27 13:49:53Z campbellbarton $
00003 *
00004 * ***** BEGIN GPL LICENSE BLOCK *****
00005 *
00006 * This program is free software; you can redistribute it and/or
00007 * modify it under the terms of the GNU General Public License
00008 * as published by the Free Software Foundation; either version 2
00009 * of the License, or (at your option) any later version.
00010 *
00011 * This program is distributed in the hope that it will be useful,
00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 * GNU General Public License for more details.
00015 *
00016 * You should have received a copy of the GNU General Public License
00017 * along with this program; if not, write to the Free Software  Foundation,
00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019 *
00020 * The Original Code is Copyright (C) 2005 by the Blender Foundation.
00021 * All rights reserved.
00022 *
00023 * Contributor(s): Daniel Dunbar
00024 *                 Ton Roosendaal,
00025 *                 Ben Batt,
00026 *                 Brecht Van Lommel,
00027 *                 Campbell Barton
00028 *
00029 * ***** END GPL LICENSE BLOCK *****
00030 *
00031 */
00032 
00038 #include <stddef.h>
00039 
00040 #include "DNA_material_types.h"
00041 
00042 #include "BLI_utildefines.h"
00043 
00044 
00045 #include "BKE_cdderivedmesh.h"
00046 #include "BKE_material.h"
00047 #include "BKE_modifier.h"
00048 #include "BKE_particle.h"
00049 
00050 #include "MOD_util.h"
00051 
00052 
00053 static void initData(ModifierData *md) 
00054 {
00055         ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
00056         psmd->psys= NULL;
00057         psmd->dm= NULL;
00058         psmd->totdmvert= psmd->totdmedge= psmd->totdmface= 0;
00059 }
00060 static void freeData(ModifierData *md)
00061 {
00062         ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
00063 
00064         if(psmd->dm){
00065                 psmd->dm->needsFree = 1;
00066                 psmd->dm->release(psmd->dm);
00067                 psmd->dm = NULL;
00068         }
00069 
00070         /* ED_object_modifier_remove may have freed this first before calling
00071          * modifier_free (which calls this function) */
00072         if(psmd->psys)
00073                 psmd->psys->flag |= PSYS_DELETE;
00074 }
00075 static void copyData(ModifierData *md, ModifierData *target)
00076 {
00077         ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
00078         ParticleSystemModifierData *tpsmd= (ParticleSystemModifierData*) target;
00079 
00080         tpsmd->dm = NULL;
00081         tpsmd->totdmvert = tpsmd->totdmedge = tpsmd->totdmface = 0;
00082         //tpsmd->facepa = 0;
00083         tpsmd->flag = psmd->flag;
00084         /* need to keep this to recognise a bit later in copy_object */
00085         tpsmd->psys = psmd->psys;
00086 }
00087 
00088 static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
00089 {
00090         ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
00091         CustomDataMask dataMask = 0;
00092         MTex *mtex;
00093         int i;
00094 
00095         if(!psmd->psys->part)
00096                 return 0;
00097 
00098         for(i=0; i<MAX_MTEX; i++) {
00099                 mtex = psmd->psys->part->mtex[i];
00100                 if(mtex && mtex->mapto && (mtex->texco & TEXCO_UV))
00101                         dataMask |= CD_MASK_MTFACE;
00102         }
00103 
00104         if(psmd->psys->part->tanfac != 0.0f)
00105                 dataMask |= CD_MASK_MTFACE;
00106 
00107         /* ask for vertexgroups if we need them */
00108         for(i=0; i<PSYS_TOT_VG; i++){
00109                 if(psmd->psys->vgroup[i]){
00110                         dataMask |= CD_MASK_MDEFORMVERT;
00111                         break;
00112                 }
00113         }
00114         
00115         /* particles only need this if they are after a non deform modifier, and
00116         * the modifier stack will only create them in that case. */
00117         dataMask |= CD_MASK_ORIGSPACE|CD_MASK_ORIGINDEX;
00118 
00119         dataMask |= CD_MASK_ORCO;
00120         
00121         return dataMask;
00122 }
00123 
00124 /* saves the current emitter state for a particle system and calculates particles */
00125 static void deformVerts(ModifierData *md, Object *ob,
00126                                                 DerivedMesh *derivedData,
00127                                                 float (*vertexCos)[3],
00128                                                 int UNUSED(numVerts),
00129                                                 int UNUSED(useRenderParams),
00130                                                 int UNUSED(isFinalCalc))
00131 {
00132         DerivedMesh *dm = derivedData;
00133         ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
00134         ParticleSystem * psys= NULL;
00135         int needsFree=0;
00136 
00137         if(ob->particlesystem.first)
00138                 psys=psmd->psys;
00139         else
00140                 return;
00141         
00142         if(!psys_check_enabled(ob, psys))
00143                 return;
00144 
00145         if(dm==NULL) {
00146                 dm= get_dm(ob, NULL, NULL, vertexCos, 1);
00147 
00148                 if(!dm)
00149                         return;
00150 
00151                 needsFree= 1;
00152         }
00153 
00154         /* clear old dm */
00155         if(psmd->dm){
00156                 psmd->dm->needsFree = 1;
00157                 psmd->dm->release(psmd->dm);
00158         }
00159         else if(psmd->flag & eParticleSystemFlag_file_loaded) {
00160                 /* in file read dm just wasn't saved in file so no need to reset everything */
00161                 psmd->flag &= ~eParticleSystemFlag_file_loaded;
00162         }
00163         else {
00164                 /* no dm before, so recalc particles fully */
00165                 psys->recalc |= PSYS_RECALC_RESET;
00166         }
00167 
00168         /* make new dm */
00169         psmd->dm=CDDM_copy(dm);
00170         CDDM_apply_vert_coords(psmd->dm, vertexCos);
00171         CDDM_calc_normals(psmd->dm);
00172 
00173         if(needsFree){
00174                 dm->needsFree = 1;
00175                 dm->release(dm);
00176         }
00177 
00178         /* protect dm */
00179         psmd->dm->needsFree = 0;
00180 
00181         /* report change in mesh structure */
00182         if(psmd->dm->getNumVerts(psmd->dm)!=psmd->totdmvert ||
00183                   psmd->dm->getNumEdges(psmd->dm)!=psmd->totdmedge ||
00184                   psmd->dm->getNumFaces(psmd->dm)!=psmd->totdmface){
00185 
00186                 psys->recalc |= PSYS_RECALC_RESET;
00187 
00188                 psmd->totdmvert= psmd->dm->getNumVerts(psmd->dm);
00189                 psmd->totdmedge= psmd->dm->getNumEdges(psmd->dm);
00190                 psmd->totdmface= psmd->dm->getNumFaces(psmd->dm);
00191         }
00192 
00193         if(psys) {
00194                 psmd->flag &= ~eParticleSystemFlag_psys_updated;
00195                 particle_system_update(md->scene, ob, psys);
00196                 psmd->flag |= eParticleSystemFlag_psys_updated;
00197         }
00198 }
00199 
00200 /* disabled particles in editmode for now, until support for proper derivedmesh
00201  * updates is coded */
00202 #if 0
00203 static void deformVertsEM(
00204                                 ModifierData *md, Object *ob, EditMesh *editData,
00205                                 DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
00206 {
00207         DerivedMesh *dm = derivedData;
00208 
00209         if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data);
00210 
00211         deformVerts(md, ob, dm, vertexCos, numVerts);
00212 
00213         if(!derivedData) dm->release(dm);
00214 }
00215 #endif
00216 
00217 
00218 ModifierTypeInfo modifierType_ParticleSystem = {
00219         /* name */              "ParticleSystem",
00220         /* structName */        "ParticleSystemModifierData",
00221         /* structSize */        sizeof(ParticleSystemModifierData),
00222         /* type */              eModifierTypeType_OnlyDeform,
00223         /* flags */             eModifierTypeFlag_AcceptsMesh
00224                                                         | eModifierTypeFlag_SupportsMapping
00225                                                         | eModifierTypeFlag_UsesPointCache /*
00226                                                         | eModifierTypeFlag_SupportsEditmode
00227                                                         | eModifierTypeFlag_EnableInEditmode */,
00228 
00229         /* copyData */          copyData,
00230         /* deformVerts */       deformVerts,
00231         /* deformVertsEM */     NULL /* deformVertsEM */ ,
00232         /* deformMatrices */    NULL,
00233         /* deformMatricesEM */  NULL,
00234         /* applyModifier */     NULL,
00235         /* applyModifierEM */   NULL,
00236         /* initData */          initData,
00237         /* requiredDataMask */  requiredDataMask,
00238         /* freeData */          freeData,
00239         /* isDisabled */        NULL,
00240         /* updateDepgraph */    NULL,
00241         /* dependsOnTime */     NULL,
00242         /* dependsOnNormals */  NULL,
00243         /* foreachObjectLink */ NULL,
00244         /* foreachIDLink */     NULL,
00245 };