[Bf-blender-cvs] [3f0b3a4fb0] cloth-improvements: Merge branch 'master' into cloth-develop

Luca Rood noreply at git.blender.org
Thu Mar 16 22:31:35 CET 2017


Commit: 3f0b3a4fb0107b7939b712227f470340e6d7339d
Author: Luca Rood
Date:   Thu Mar 16 17:56:34 2017 -0300
Branches: cloth-improvements
https://developer.blender.org/rB3f0b3a4fb0107b7939b712227f470340e6d7339d

Merge branch 'master' into cloth-develop

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



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

diff --cc source/blender/blenkernel/BKE_deform.h
index c2679a3d06,3ce08a1417..a183ea7f66
--- a/source/blender/blenkernel/BKE_deform.h
+++ b/source/blender/blenkernel/BKE_deform.h
@@@ -116,21 -116,4 +116,12 @@@ void BKE_defvert_extract_vgroup_to_poly
          struct MDeformVert *dvert, const int defgroup, const int num_verts, struct MLoop *loops, const int num_loops,
          struct MPoly *polys, const int num_polys, float *r_weights, const bool invert_vgroup);
  
- /* utility function, note that MAX_VGROUP_NAME chars is the maximum string length since its only
-  * used with defgroups currently */
- 
- void BKE_deform_split_suffix(const char string[MAX_VGROUP_NAME], char base[MAX_VGROUP_NAME], char ext[MAX_VGROUP_NAME]);
- void BKE_deform_split_prefix(const char string[MAX_VGROUP_NAME], char base[MAX_VGROUP_NAME], char ext[MAX_VGROUP_NAME]);
- 
- void BKE_deform_flip_side_name(char name[MAX_VGROUP_NAME], const char from_name[MAX_VGROUP_NAME],
-                                const bool strip_number);
- 
 +float BKE_defvert_combined_weight(const Object *object, const struct MDeformVert *dvert, const int mode);
 +
 +/* combined weight mode */
 +enum {
 +	DVERT_COMBINED_MODE_ADD = 0,
 +	DVERT_COMBINED_MODE_MIX = 1,
 +};
 +
  #endif  /* __BKE_DEFORM_H__ */
