|
Blender
V2.59
|
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 };