Ejemplo n.º 1
0
static int rna_SmokeModifier_grid_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION])
{
#ifdef WITH_SMOKE
	SmokeDomainSettings *sds = (SmokeDomainSettings *)ptr->data;
	float *density = NULL;
	int size = 0;

	if (sds->flags & MOD_SMOKE_HIGHRES && sds->wt) {
		/* high resolution smoke */
		int res[3];

		smoke_turbulence_get_res(sds->wt, res);
		size = res[0] * res[1] * res[2];

		density = smoke_turbulence_get_density(sds->wt);
	}
	else if (sds->fluid) {
		/* regular resolution */
		size = sds->res[0] * sds->res[1] * sds->res[2];
		density = smoke_get_density(sds->fluid);
	}

	length[0] = (density) ? size : 0;
#else
	(void)ptr;
	length[0] = 0;
#endif
	return length[0];
}
Ejemplo n.º 2
0
static void rna_SmokeModifier_density_get(PointerRNA *ptr, float *values)
{
	SmokeDomainSettings *settings = (SmokeDomainSettings *)ptr->data;
	float *density = smoke_get_density(settings->fluid);
	unsigned int size = settings->res[0] * settings->res[1] * settings->res[2];

	memcpy(values, density, size * sizeof(float));
}
Ejemplo n.º 3
0
static int rna_SmokeModifier_density_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION])
{
	SmokeDomainSettings *settings = (SmokeDomainSettings *)ptr->data;

	if (settings->fluid) {
		float *density = smoke_get_density(settings->fluid);
		unsigned int size = settings->res[0] * settings->res[1] * settings->res[2];

		if (density)
			length[0] = size;
		else
			length[0] = 0;
	}
	else {
		length[0] = 0; /* No smoke domain created yet */
	}

	return length[0];
}
Ejemplo n.º 4
0
static void rna_SmokeModifier_density_grid_get(PointerRNA *ptr, float *values)
{
#ifdef WITH_SMOKE
	SmokeDomainSettings *sds = (SmokeDomainSettings *)ptr->data;
	int length[RNA_MAX_ARRAY_DIMENSION];
	int size = rna_SmokeModifier_grid_get_length(ptr, length);
	float *density;

	BLI_rw_mutex_lock(sds->fluid_mutex, THREAD_LOCK_READ);
	
	if (sds->flags & MOD_SMOKE_HIGHRES && sds->wt)
		density = smoke_turbulence_get_density(sds->wt);
	else
		density = smoke_get_density(sds->fluid);

	memcpy(values, density, size * sizeof(float));

	BLI_rw_mutex_unlock(sds->fluid_mutex);
#else
	UNUSED_VARS(ptr, values);
#endif
}
Ejemplo n.º 5
0
static void init_frame_smoke(VoxelData *vd, float cfra)
{
#ifdef WITH_SMOKE
	Object *ob;
	ModifierData *md;
	
	vd->dataset = NULL;
	if (vd->object == NULL)	return;	
	ob= vd->object;
	
	/* draw code for smoke */
	if( (md = (ModifierData *)modifiers_findByType(ob, eModifierType_Smoke)) )
	{
		SmokeModifierData *smd = (SmokeModifierData *)md;

		
		if(smd->domain && smd->domain->fluid) {
			if(cfra < smd->domain->point_cache[0]->startframe)
				; /* don't show smoke before simulation starts, this could be made an option in the future */
			else if (vd->smoked_type == TEX_VD_SMOKEHEAT) {
				size_t totRes;
				size_t i;
				float *heat;

				VECCOPY(vd->resol, smd->domain->res);
				totRes= vd_resol_size(vd);

				// scaling heat values from -2.0-2.0 to 0.0-1.0
				vd->dataset = MEM_mapallocN(sizeof(float)*(totRes), "smoke data");


				heat = smoke_get_heat(smd->domain->fluid);

				for (i=0; i<totRes; i++)
				{
					vd->dataset[i] = (heat[i]+2.0f)/4.0f;
				}

				//vd->dataset = smoke_get_heat(smd->domain->fluid);
			}
			else if (vd->smoked_type == TEX_VD_SMOKEVEL) {
				size_t totRes;
				size_t i;
				float *xvel, *yvel, *zvel;

				VECCOPY(vd->resol, smd->domain->res);
				totRes= vd_resol_size(vd);

				// scaling heat values from -2.0-2.0 to 0.0-1.0
				vd->dataset = MEM_mapallocN(sizeof(float)*(totRes), "smoke data");

				xvel = smoke_get_velocity_x(smd->domain->fluid);
				yvel = smoke_get_velocity_y(smd->domain->fluid);
				zvel = smoke_get_velocity_z(smd->domain->fluid);

				for (i=0; i<totRes; i++)
				{
					vd->dataset[i] = sqrt(xvel[i]*xvel[i] + yvel[i]*yvel[i] + zvel[i]*zvel[i])*3.0f;
				}

			}
			else {
				size_t totRes;
				float *density;

				if (smd->domain->flags & MOD_SMOKE_HIGHRES) {
					smoke_turbulence_get_res(smd->domain->wt, vd->resol);
					density = smoke_turbulence_get_density(smd->domain->wt);
				} else {
					VECCOPY(vd->resol, smd->domain->res);
					density = smoke_get_density(smd->domain->fluid);
				}

				/* TODO: is_vd_res_ok(rvd) doesnt check this resolution */
				totRes= vd_resol_size(vd);
				/* always store copy, as smoke internal data can change */
				vd->dataset = MEM_mapallocN(sizeof(float)*(totRes), "smoke data");
				memcpy(vd->dataset, density, sizeof(float)*totRes);
			} // end of fluid condition
		}
	}
	
	vd->ok = 1;

#else // WITH_SMOKE
	(void)vd;
	(void)cfra;

	vd->dataset= NULL;
#endif
}
Ejemplo n.º 6
0
Archivo: smoke.c Proyecto: jinjoh/NOOR
static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd)
{
	SmokeDomainSettings *sds = smd->domain;
	GroupObject *go = NULL;			
	Base *base = NULL;	

	// do flows and fluids
	if(1)			
	{				
		Object *otherobj = NULL;				
		ModifierData *md = NULL;
		if(sds->fluid_group) // we use groups since we have 2 domains
			go = sds->fluid_group->gobject.first;				
		else					
			base = scene->base.first;
		while(base || go)
		{					
			otherobj = NULL;
			if(sds->fluid_group) 
			{
				if(go->ob)							
					otherobj = go->ob;					
			}					
			else						
				otherobj = base->object;
			if(!otherobj)
			{
				if(sds->fluid_group)
					go = go->next;
				else
					base= base->next;

				continue;
			}

			md = modifiers_findByType(otherobj, eModifierType_Smoke);
			
			// check for active smoke modifier
			if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render))
			{
				SmokeModifierData *smd2 = (SmokeModifierData *)md;
				
				// check for initialized smoke object
				if((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow)						
				{
					// we got nice flow object
					SmokeFlowSettings *sfs = smd2->flow;
					
					if(sfs->psys && sfs->psys->part && sfs->psys->part->type==PART_EMITTER) // is particle system selected
					{
						ParticleSystem *psys = sfs->psys;
						ParticleSettings *part=psys->part;
						ParticleData *pa = NULL;								
						int p = 0;								
						float *density = smoke_get_density(sds->fluid);								
						float *bigdensity = smoke_turbulence_get_density(sds->wt);								
						float *heat = smoke_get_heat(sds->fluid);								
						float *velocity_x = smoke_get_velocity_x(sds->fluid);								
						float *velocity_y = smoke_get_velocity_y(sds->fluid);								
						float *velocity_z = smoke_get_velocity_z(sds->fluid);								
						unsigned char *obstacle = smoke_get_obstacle(sds->fluid);								
						int bigres[3];	
														
						// mostly copied from particle code								
						for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++)								
						{									
							int cell[3];									
							size_t i = 0;									
							size_t index = 0;									
							int badcell = 0;																		
							if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue;									
							else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0) continue;									
							else if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue;																		
							// VECCOPY(pos, pa->state.co);									
							// Mat4MulVecfl (ob->imat, pos);																		
							// 1. get corresponding cell	
							get_cell(smd->domain->p0, smd->domain->res, smd->domain->dx, pa->state.co, cell, 0);																	
							// check if cell is valid (in the domain boundary)									
							for(i = 0; i < 3; i++)									
							{										
								if((cell[i] > sds->res[i] - 1) || (cell[i] < 0))										
								{											
									badcell = 1;											
									break;										
								}									
							}																			
							if(badcell)										
								continue;																		
							// 2. set cell values (heat, density and velocity)									
							index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);																		
							if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) && !(obstacle[index] & 2)) // this is inflow									
							{										
								// heat[index] += sfs->temp * 0.1;										
								// density[index] += sfs->density * 0.1;
								heat[index] = sfs->temp;
								density[index] = sfs->density;

								/*
								velocity_x[index] = pa->state.vel[0];
								velocity_y[index] = pa->state.vel[1];
								velocity_z[index] = pa->state.vel[2];										
								*/										
								
								// obstacle[index] |= 2;
								// we need different handling for the high-res feature
								if(bigdensity)
								{
									// init all surrounding cells according to amplification, too
									int i, j, k;

									smoke_turbulence_get_res(smd->domain->wt, bigres);

									for(i = 0; i < smd->domain->amplify + 1; i++)
										for(j = 0; j < smd->domain->amplify + 1; j++)
											for(k = 0; k < smd->domain->amplify + 1; k++)													
											{														
												index = smoke_get_index((smd->domain->amplify + 1)* cell[0] + i, bigres[0], (smd->domain->amplify + 1)* cell[1] + j, bigres[1], (smd->domain->amplify + 1)* cell[2] + k);														
												bigdensity[index] = sfs->density;													
											}										
								}									
							}									
							else if(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) // outflow									
							{										
								heat[index] = 0.f;										
								density[index] = 0.f;										
								velocity_x[index] = 0.f;										
								velocity_y[index] = 0.f;										
								velocity_z[index] = 0.f;
								// we need different handling for the high-res feature
								if(bigdensity)
								{
									// init all surrounding cells according to amplification, too											
									int i, j, k;
									smoke_turbulence_get_res(smd->domain->wt, bigres);

									for(i = 0; i < smd->domain->amplify + 1; i++)
										for(j = 0; j < smd->domain->amplify + 1; j++)
											for(k = 0; k < smd->domain->amplify + 1; k++)
											{														
												index = smoke_get_index((smd->domain->amplify + 1)* cell[0] + i, bigres[0], (smd->domain->amplify + 1)* cell[1] + j, bigres[1], (smd->domain->amplify + 1)* cell[2] + k);														
												bigdensity[index] = 0.f;													
											}										
								}									
							}	// particles loop							
					}							
				}							
				else							
				{								
					/*								
					for()								
					{									
						// no psys									
						BVHTreeNearest nearest;
						nearest.index = -1;
						nearest.dist = FLT_MAX;

						BLI_bvhtree_find_nearest(sfs->bvh->tree, pco, &nearest, sfs->bvh->nearest_callback, sfs->bvh);
					}*/							
				}						
			}						
		}
			if(sds->fluid_group)
				go = go->next;
			else
				base= base->next;
		}
	}

	// do effectors
	{
		ListBase *effectors = pdInitEffectors(scene, ob, NULL, sds->effector_weights);

		if(effectors)
		{
			float *density = smoke_get_density(sds->fluid);
			float *force_x = smoke_get_force_x(sds->fluid);
			float *force_y = smoke_get_force_y(sds->fluid);
			float *force_z = smoke_get_force_z(sds->fluid);
			float *velocity_x = smoke_get_velocity_x(sds->fluid);
			float *velocity_y = smoke_get_velocity_y(sds->fluid);
			float *velocity_z = smoke_get_velocity_z(sds->fluid);
			int x, y, z;

			// precalculate wind forces
			for(x = 0; x < sds->res[0]; x++)
				for(y = 0; y < sds->res[1]; y++)
					for(z = 0; z < sds->res[2]; z++)
			{	
				EffectedPoint epoint;
				float voxelCenter[3] = {0,0,0} , vel[3] = {0,0,0} , retvel[3] = {0,0,0};
				unsigned int index = smoke_get_index(x, sds->res[0], y, sds->res[1], z);

				if(density[index] < FLT_EPSILON)					
					continue;	

				vel[0] = velocity_x[index];
				vel[1] = velocity_y[index];
				vel[2] = velocity_z[index];

				voxelCenter[0] = sds->p0[0] + sds->dx *  x + sds->dx * 0.5;
				voxelCenter[1] = sds->p0[1] + sds->dx *  y + sds->dx * 0.5;
				voxelCenter[2] = sds->p0[2] + sds->dx *  z + sds->dx * 0.5;

				pd_point_from_loc(scene, voxelCenter, vel, index, &epoint);
				pdDoEffectors(effectors, NULL, sds->effector_weights, &epoint, retvel, NULL);

				// TODO dg - do in force!
				force_x[index] = MIN2(MAX2(-1.0, retvel[0] * 0.2), 1.0); 
				force_y[index] = MIN2(MAX2(-1.0, retvel[1] * 0.2), 1.0); 
				force_z[index] = MIN2(MAX2(-1.0, retvel[2] * 0.2), 1.0);
			}
		}

		pdEndEffectors(&effectors);
	}

	// do collisions	
	if(1)
	{
		Object *otherobj = NULL;
		ModifierData *md = NULL;

		if(sds->coll_group) // we use groups since we have 2 domains
			go = sds->coll_group->gobject.first;
		else
			base = scene->base.first;

		while(base || go)
		{
			otherobj = NULL;
			if(sds->coll_group) 
			{						
				if(go->ob)							
					otherobj = go->ob;					
			}					
			else						
				otherobj = base->object;					
			if(!otherobj)					
			{						
				if(sds->coll_group)							
					go = go->next;						
				else							
					base= base->next;						
				continue;					
			}			
			md = modifiers_findByType(otherobj, eModifierType_Smoke);
			
			// check for active smoke modifier
			if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render))					
			{
				SmokeModifierData *smd2 = (SmokeModifierData *)md;

				if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll && smd2->coll->points)
				{
					// we got nice collision object
					SmokeCollSettings *scs = smd2->coll;
					size_t i, j;
					unsigned char *obstacles = smoke_get_obstacle(smd->domain->fluid);

					for(i = 0; i < scs->numpoints; i++)
					{
						int badcell = 0;
						size_t index = 0;
						int cell[3];

						// 1. get corresponding cell
						get_cell(smd->domain->p0, smd->domain->res, smd->domain->dx, &scs->points[3 * i], cell, 0);
					
						// check if cell is valid (in the domain boundary)
						for(j = 0; j < 3; j++)
							if((cell[j] > sds->res[j] - 1) || (cell[j] < 0))
							{
								badcell = 1;
								break;
							}
																
							if(badcell)									
								continue;
						// 2. set cell values (heat, density and velocity)
						index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]);
														
						// printf("cell[0]: %d, cell[1]: %d, cell[2]: %d\n", cell[0], cell[1], cell[2]);								
						// printf("res[0]: %d, res[1]: %d, res[2]: %d, index: %d\n\n", sds->res[0], sds->res[1], sds->res[2], index);																	
						obstacles[index] = 1;
						// for moving gobstacles								
						/*
						const LbmFloat maxVelVal = 0.1666;
						const LbmFloat maxusqr = maxVelVal*maxVelVal*3. *1.5;

						LbmVec objvel = vec2L((mMOIVertices[n]-mMOIVerticesOld[n]) /dvec); 
						{ 								
						const LbmFloat usqr = (objvel[0]*objvel[0]+objvel[1]*objvel[1]+objvel[2]*objvel[2])*1.5; 								
						USQRMAXCHECK(usqr, objvel[0],objvel[1],objvel[2], mMaxVlen, mMxvx,mMxvy,mMxvz); 								
						if(usqr>maxusqr) { 									
						// cutoff at maxVelVal 									
						for(int jj=0; jj<3; jj++) { 										
						if(objvel[jj]>0.) objvel[jj] =  maxVelVal;  										
						if(objvel[jj]<0.) objvel[jj] = -maxVelVal; 									
						} 								
						} 
						} 								
						const LbmFloat dp=dot(objvel, vec2L((*pNormals)[n]) ); 								
						const LbmVec oldov=objvel; // debug								
						objvel = vec2L((*pNormals)[n]) *dp;								
						*/
					}
				}
			}

			if(sds->coll_group)
				go = go->next;
			else
				base= base->next;
		}
	}
}
Ejemplo n.º 7
0
Archivo: smoke.c Proyecto: jinjoh/NOOR
void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
{	
	if((smd->type & MOD_SMOKE_TYPE_FLOW))
	{
		if(scene->r.cfra >= smd->time)
			smokeModifier_init(smd, ob, scene, dm);

		if(scene->r.cfra > smd->time)
		{
			// XXX TODO
			smd->time = scene->r.cfra;

			// rigid movement support
			/*
			Mat4CpyMat4(smd->flow->mat_old, smd->flow->mat);
			Mat4CpyMat4(smd->flow->mat, ob->obmat);
			*/
		}
		else if(scene->r.cfra < smd->time)
		{
			smd->time = scene->r.cfra;
			smokeModifier_reset(smd);
		}
	}
	else if(smd->type & MOD_SMOKE_TYPE_COLL)
	{
		if(scene->r.cfra >= smd->time)
			smokeModifier_init(smd, ob, scene, dm);

		if(scene->r.cfra > smd->time)
		{
			// XXX TODO
			smd->time = scene->r.cfra;
			
			if(smd->coll->dm)
				smd->coll->dm->release(smd->coll->dm);

			smd->coll->dm = CDDM_copy(dm);

			// rigid movement support
			Mat4CpyMat4(smd->coll->mat_old, smd->coll->mat);
			Mat4CpyMat4(smd->coll->mat, ob->obmat);
		}
		else if(scene->r.cfra < smd->time)
		{
			smd->time = scene->r.cfra;
			smokeModifier_reset(smd);
		}
	}
	else if(smd->type & MOD_SMOKE_TYPE_DOMAIN)
	{
		SmokeDomainSettings *sds = smd->domain;
		float light[3];	
		PointCache *cache = NULL;
		PTCacheID pid;
		PointCache *cache_wt = NULL;
		PTCacheID pid_wt;
		int startframe, endframe, framenr;
		float timescale;
		int cache_result = 0, cache_result_wt = 0;

		framenr = scene->r.cfra;

		// printf("time: %d\n", scene->r.cfra);

		if(framenr == smd->time)
			return;

		cache = sds->point_cache[0];
		BKE_ptcache_id_from_smoke(&pid, ob, smd);
		BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, &timescale);

		cache_wt = sds->point_cache[1];
		BKE_ptcache_id_from_smoke_turbulence(&pid_wt, ob, smd);

		if(!smd->domain->fluid)
		{
			BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
			BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_OUTDATED);
		}

		if(framenr < startframe)
			return;

		if(framenr > endframe)
			return;

		if(!smd->domain->fluid && (framenr != startframe))
			return;

		// printf("startframe: %d, framenr: %d\n", startframe, framenr);

		if(!smokeModifier_init(smd, ob, scene, dm))
		{
			printf("bad smokeModifier_init\n");
			return;
		}

		/* try to read from cache */
		cache_result =  BKE_ptcache_read_cache(&pid, (float)framenr, scene->r.frs_sec);
		// printf("cache_result: %d\n", cache_result);

		if(cache_result == PTCACHE_READ_EXACT) 
		{
			cache->flag |= PTCACHE_SIMULATION_VALID;
			cache->simframe= framenr;

			if(sds->wt)
			{
				cache_result_wt = BKE_ptcache_read_cache(&pid_wt, (float)framenr, scene->r.frs_sec);
				
				if(cache_result_wt == PTCACHE_READ_EXACT) 
				{
					cache_wt->flag |= PTCACHE_SIMULATION_VALID;
					cache_wt->simframe= framenr;
				}
			}
			return;
		}

		tstart();

		smoke_calc_domain(scene, ob, smd);
		
		// set new time
		smd->time = scene->r.cfra;

		/* do simulation */

		// low res
		cache->flag |= PTCACHE_SIMULATION_VALID;
		cache->simframe= framenr;

		// simulate the actual smoke (c++ code in intern/smoke)
		// DG: interesting commenting this line + deactivating loading of noise files
		if(framenr!=startframe)
		{
			if(sds->flags & MOD_SMOKE_DISSOLVE)
				smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
			smoke_step(sds->fluid, smd->time);
		}

		// create shadows before writing cache so we get nice shadows for sstartframe, too
		if(get_lamp(scene, light))
			smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx);
	
		BKE_ptcache_write_cache(&pid, framenr);

		if(sds->wt)
		{
			if(framenr!=startframe)
			{
				if(sds->flags & MOD_SMOKE_DISSOLVE)
					smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG);
				smoke_turbulence_step(sds->wt, sds->fluid);
			}

			cache_wt->flag |= PTCACHE_SIMULATION_VALID;
			cache_wt->simframe= framenr;
			BKE_ptcache_write_cache(&pid_wt, framenr);
		}

		tend();
		printf ( "Frame: %d, Time: %f\n", (int)smd->time, ( float ) tval() );
	}
}