Ejemplo n.º 1
0
static void rna_SmokeModifier_velocity_grid_get(PointerRNA *ptr, float *values)
{
#ifdef WITH_SMOKE
	SmokeDomainSettings *sds = (SmokeDomainSettings *)ptr->data;
	int length[RNA_MAX_ARRAY_DIMENSION];
	int size = rna_SmokeModifier_velocity_grid_get_length(ptr, length);
	float *vx, *vy, *vz;
	int i;

	BLI_rw_mutex_lock(sds->fluid_mutex, THREAD_LOCK_READ);

	vx = smoke_get_velocity_x(sds->fluid);
	vy = smoke_get_velocity_y(sds->fluid);
	vz = smoke_get_velocity_z(sds->fluid);

	for (i = 0; i < size; i += 3) {
		*(values++) = *(vx++);
		*(values++) = *(vy++);
		*(values++) = *(vz++);
	}

	BLI_rw_mutex_unlock(sds->fluid_mutex);
#else
	UNUSED_VARS(ptr, values);
#endif
}
Ejemplo n.º 2
0
void draw_smoke_velocity(SmokeDomainSettings *domain, Object *ob)
{
	float x, y, z;
	float x0, y0, z0;
	int *base_res = domain->base_res;
	int *res = domain->res;
	int *res_min = domain->res_min;
	int *res_max = domain->res_max;
	float *vel_x = smoke_get_velocity_x(domain->fluid);
	float *vel_y = smoke_get_velocity_y(domain->fluid);
	float *vel_z = smoke_get_velocity_z(domain->fluid);

	float min[3];
	float *cell_size = domain->cell_size;
	float step_size = ((float)max_iii(base_res[0], base_res[1], base_res[2])) / 16.f;
	float vf = domain->scale / 16.f * 2.f; /* velocity factor */

	glLineWidth(1.0f);

	/* set first position so that it doesn't jump when domain moves */
	x0 = res_min[0] + fmod(-(float)domain->shift[0] + res_min[0], step_size);
	y0 = res_min[1] + fmod(-(float)domain->shift[1] + res_min[1], step_size);
	z0 = res_min[2] + fmod(-(float)domain->shift[2] + res_min[2], step_size);
	if (x0 < res_min[0]) x0 += step_size;
	if (y0 < res_min[1]) y0 += step_size;
	if (z0 < res_min[2]) z0 += step_size;
	add_v3_v3v3(min, domain->p0, domain->obj_shift_f);

	for (x = floor(x0); x < res_max[0]; x += step_size)
		for (y = floor(y0); y < res_max[1]; y += step_size)
			for (z = floor(z0); z < res_max[2]; z += step_size) {
				int index = (floor(x) - res_min[0]) + (floor(y) - res_min[1]) * res[0] + (floor(z) - res_min[2]) * res[0] * res[1];

				float pos[3] = {min[0] + ((float)x + 0.5f) * cell_size[0], min[1] + ((float)y + 0.5f) * cell_size[1], min[2] + ((float)z + 0.5f) * cell_size[2]};
				float vel = sqrtf(vel_x[index] * vel_x[index] + vel_y[index] * vel_y[index] + vel_z[index] * vel_z[index]);

				/* draw heat as scaled "arrows" */
				if (vel >= 0.01f) {
					float col_g = 1.0f - vel;
					CLAMP(col_g, 0.0f, 1.0f);
					glColor3f(1.0f, col_g, 0.0f);
					glPointSize(10.0f * vel);

					glBegin(GL_LINES);
					glVertex3f(pos[0], pos[1], pos[2]);
					glVertex3f(pos[0] + vel_x[index] * vf, pos[1] + vel_y[index] * vf, pos[2] + vel_z[index] * vf);
					glEnd();
					glBegin(GL_POINTS);
					glVertex3f(pos[0] + vel_x[index] * vf, pos[1] + vel_y[index] * vf, pos[2] + vel_z[index] * vf);
					glEnd();
				}
			}
}
Ejemplo n.º 3
0
static int rna_SmokeModifier_velocity_grid_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION])
{
#ifdef WITH_SMOKE
	SmokeDomainSettings *sds = (SmokeDomainSettings *)ptr->data;
	float *vx = NULL;
	float *vy = NULL;
	float *vz = NULL;
	int size = 0;

	/* Velocity data is always low-resolution. */
	if (sds->fluid) {
		size = 3 * sds->res[0] * sds->res[1] * sds->res[2];
		vx = smoke_get_velocity_x(sds->fluid);
		vy = smoke_get_velocity_y(sds->fluid);
		vz = smoke_get_velocity_z(sds->fluid);
	}

	length[0] = (vx && vy && vz) ? size : 0;
#else
	(void)ptr;
	length[0] = 0;
#endif
	return length[0];
}
Ejemplo n.º 4
0
static void init_frame_smoke(VoxelData *vd, int 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;
		SmokeDomainSettings *sds = smd->domain;
		
		if (sds && sds->fluid) {
			BLI_rw_mutex_lock(sds->fluid_mutex, THREAD_LOCK_READ);

			if (!sds->fluid) {
				BLI_rw_mutex_unlock(sds->fluid_mutex);
				return;
			}

			if (cfra < sds->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;

				if (!smoke_has_heat(sds->fluid)) {
					BLI_rw_mutex_unlock(sds->fluid_mutex);
					return;
				}

				copy_v3_v3_int(vd->resol, sds->res);
				totRes = vd_resol_size(vd);
				vd->dataset = MEM_mapallocN(sizeof(float) * (totRes), "smoke data");
				/* get heat data */
				heat = smoke_get_heat(sds->fluid);

				/* scale heat values from -2.0-2.0 to 0.0-1.0 */
				for (i = 0; i < totRes; i++) {
					vd->dataset[i] = (heat[i] + 2.0f) / 4.0f;
				}
			}
			else if (vd->smoked_type == TEX_VD_SMOKEVEL) {
				size_t totRes;
				size_t i;
				float *xvel, *yvel, *zvel;

				copy_v3_v3_int(vd->resol, sds->res);
				totRes = vd_resol_size(vd);
				vd->dataset = MEM_mapallocN(sizeof(float) * (totRes), "smoke data");
				/* get velocity data */
				xvel = smoke_get_velocity_x(sds->fluid);
				yvel = smoke_get_velocity_y(sds->fluid);
				zvel = smoke_get_velocity_z(sds->fluid);

				/* map velocities between 0 and 0.3f */
				for (i = 0; i < totRes; i++) {
					vd->dataset[i] = sqrtf(xvel[i] * xvel[i] + yvel[i] * yvel[i] + zvel[i] * zvel[i]) * 3.0f;
				}

			}
			else if (vd->smoked_type == TEX_VD_SMOKEFLAME) {
				size_t totRes;
				float *flame;

				if (sds->flags & MOD_SMOKE_HIGHRES) {
					if (!smoke_turbulence_has_fuel(sds->wt)) {
						BLI_rw_mutex_unlock(sds->fluid_mutex);
						return;
					}
					smoke_turbulence_get_res(sds->wt, vd->resol);
					flame = smoke_turbulence_get_flame(sds->wt);
				}
				else {
					if (!smoke_has_fuel(sds->fluid)) {
						BLI_rw_mutex_unlock(sds->fluid_mutex);
						return;
					}
					copy_v3_v3_int(vd->resol, sds->res);
					flame = smoke_get_flame(sds->fluid);
				}

				/* always store copy, as smoke internal data can change */
				totRes = vd_resol_size(vd);
				vd->dataset = MEM_mapallocN(sizeof(float)*(totRes), "smoke data");
				memcpy(vd->dataset, flame, sizeof(float)*totRes);
			}
			else {
				size_t totCells;
				int depth = 4;
				vd->data_type = TEX_VD_RGBA_PREMUL;

				/* data resolution */
				if (sds->flags & MOD_SMOKE_HIGHRES) {
					smoke_turbulence_get_res(sds->wt, vd->resol);
				}
				else {
					copy_v3_v3_int(vd->resol, sds->res);
				}

				/* TODO: is_vd_res_ok(rvd) doesnt check this resolution */
				totCells = vd_resol_size(vd) * depth;
				/* always store copy, as smoke internal data can change */
				vd->dataset = MEM_mapallocN(sizeof(float) * totCells, "smoke data");

				if (sds->flags & MOD_SMOKE_HIGHRES) {
					if (smoke_turbulence_has_colors(sds->wt)) {
						smoke_turbulence_get_rgba(sds->wt, vd->dataset, 1);
					}
					else {
						smoke_turbulence_get_rgba_from_density(sds->wt, sds->active_color, vd->dataset, 1);
					}
				}
				else {
					if (smoke_has_colors(sds->fluid)) {
						smoke_get_rgba(sds->fluid, vd->dataset, 1);
					}
					else {
						smoke_get_rgba_from_density(sds->fluid, sds->active_color, vd->dataset, 1);
					}
				}
			}  /* end of fluid condition */

			BLI_rw_mutex_unlock(sds->fluid_mutex);
		}
	}
	
	vd->ok = 1;

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

	vd->dataset = NULL;
#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;
		}
	}
}