This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/modifiers/intern/MOD_particlesystem.c

245 lines
6.4 KiB
C
Raw Normal View History

/*
2010-04-11 23:20:03 +00:00
* $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 "BLI_utildefines.h"
#include "BKE_utildefines.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 |= CD_MASK_MTFACE;
}
}
if(psmd->psys->part->tanfac!=0.0)
dataMask |= CD_MASK_MTFACE;
/* ask for vertexgroups if we need them */
for(i=0; i<PSYS_TOT_VG; i++){
if(psmd->psys->vgroup[i]){
dataMask |= CD_MASK_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|CD_MASK_ORIGINDEX;
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 UNUSED(numVerts),
int UNUSED(useRenderParams),
int UNUSED(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(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);
}
else if(psmd->flag & eParticleSystemFlag_file_loaded) {
/* in file read dm just wasn't saved in file so no need to reset everything */
psmd->flag &= ~eParticleSystemFlag_file_loaded;
}
else {
/* no dm before, so recalc particles fully */
psys->recalc |= PSYS_RECALC_RESET;
}
/* 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){
psys->recalc |= PSYS_RECALC_RESET;
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;
}
}
/* 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,
/* dependsOnNormals */ 0,
/* foreachObjectLink */ 0,
/* foreachIDLink */ 0,
};