[Bf-blender-cvs] [ef8a137d8ab] fluid-mantaflow: fix for particle and mesh scaling

Sebastián Barschkis noreply at git.blender.org
Sat Nov 11 13:08:19 CET 2017


Commit: ef8a137d8ab1b46b54055baced2c3cdcf2906fdd
Author: Sebastián Barschkis
Date:   Sat Nov 11 13:02:44 2017 +0100
Branches: fluid-mantaflow
https://developer.blender.org/rBef8a137d8ab1b46b54055baced2c3cdcf2906fdd

fix for particle and mesh scaling

===================================================================

M	source/blender/blenkernel/intern/particle_system.c
M	source/blender/blenkernel/intern/smoke.c

===================================================================

diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 24cc32f8e55..7d6c6996ade 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -3788,9 +3788,12 @@ static void particles_manta_step(ParticleSimulationData *sim, int UNUSED(cfra),
 			int p, totpart, tottypepart = 0;
 			int flagActivePart, activeParts = 0;
 			float posX, posY, posZ, velX, velY, velZ;
-			int resX, resY, resZ;
+			float resX, resY, resZ;
 			char debugStrBuffer[256];
 
+			// Helper for scaling
+			float min[3], max[3], size[3], cell_size_scaled[3], max_size;
+
 			// Sanity check: parts also enabled in fluid domain?
 			if ((part->type == PART_MANTA_FLIP && (sds->particle_type & MOD_SMOKE_PARTICLE_FLIP)==0) ||
 				(part->type == PART_MANTA_DROP && (sds->particle_type & MOD_SMOKE_PARTICLE_DROP)==0) ||
@@ -3854,9 +3857,9 @@ static void particles_manta_step(ParticleSimulationData *sim, int UNUSED(cfra),
 
 				// printf("system type is %d and particle type is %d\n", part->type, flagActivePart);
 
-				resX = fluid_get_res_x(sds->fluid);
-				resY = fluid_get_res_y(sds->fluid);
-				resZ = fluid_get_res_z(sds->fluid);
+				resX = (float) fluid_get_res_x(sds->fluid);
+				resY = (float) fluid_get_res_y(sds->fluid);
+				resZ = (float) fluid_get_res_z(sds->fluid);
 
 				if (part->type == PART_MANTA_FLIP) {
 					posX = liquid_get_flip_particle_position_x_at(sds->fluid, p);
@@ -3881,41 +3884,35 @@ static void particles_manta_step(ParticleSimulationData *sim, int UNUSED(cfra),
 
 					pa->size = sds->particle_radius;
 					pa->size /= 10.0f;
+					
+					// Get size (dimension) but considering scaling scaling
+					copy_v3_v3(cell_size_scaled, sds->cell_size);
+					mul_v3_v3(cell_size_scaled, ob->size);
+					VECMADD(min, sds->p0, cell_size_scaled, sds->res_min);
+					VECMADD(max, sds->p0, cell_size_scaled, sds->res_max);
+					sub_v3_v3v3(size, max, min);
 
-					float ob_loc[3] = {0};
-					float ob_cache_loc[3] = {0};
+					// Biggest dimension will be used for upscaling
+					max_size = MAX3(size[0], size[1], size[2]);
 
 					// set particle position
 					pa->state.co[0] = posX;
 					pa->state.co[1] = posY;
 					pa->state.co[2] = posZ;
 
-					// translate particles coordinates to  origin (0,0,0)
-					pa->state.co[0] -= resX / 2.0f;
-					pa->state.co[1] -= resY / 2.0f;
-					pa->state.co[2] -= resZ / 2.0f;
-
-					// scale down
-					pa->state.co[0] *= 1.0f / resX;
-					pa->state.co[1] *= 1.0f / resY;
-					pa->state.co[2] *= 1.0f / resZ;
-
-					// scale up
-					mul_v3_fl(pa->state.co, sds->scale);
-
-					/* calculate required shift to match domain's global position
-					 *  it was originally simulated at (if object moves without step) */
-					invert_m4_m4(ob->imat, ob->obmat);
-					mul_m4_v3(ob->obmat, ob_loc);
-					mul_m4_v3(sds->obmat, ob_cache_loc);
-					VECSUB(sds->obj_shift_f, ob_cache_loc, ob_loc);
-					/* convert shift to local space and apply to particles */
-					mul_mat3_m4_v3(ob->imat, sds->obj_shift_f);
-					/* apply */
-					sub_v3_v3(pa->state.co, sds->obj_shift_f);
-
-					// scale up to match actual domain size. also take care of domain translations globally
-					mul_m4_v3(sds->obmat, pa->state.co);
+					// normalize to unit cube around 0
+					pa->state.co[0] -= resX * 0.5f;
+					pa->state.co[1] -= resY * 0.5f;
+					pa->state.co[2] -= resZ * 0.5f;
+					mul_v3_fl(pa->state.co, sds->dx);
+
+					// match domain dimension / size
+					pa->state.co[0] *= max_size / fabsf(ob->size[0]);;
+					pa->state.co[1] *= max_size / fabsf(ob->size[1]);;
+					pa->state.co[2] *= max_size / fabsf(ob->size[2]);;
+
+					// match domain scale
+					mul_m4_v3(ob->obmat, pa->state.co);
 
 					// printf("pa->state.co[0]: %f, pa->state.co[1]: %f, pa->state.co[2]: %f\n", pa->state.co[0], pa->state.co[1], pa->state.co[2]);
 
@@ -3923,11 +3920,7 @@ static void particles_manta_step(ParticleSimulationData *sim, int UNUSED(cfra),
 					pa->state.vel[0] = velX;
 					pa->state.vel[1] = velY;
 					pa->state.vel[2] = velZ;
-
-					// scale down
-					pa->state.vel[0] *= 1.0f / resX;
-					pa->state.vel[1] *= 1.0f / resY;
-					pa->state.vel[2] *= 1.0f / resZ;
+					mul_v3_fl(pa->state.vel, sds->dx);
 
 					// printf("pa->state.vel[0]: %f, pa->state.vel[1]: %f, pa->state.vel[2]: %f\n", pa->state.vel[0], pa->state.vel[1], pa->state.vel[2]);
 
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 1528c8d6921..455b93cb6b8 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -2949,7 +2949,11 @@ static DerivedMesh *createLiquidMesh(SmokeDomainSettings *sds, DerivedMesh *orgd
 	MLoop *mloops;
 	short *normals, *no_s;
 	float no[3];
-	
+	float min[3];
+	float max[3];
+	float size[3];
+	float cell_size_scaled[3];
+
 	/* assign material + flags to new dm
 	 * if there's no faces in original dm, keep materials and flags unchanged */
 	MPoly *mpoly;
@@ -2958,54 +2962,63 @@ static DerivedMesh *createLiquidMesh(SmokeDomainSettings *sds, DerivedMesh *orgd
 	if (mpoly) {
 		mp_example = *mpoly;
 	}
-	
+
 	const short mp_mat_nr = mp_example.mat_nr;
 	const char mp_flag    = mp_example.flag;
-	
+
 	int i;
 	int num_verts, num_normals, num_faces;
-	
+
 	if (!sds->fluid)
 		return NULL;
-	
+
 	/* just display original object */
 	if (sds->viewport_display_mode == SM_VIEWPORT_GEOMETRY)
 		return NULL;
-	
+
 	num_verts   = liquid_get_num_verts(sds->fluid);
 	num_normals = liquid_get_num_normals(sds->fluid);
 	num_faces   = liquid_get_num_triangles(sds->fluid);
-	
+
 	if (!num_verts || !num_normals || !num_faces)
 		return NULL;
-	
+
 	dm     = CDDM_new(num_verts, 0, 0, num_faces * 3, num_faces);
 	mverts = CDDM_get_verts(dm);
 	mpolys = CDDM_get_polys(dm);
 	mloops = CDDM_get_loops(dm);
-	
+
 	if (!dm)
 		return NULL;
-	
-	float max_size = MAX3(sds->global_size[0], sds->global_size[1], sds->global_size[2]);
-	
+
+	// Get size (dimension) but considering scaling scaling
+	copy_v3_v3(cell_size_scaled, sds->cell_size);
+	mul_v3_v3(cell_size_scaled, ob->size);
+	VECMADD(min, sds->p0, cell_size_scaled, sds->res_min);
+	VECMADD(max, sds->p0, cell_size_scaled, sds->res_max);
+	sub_v3_v3v3(size, max, min);
+
+	// Biggest dimension will be used for upscaling
+	float max_size = MAX3(size[0], size[1], size[2]);
+
 	// Vertices
 	for (i = 0; i < num_verts; i++, mverts++)
 	{
+		// read raw data. is normalized cube around domain origin
 		mverts->co[0] = liquid_get_vertex_x_at(sds->fluid, i);
 		mverts->co[1] = liquid_get_vertex_y_at(sds->fluid, i);
 		mverts->co[2] = liquid_get_vertex_z_at(sds->fluid, i);
-		
+
 		mverts->co[0] *= max_size / fabsf(ob->size[0]);
 		mverts->co[1] *= max_size / fabsf(ob->size[1]);
 		mverts->co[2] *= max_size / fabsf(ob->size[2]);
-		
+
 //		printf("mverts->co[0]: %f, mverts->co[1]: %f, mverts->co[2]: %f\n", mverts->co[0], mverts->co[1], mverts->co[2]);
 	}
-	
+
 	// Normals
 	normals = MEM_callocN(sizeof(short) * num_normals * 3, "liquid_tmp_normals");
-	
+
 	for (i = 0, no_s = normals; i < num_normals; no_s += 3, i++)
 	{
 		no[0] = liquid_get_normal_x_at(sds->fluid, i);
@@ -3013,10 +3026,10 @@ static DerivedMesh *createLiquidMesh(SmokeDomainSettings *sds, DerivedMesh *orgd
 		no[2] = liquid_get_normal_z_at(sds->fluid, i);
 
 		normal_float_to_short_v3(no_s, no);
-		
+
 //		printf("no_s[0]: %d, no_s[1]: %d, no_s[2]: %d\n", no_s[0], no_s[1], no_s[2]);
 	}
-	
+
 	// Triangles
 	for (i = 0; i < num_faces; i++, mpolys++, mloops += 3)
 	{
@@ -3026,17 +3039,17 @@ static DerivedMesh *createLiquidMesh(SmokeDomainSettings *sds, DerivedMesh *orgd
 
 		mpolys->loopstart = i * 3;
 		mpolys->totloop = 3;
-		
+
 		mloops[0].v = liquid_get_triangle_x_at(sds->fluid, i);
 		mloops[1].v = liquid_get_triangle_y_at(sds->fluid, i);
 		mloops[2].v = liquid_get_triangle_z_at(sds->fluid, i);
-		
+
 //		printf("mloops[0].v: %d, mloops[1].v: %d, mloops[2].v: %d\n", mloops[0].v, mloops[1].v, mloops[2].v);
 	}
-	
+
 	CDDM_calc_edges(dm);
 	CDDM_apply_vert_normals(dm, (short (*)[3])normals);
-	
+
 	MEM_freeN(normals);
 
 	return dm;



More information about the Bf-blender-cvs mailing list