246 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			246 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
* $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 *****
 | 
						|
*
 | 
						|
*/
 | 
						|
 | 
						|
/** \file blender/modifiers/intern/MOD_particlesystem.c
 | 
						|
 *  \ingroup modifiers
 | 
						|
 */
 | 
						|
 | 
						|
 | 
						|
#include "stddef.h"
 | 
						|
 | 
						|
#include "DNA_material_types.h"
 | 
						|
 | 
						|
#include "BLI_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 *UNUSED(ob), ModifierData *md)
 | 
						|
{
 | 
						|
	ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
 | 
						|
	CustomDataMask dataMask = 0;
 | 
						|
	MTex *mtex;
 | 
						|
	int i;
 | 
						|
 | 
						|
	if(!psmd->psys->part)
 | 
						|
		return 0;
 | 
						|
 | 
						|
	for(i=0; i<MAX_MTEX; i++) {
 | 
						|
		mtex = psmd->psys->part->mtex[i];
 | 
						|
		if(mtex && mtex->mapto && (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 */ ,
 | 
						|
	/* deformMatrices */    0,
 | 
						|
	/* deformMatricesEM */  0,
 | 
						|
	/* applyModifier */     0,
 | 
						|
	/* applyModifierEM */   0,
 | 
						|
	/* initData */          initData,
 | 
						|
	/* requiredDataMask */  requiredDataMask,
 | 
						|
	/* freeData */          freeData,
 | 
						|
	/* isDisabled */        0,
 | 
						|
	/* updateDepgraph */    0,
 | 
						|
	/* dependsOnTime */     0,
 | 
						|
	/* dependsOnNormals */	0,
 | 
						|
	/* foreachObjectLink */ 0,
 | 
						|
	/* foreachIDLink */     0,
 | 
						|
};
 |