diff --cc source/blender/blenkernel/intern/collision.c
index 33e4f30708,ee25be3685..95a384e94c
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@@ -174,419 -172,6 +174,419 @@@ void bvhtree_update_from_mvert
  Collision modifier code end
  ***********************************/
  
 +static void clamp_point_seg(float a[3], float b[3], float p[3])
 +{
 +	float ap[3], bp[3], ab[3];
 +
 +	sub_v3_v3v3(ap, p, a);
 +	sub_v3_v3v3(bp, p, b);
 +	sub_v3_v3v3(ab, b, a);
 +
 +	if (dot_v3v3(ap, bp) > 0.0f) {
 +		if (dot_v3v3(ap, ab) > 0.0f) {
 +			copy_v3_v3(p, b);
 +		}
 +		else {
 +			copy_v3_v3(p, a);
 +		}
 +	}
 +}
 +
 +static bool isect_seg_seg(float a1[3], float a2[3], float b1[3], float b2[3], float r_a[3], float r_b[3])
 +{
 +	if (isect_line_line_v3(a1, a2, b1, b2, r_a, r_b)) {
 +		clamp_point_seg(a1, a2, r_a);
 +		clamp_point_seg(b1, b2, r_b);
 +
 +		return true;
 +	}
 +
 +	return false;
 +}
 +
 +BLI_INLINE int next_ind(int i)
 +{
 +	return (++i < 3) ? i : 0;
 +}
 +
 +static float compute_collision_point(float a1[3], float a2[3], float a3[3], float b1[3], float b2[3], float b3[3],
 +                                     bool culling, bool use_normal, float r_a[3], float r_b[3], float r_vec[3])
 +{
 +	float a[3][3];
 +	float b[3][3];
 +	float dist;
 +	float mindist = FLT_MAX;
 +	float tmp_co1[3], tmp_co2[3];
 +	float isect_a[3], isect_b[3];
 +	int isect_count = 0;
 +	float tmp, tmp_vec[3];
 +	float normal[3], cent[3];
 +	bool backside = false;
 +
 +	copy_v3_v3(a[0], a1);
 +	copy_v3_v3(a[1], a2);
 +	copy_v3_v3(a[2], a3);
 +
 +	copy_v3_v3(b[0], b1);
 +	copy_v3_v3(b[1], b2);
 +	copy_v3_v3(b[2], b3);
 +
 +	/* Find intersections */
 +	for (int i = 0; i < 3; i++) {
 +		if (isect_line_segment_tri_v3(a[i], a[next_ind(i)], b[0], b[1], b[2], &tmp, NULL)) {
 +			interp_v3_v3v3(isect_a, a[i], a[next_ind(i)], tmp);
 +			isect_count++;
 +		}
 +	}
 +
 +	if (isect_count == 0) {
 +		for (int i = 0; i < 3; i++) {
 +			if (isect_line_segment_tri_v3(b[i], b[next_ind(i)], a[0], a[1], a[2], &tmp, NULL)) {
 +				isect_count++;
 +			}
 +		}
 +	}
 +	else if (isect_count == 1) {
 +		for (int i = 0; i < 3; i++) {
 +			if (isect_line_segment_tri_v3(b[i], b[next_ind(i)], a[0], a[1], a[2], &tmp, NULL)) {
 +				interp_v3_v3v3(isect_b, b[i], b[next_ind(i)], tmp);
 +				break;
 +			}
 +		}
 +	}
 +
 +	/* Determine collision side */
 +	if (culling) {
 +		normal_tri_v3(normal, b[0], b[1], b[2]);
- 		cent_tri_v3(cent, b[0], b[1], b[2]);
++		mid_v3_v3v3v3(cent, b[0], b[1], b[2]);
 +
 +		if (isect_count == 2) {
 +			backside = true;
 +		}
 +		else if (isect_count == 0) {
 +			for (int i = 0; i < 3; i++) {
 +				sub_v3_v3v3(tmp_vec, a[i], cent);
 +				if (dot_v3v3(tmp_vec, normal) < 0.0f) {
 +					backside = true;
 +					break;
 +				}
 +			}
 +		}
 +	}
 +	else if (use_normal) {
 +		normal_tri_v3(normal, b[0], b[1], b[2]);
 +	}
 +
 +	if (isect_count == 1) {
 +		/* Edge intersection */
 +		copy_v3_v3(r_a, isect_a);
 +		copy_v3_v3(r_b, isect_b);
 +
 +		sub_v3_v3v3(r_vec, r_b, r_a);
 +
 +		if (use_normal) {
 +			copy_v3_v3(r_vec, normal);
 +		}
 +
 +		return 0.0f;
 +	}
 +	else if (backside) {
 +		float maxdist = 0.0f;
 +		bool found = false;
 +
 +		/* Point projections */
 +		for (int i = 0; i < 3; i++) {
 +			if (isect_ray_tri_v3(a[i], normal, b[0], b[1], b[2], &tmp, NULL)) {
 +				if (tmp > maxdist) {
 +					maxdist = tmp;
 +					copy_v3_v3(r_a, a[i]);
 +					madd_v3_v3v3fl(r_b, a[i], normal, tmp);
 +					found = true;
 +				}
 +			}
 +		}
 +
 +		negate_v3(normal);
 +
 +		for (int i = 0; i < 3; i++) {
 +			if (isect_ray_tri_v3(b[i], normal, a[0], a[1], a[2], &tmp, NULL)) {
 +				if (tmp > maxdist) {
 +					maxdist = tmp;
 +					madd_v3_v3v3fl(r_a, b[i], normal, tmp);
 +					copy_v3_v3(r_b, b[i]);
 +					found = true;
 +				}
 +			}
 +		}
 +
 +		negate_v3(normal);
 +
 +		/* Edge projections */
 +		for (int i = 0; i < 3; i++) {
 +			float dir[3];
 +
 +			sub_v3_v3v3(tmp_vec, b[next_ind(i)], b[i]);
 +			cross_v3_v3v3(dir, tmp_vec, normal);
 +
 +			for (int j = 0; j < 3; j++) {
 +				if (isect_line_plane_v3(tmp_co1, a[j], a[next_ind(j)], b[i], dir) &&
 +				    point_in_slice_seg(tmp_co1, a[j], a[next_ind(j)]) &&
 +				    point_in_slice_seg(tmp_co1, b[i], b[next_ind(i)]))
 +				{
 +					closest_to_line_v3(tmp_co2, tmp_co1, b[i], b[next_ind(i)]);
 +					sub_v3_v3v3(tmp_vec, tmp_co1, tmp_co2);
 +					tmp = len_v3(tmp_vec);
 +
 +					if ((tmp > maxdist) && (dot_v3v3(tmp_vec, normal) < 0.0f)) {
 +						maxdist = tmp;
 +						copy_v3_v3(r_a, tmp_co1);
 +						copy_v3_v3(r_b, tmp_co2);
 +						found = true;
 +					}
 +				}
 +			}
 +		}
 +
 +		/* If no point is found, will fallback onto regular proximity test below */
 +		if (found) {
 +			sub_v3_v3v3(r_vec, r_b, r_a);
 +
 +			if (use_normal) {
 +				if (dot_v3v3(normal, r_vec) >= 0.0f) {
 +					copy_v3_v3(r_vec, normal);
 +				}
 +				else {
 +					negate_v3_v3(r_vec, normal);
 +				}
 +			}
 +
 +			return 0.0f;
 +		}
 +	}
 +
 +	/* Closest point */
 +	for (int i = 0; i < 3; i++) {
 +		closest_on_tri_to_point_v3(tmp_co1, a[i], b[0], b[1], b[2]);
 +		tmp = len_squared_v3v3(tmp_co1, a[i]);
 +
 +		if (tmp < mindist) {
 +			mindist = tmp;
 +			copy_v3_v3(r_a, a[i]);
 +			copy_v3_v3(r_b, tmp_co1);
 +		}
 +	}
 +
 +	for (int i = 0; i < 3; i++) {
 +		closest_on_tri_to_point_v3(tmp_co1, b[i], a[0], a[1], a[2]);
 +		tmp = len_squared_v3v3(tmp_co1, b[i]);
 +
 +		if (tmp < mindist) {
 +			mindist = tmp;
 +			copy_v3_v3(r_a, tmp_co1);
 +			copy_v3_v3(r_b, b[i]);
 +		}
 +	}
 +
 +	/* Closest edge */
 +	if (isect_count == 0) {
 +		for (int i = 0; i < 3; i++) {
 +			for (int j = 0; j < 3; j++) {
 +				if (isect_seg_seg(a[i], a[next_ind(i)], b[j], b[next_ind(j)], tmp_co1, tmp_co2)) {
 +					tmp = len_squared_v3v3(tmp_co1, tmp_co2);
 +
 +					if (tmp < mindist) {
 +						mindist = tmp;
 +						copy_v3_v3(r_a, tmp_co1);
 +						copy_v3_v3(r_b, tmp_co2);
 +					}
 +				}
 +			}
 +		}
 +	}
 +
 +	if (isect_count == 0) {
 +		sub_v3_v3v3(r_vec, r_a, r_b);
 +		dist = sqrtf(mindist);
 +	}
 +	else {
 +		sub_v3_v3v3(r_vec, r_b, r_a);
 +		dist = 0.0f;
 +	}
 +
 +	if (culling && use_normal) {
 +		copy_v3_v3(r_vec, normal);
 +	}
 +	else if (use_normal) {
 +		if (dot_v3v3(normal, r_vec) >= 0.0f) {
 +			copy_v3_v3(r_vec, normal);
 +		}
 +		else {
 +			negate_v3_v3(r_vec, normal);
 +		}
 +	}
 +	else if (culling && (dot_v3v3(r_vec, normal) < 0.0f)) {
 +		return FLT_MAX;
 +	}
 +
 +	return dist;
 +}
 +
 +static void free_impulse_clusters(ImpulseCluster *clusters)
 +{
 +	while (clusters) {
 +		ImpulseCluster *next = clusters->next;
 +
 +		MEM_freeN(clusters);
 +
 +		clusters = next;
 +	}
 +}
 +
 +/* This allows inserting impulses one by one into the cluster array, and immediately computing the clustering,
 + * but the clustering isn't exact, because of not knowing all impulses beforehand.
 + * Seems to be good enough however, and is much faster than the true hclust below... */
 +static void insert_impulse_in_cluster_array(ImpulseCluster **clusters, const float impulse[3], const float clustang)
 +{
 +	ImpulseCluster *imp;
 +	ImpulseCluster *close = NULL;
 +	float dir[3];
 +	float mag;
 +	float minang = FLT_MAX;
 +	float ang;
 +
 +	mag = normalize_v3_v3(dir, impulse);
 +
 +	if (mag < FLT_EPSILON) {
 +		return;
 +	}
 +
 +	for (imp = *clusters; imp; imp = imp->next) {
 +		ang = angle_normalized_v3v3(imp->dir, dir);
 +
 +		if (ang < minang) {
 +			minang = ang;
 +			close = imp;
 +		}
 +	}
 +
 +	if (minang < clustang) {
 +		/* Set total magnitude */
 +		close->totmag += mag;
 +
 +		/* Set dominant magnitude */
 +		close->dominant_mag = max_ff(close->dominant_mag, mag);
 +
 +		/* Interpolate direction */
 +		if(!interp_v3_v3v3_slerp(close->dir, close->dir, dir, mag / close->totmag)) {
 +			BLI_assert(false);
 +		}
 +	}
 +	else {
 +		ImpulseCluster *tmp = MEM_mallocN(sizeof(*tmp), "cloth_collision_impulse_cluster");
 +
 +		tmp->next = *clusters;
 +		copy_v3_v3(tmp->dir, dir);
 +		tmp->totmag = mag;
 +		tmp->dominant_mag = mag;
 +
 +		*clusters = tmp;
 +	}
 +}
 +
 +#if 0
 +static void insert_impulse_in_cluster_array(ImpulseCluster **clusters, const float impulse[3])
 +{
 +	ImpulseCluster *tmp;
 +	float dir[3];
 +	float mag;
 +
 +	mag = normalize_v3_v3(dir, impulse);
 +
 +	if (mag < FLT_EPSILON) {
 +		return;
 +	}
 +
 +	tmp = MEM_mallocN(sizeof(*tmp), "cloth_collision_impulse_cluster");
 +
 +	copy_v3_v3(tmp->dir, dir);
 +	tmp->totmag = mag;
 +	tmp->dominant_mag = mag;
 +
 +	tmp->next = *clusters;
 +	*clusters = tmp;
 +}
 +
 +BLI_INLINE bool join_closest_impulse_clusters(ImpulseCluster **clusters, const float clustang)
 +{
 +	ImpulseCluster **imp1, **imp2;
 +	ImpulseCluster **close1, **close2;
 +	float minang = FLT_MAX;
 +	float ang;
 +
 +	for (imp1 = clusters; *imp1; imp1 = &(*imp1)->next) {
 +		for (imp2 = &(*imp1)->next; *imp2; imp2 = &(*imp2)->next) {
 +			ang = angle_normalized_v3v3((*imp1)->dir, (*imp2)->dir);
 +
 +			if (ang < minang) {
 +				minang = ang;
 +				close1 = imp1;
 +				close2 = 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list