Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenlib/BLI_math_geom.h7
-rw-r--r--source/blender/blenlib/intern/math_geom.c40
-rw-r--r--source/blender/editors/transform/transform_constraints.c22
3 files changed, 59 insertions, 10 deletions
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index 484d5af194d..d5485765844 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -302,6 +302,13 @@ bool isect_line_line_strict_v3(const float v1[3],
float vi[3],
float *r_lambda);
+bool isect_ray_ray_v3(const float ray_origin_a[3],
+ const float ray_direction_a[3],
+ const float ray_origin_b[3],
+ const float ray_direction_b[3],
+ float *r_lambda_a,
+ float *r_lambda_b);
+
bool isect_ray_plane_v3(const float ray_origin[3],
const float ray_direction[3],
const float plane[4],
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 5dbd2a52d07..8b715ebf87b 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -2798,6 +2798,46 @@ bool isect_line_line_strict_v3(const float v1[3],
}
}
+/**
+ * Check if two rays are not parallel and returns a factor that indicates
+ * the distance from \a ray_origin_b to the closest point on ray-a to ray-b.
+ *
+ * \note Neither directions need to be normalized.
+ */
+bool isect_ray_ray_v3(const float ray_origin_a[3],
+ const float ray_direction_a[3],
+ const float ray_origin_b[3],
+ const float ray_direction_b[3],
+ float *r_lambda_a,
+ float *r_lambda_b)
+{
+ BLI_assert(r_lambda_a || r_lambda_b);
+ float n[3];
+ cross_v3_v3v3(n, ray_direction_b, ray_direction_a);
+ const float nlen = len_squared_v3(n);
+
+ if (UNLIKELY(nlen == 0.0f)) {
+ /* The lines are parallel. */
+ return false;
+ }
+
+ float t[3], c[3], cray[3];
+ sub_v3_v3v3(t, ray_origin_b, ray_origin_a);
+ sub_v3_v3v3(c, n, t);
+
+ if (r_lambda_a != NULL) {
+ cross_v3_v3v3(cray, c, ray_direction_a);
+ *r_lambda_a = dot_v3v3(cray, n) / nlen;
+ }
+
+ if (r_lambda_b != NULL) {
+ cross_v3_v3v3(cray, c, ray_direction_b);
+ *r_lambda_b = dot_v3v3(cray, n) / nlen;
+ }
+
+ return true;
+}
+
bool isect_aabb_aabb_v3(const float min1[3],
const float max1[3],
const float min2[3],
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index cb539c8d1a5..208242d53b3 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -235,8 +235,7 @@ static void axisProjection(const TransInfo *t,
normalize_v3_v3_length(out, axis, -factor);
}
else {
- float v[3], i1[3], i2[3];
- float v2[3], v4[3];
+ float v[3];
float norm_center[3];
float plane[3];
@@ -261,14 +260,17 @@ static void axisProjection(const TransInfo *t,
}
}
else {
- add_v3_v3v3(v2, t_con_center, axis);
- add_v3_v3v3(v4, v, norm);
-
- isect_line_line_v3(t_con_center, v2, v, v4, i1, i2);
-
- sub_v3_v3v3(v, i2, v);
-
- sub_v3_v3v3(out, i1, t_con_center);
+ /* Use ray-ray intersection instead of line-line because this gave
+ * precision issues adding small values to large numbers. */
+ float mul;
+ if (isect_ray_ray_v3(v, norm, t_con_center, axis, &mul, NULL)) {
+ madd_v3_v3v3fl(out, t_con_center, axis, mul);
+ sub_v3_v3(out, t_con_center);
+ }
+ else {
+ /* In practice this should never fail. */
+ BLI_assert(0);
+ }
/* possible some values become nan when
* viewpoint and object are both zero */