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