mirror of
https://github.com/TheRedShip/RT_GPU.git
synced 2025-09-27 10:48:34 +02:00
~ | Cylinder fixed
This commit is contained in:
@ -2,7 +2,7 @@ CAM 1.43879 3.42554 1.94198 -44.6001 -139.599 0 4 90 5
|
|||||||
|
|
||||||
|
|
||||||
MAT 200 200 200 0.0 0.0 0.0 //white
|
MAT 200 200 200 0.0 0.0 0.0 //white
|
||||||
MAT 255 50 50 0.0 1.0 0.0 //red
|
MAT 255 50 50 0.0 1.0 0.05 //red
|
||||||
MAT 50 255 50 0.0 0.0 0.0 //green
|
MAT 50 255 50 0.0 0.0 0.0 //green
|
||||||
MAT 100 100 255 0.0 0.0 0.0 //blue
|
MAT 100 100 255 0.0 0.0 0.0 //blue
|
||||||
MAT 255 100 255 0.0 0.0 0.0 //purple
|
MAT 255 100 255 0.0 0.0 0.0 //purple
|
||||||
|
@ -154,56 +154,49 @@ bool intersectCylinder(Ray ray, GPUObject obj, out hitInfo hit)
|
|||||||
float radius = obj.normal.x;
|
float radius = obj.normal.x;
|
||||||
float height = obj.normal.y;
|
float height = obj.normal.y;
|
||||||
|
|
||||||
vec3 p = ray.origin - obj.position;
|
vec3 rayOrigin = mat3(obj.rotation) * (ray.origin - obj.position);
|
||||||
|
vec3 rayDir = mat3(obj.rotation) * ray.direction;
|
||||||
vec3 d = ray.direction * mat3(obj.rotation);
|
|
||||||
p = p * mat3(obj.rotation);
|
float halfHeight = height * 0.5;
|
||||||
|
float radius2 = radius * radius;
|
||||||
float half_height = height * 0.5;
|
|
||||||
|
vec2 oc_xz = rayOrigin.xz;
|
||||||
float a = d.x * d.x + d.z * d.z;
|
vec2 rd_xz = rayDir.xz;
|
||||||
float b = p.x * d.x + p.z * d.z;
|
float a = dot(rd_xz, rd_xz);
|
||||||
float c = p.x * p.x + p.z * p.z - radius * radius;
|
float b = dot(oc_xz, rd_xz);
|
||||||
|
float c = dot(oc_xz, oc_xz) - radius2;
|
||||||
float h = b * b - a * c;
|
|
||||||
if (h < 0.0) return false;
|
float h = b * b - a * c;
|
||||||
|
if (h < 0.0) return (false);
|
||||||
float sqrt_h = sqrt(h);
|
|
||||||
float t = (-b - sqrt_h) / a;
|
float t_cyl = (-b - sqrt(h)) / a;
|
||||||
|
float y = rayOrigin.y + t_cyl * rayDir.y;
|
||||||
if (t <= 0.0)
|
|
||||||
{
|
t_cyl = mix((-b + sqrt(h)) / a, t_cyl,
|
||||||
t = (-b + sqrt_h) / a;
|
float(abs(y) <= halfHeight && t_cyl > 0.0));
|
||||||
if (t <= 0.0) return false;
|
y = rayOrigin.y + t_cyl * rayDir.y;
|
||||||
}
|
|
||||||
|
float invRayDirY = 1.0 / rayDir.y;
|
||||||
float y = p.y + t * d.y;
|
float t_cap = (-sign(rayDir.y) * halfHeight - rayOrigin.y) * invRayDirY;
|
||||||
|
vec2 cap_xz = rayOrigin.xz + t_cap * rayDir.xz;
|
||||||
if (abs(y) <= half_height)
|
bool cap_valid = (dot(cap_xz, cap_xz) <= radius2) && (t_cap > 0.0);
|
||||||
{
|
|
||||||
|
bool cyl_valid = abs(y) <= halfHeight && t_cyl > 0.0;
|
||||||
hit.t = t;
|
float t = mix(t_cap, t_cyl, float(cyl_valid && (t_cyl < t_cap || !cap_valid)));
|
||||||
hit.position = ray.origin + ray.direction * t;
|
|
||||||
|
if (!cyl_valid && !cap_valid) return (false);
|
||||||
vec3 local_normal = vec3(p.x + t * d.x, 0.0, p.z + t * d.z);
|
|
||||||
hit.normal = normalize(local_normal * inverse(mat3(obj.rotation)));
|
vec3 p = rayOrigin + t * rayDir;
|
||||||
return true;
|
|
||||||
}
|
vec3 n_side = normalize(vec3(p.x, 0.0, p.z));
|
||||||
|
vec3 n_cap = vec3(0.0, -sign(rayDir.y), 0.0);
|
||||||
float cap_t = (sign(y) * half_height - p.y) / d.y;
|
vec3 normal = mix(n_cap, n_side, float(cyl_valid && (t_cyl < t_cap || !cap_valid)));
|
||||||
if (cap_t <= 0.0) return false;
|
|
||||||
|
hit.t = t;
|
||||||
float cap_x = p.x + cap_t * d.x;
|
hit.position = ray.origin + ray.direction * t;
|
||||||
float cap_z = p.z + cap_t * d.z;
|
hit.normal = normalize(transpose(mat3(obj.rotation)) * normal);
|
||||||
if (cap_x * cap_x + cap_z * cap_z > radius * radius) return false;
|
|
||||||
|
return (true);
|
||||||
hit.t = cap_t;
|
|
||||||
hit.position = ray.origin + ray.direction * cap_t;
|
|
||||||
|
|
||||||
|
|
||||||
vec3 cap_normal = vec3(0.0, sign(y), 0.0);
|
|
||||||
hit.normal = normalize(cap_normal * inverse(mat3(obj.rotation)));
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool intersect(Ray ray, GPUObject obj, out hitInfo hit)
|
bool intersect(Ray ray, GPUObject obj, out hitInfo hit)
|
||||||
|
Reference in New Issue
Block a user