~ | Cylinder fixed

This commit is contained in:
TheRedShip
2025-01-11 14:47:23 +01:00
parent bb56f096c8
commit ec30084d6f
2 changed files with 44 additions and 51 deletions

View File

@ -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

View File

@ -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)