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:
Diffstat (limited to 'source/blender/draw/intern/shaders/common_math_geom_lib.glsl')
-rw-r--r--source/blender/draw/intern/shaders/common_math_geom_lib.glsl144
1 files changed, 105 insertions, 39 deletions
diff --git a/source/blender/draw/intern/shaders/common_math_geom_lib.glsl b/source/blender/draw/intern/shaders/common_math_geom_lib.glsl
index 6d4452c18c8..71460c39285 100644
--- a/source/blender/draw/intern/shaders/common_math_geom_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_math_geom_lib.glsl
@@ -5,63 +5,88 @@
/** \name Math intersection & projection functions.
* \{ */
-float point_plane_projection_dist(vec3 lineorigin, vec3 planeorigin, vec3 planenormal)
+vec4 plane_from_quad(vec3 v0, vec3 v1, vec3 v2, vec3 v3)
{
- return dot(planenormal, planeorigin - lineorigin);
+ vec3 nor = normalize(cross(v2 - v1, v0 - v1) + cross(v0 - v3, v2 - v3));
+ return vec4(nor, -dot(nor, v2));
}
-float line_plane_intersect_dist(vec3 lineorigin,
- vec3 linedirection,
- vec3 planeorigin,
- vec3 planenormal)
+vec4 plane_from_tri(vec3 v0, vec3 v1, vec3 v2)
{
- return dot(planenormal, planeorigin - lineorigin) / dot(planenormal, linedirection);
+ vec3 nor = normalize(cross(v2 - v1, v0 - v1));
+ return vec4(nor, -dot(nor, v2));
}
-float line_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec4 plane)
+float point_plane_projection_dist(vec3 line_origin, vec3 plane_origin, vec3 plane_normal)
+{
+ return dot(plane_normal, plane_origin - line_origin);
+}
+
+float point_line_projection_dist(vec2 point, vec2 line_origin, vec2 line_normal)
+{
+ return dot(line_normal, line_origin - point);
+}
+
+float line_plane_intersect_dist(vec3 line_origin,
+ vec3 line_direction,
+ vec3 plane_origin,
+ vec3 plane_normal)
+{
+ return dot(plane_normal, plane_origin - line_origin) / dot(plane_normal, line_direction);
+}
+
+float line_plane_intersect_dist(vec3 line_origin, vec3 line_direction, vec4 plane)
{
vec3 plane_co = plane.xyz * (-plane.w / len_squared(plane.xyz));
- vec3 h = lineorigin - plane_co;
- return -dot(plane.xyz, h) / dot(plane.xyz, linedirection);
+ vec3 h = line_origin - plane_co;
+ return -dot(plane.xyz, h) / dot(plane.xyz, line_direction);
}
-vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin, vec3 planenormal)
+vec3 line_plane_intersect(vec3 line_origin,
+ vec3 line_direction,
+ vec3 plane_origin,
+ vec3 plane_normal)
{
- float dist = line_plane_intersect_dist(lineorigin, linedirection, planeorigin, planenormal);
- return lineorigin + linedirection * dist;
+ float dist = line_plane_intersect_dist(line_origin, line_direction, plane_origin, plane_normal);
+ return line_origin + line_direction * dist;
}
-vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec4 plane)
+vec3 line_plane_intersect(vec3 line_origin, vec3 line_direction, vec4 plane)
{
- float dist = line_plane_intersect_dist(lineorigin, linedirection, plane);
- return lineorigin + linedirection * dist;
+ float dist = line_plane_intersect_dist(line_origin, line_direction, plane);
+ return line_origin + line_direction * dist;
}
-float line_aligned_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec3 planeorigin)
+float line_aligned_plane_intersect_dist(vec3 line_origin, vec3 line_direction, vec3 plane_origin)
{
/* aligned plane normal */
- vec3 L = planeorigin - lineorigin;
- float diskdist = length(L);
- vec3 planenormal = -normalize(L);
- return -diskdist / dot(planenormal, linedirection);
+ vec3 L = plane_origin - line_origin;
+ float disk_dist = length(L);
+ vec3 plane_normal = -normalize(L);
+ return -disk_dist / dot(plane_normal, line_direction);
}
-vec3 line_aligned_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin)
+vec3 line_aligned_plane_intersect(vec3 line_origin, vec3 line_direction, vec3 plane_origin)
{
- float dist = line_aligned_plane_intersect_dist(lineorigin, linedirection, planeorigin);
+ float dist = line_aligned_plane_intersect_dist(line_origin, line_direction, plane_origin);
if (dist < 0) {
/* if intersection is behind we fake the intersection to be
* really far and (hopefully) not inside the radius of interest */
dist = 1e16;
}
- return lineorigin + linedirection * dist;
+ return line_origin + line_direction * dist;
}
-float line_unit_sphere_intersect_dist(vec3 lineorigin, vec3 linedirection)
+/**
+ * Returns intersection distance between the unit sphere and the line
+ * with the assumption that \a line_origin is contained in the unit sphere.
+ * It will always returns the farthest intersection.
+ */
+float line_unit_sphere_intersect_dist(vec3 line_origin, vec3 line_direction)
{
- float a = dot(linedirection, linedirection);
- float b = dot(linedirection, lineorigin);
- float c = dot(lineorigin, lineorigin) - 1;
+ float a = dot(line_direction, line_direction);
+ float b = dot(line_direction, line_origin);
+ float c = dot(line_origin, line_origin) - 1;
float dist = 1e15;
float determinant = b * b - a * c;
@@ -72,22 +97,63 @@ float line_unit_sphere_intersect_dist(vec3 lineorigin, vec3 linedirection)
return dist;
}
-float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection)
+/**
+ * Returns minimum intersection distance between the unit box and the line
+ * with the assumption that \a line_origin is contained in the unit box.
+ * In other words, it will always returns the farthest intersection.
+ */
+float line_unit_box_intersect_dist(vec3 line_origin, vec3 line_direction)
{
/* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
*/
- vec3 firstplane = (vec3(1.0) - lineorigin) / linedirection;
- vec3 secondplane = (vec3(-1.0) - lineorigin) / linedirection;
- vec3 furthestplane = max(firstplane, secondplane);
+ vec3 first_plane = (vec3(1.0) - line_origin) / line_direction;
+ vec3 second_plane = (vec3(-1.0) - line_origin) / line_direction;
+ vec3 farthest_plane = max(first_plane, second_plane);
+
+ return min_v3(farthest_plane);
+}
+
+float line_unit_box_intersect_dist_safe(vec3 line_origin, vec3 line_direction)
+{
+ vec3 safe_line_direction = max(vec3(1e-8), abs(line_direction)) *
+ select(vec3(1.0), -vec3(1.0), lessThan(line_direction, vec3(0.0)));
+ return line_unit_box_intersect_dist(line_origin, safe_line_direction);
+}
+
+/**
+ * Same as line_unit_box_intersect_dist but for 2D case.
+ */
+float line_unit_square_intersect_dist(vec2 line_origin, vec2 line_direction)
+{
+ vec2 first_plane = (vec2(1.0) - line_origin) / line_direction;
+ vec2 second_plane = (vec2(-1.0) - line_origin) / line_direction;
+ vec2 farthest_plane = max(first_plane, second_plane);
- return min_v3(furthestplane);
+ return min_v2(farthest_plane);
}
-float line_unit_box_intersect_dist_safe(vec3 lineorigin, vec3 linedirection)
+float line_unit_square_intersect_dist_safe(vec2 line_origin, vec2 line_direction)
{
- vec3 safe_linedirection = max(vec3(1e-8), abs(linedirection)) *
- select(vec3(1.0), -vec3(1.0), lessThan(linedirection, vec3(0.0)));
- return line_unit_box_intersect_dist(lineorigin, safe_linedirection);
+ vec2 safe_line_direction = max(vec2(1e-8), abs(line_direction)) *
+ select(vec2(1.0), -vec2(1.0), lessThan(line_direction, vec2(0.0)));
+ return line_unit_square_intersect_dist(line_origin, safe_line_direction);
+}
+
+/**
+ * Returns clipping distance (intersection with the nearest plane) with the given axis-aligned
+ * bound box along \a line_direction.
+ * Safe even if \a line_direction is degenerate.
+ * It assumes that an intersection exists (i.e: that \a line_direction points towards the AABB).
+ */
+float line_aabb_clipping_dist(vec3 line_origin, vec3 line_direction, vec3 aabb_min, vec3 aabb_max)
+{
+ vec3 safe_dir = select(line_direction, vec3(1e-5), lessThan(abs(line_direction), vec3(1e-5)));
+ vec3 dir_inv = 1.0 / safe_dir;
+
+ vec3 first_plane = (aabb_min - line_origin) * dir_inv;
+ vec3 second_plane = (aabb_max - line_origin) * dir_inv;
+ vec3 nearest_plane = min(first_plane, second_plane);
+ return max_v3(nearest_plane);
}
/** \} */
@@ -98,8 +164,8 @@ float line_unit_box_intersect_dist_safe(vec3 lineorigin, vec3 linedirection)
void make_orthonormal_basis(vec3 N, out vec3 T, out vec3 B)
{
- vec3 UpVector = abs(N.z) < 0.99999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
- T = normalize(cross(UpVector, N));
+ vec3 up_vector = abs(N.z) < 0.99999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
+ T = normalize(cross(up_vector, N));
B = cross(N, T);
}