[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