Blender V2.61 - r43446

MOD_particlesystem.c

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