#include "dxstdafx.h" #include "cylinder.h" bool Cylinder::intersectBackSide (const Ray& ray, float& depth, float rayMin, float rayMax) { return false; } bool Cylinder::intersect (const Ray& ray, float& depth, float rayMin, float rayMax) { lastTestedRayId = ray.id; lastTestedRayResult.isIntersect = false; Vector diff = (ray.origin - centre); diff.y = 0.0f; float b = 2.0f * (ray.dir * diff); float c = diff * diff - radius * radius; float a = ray.dir.x * ray.dir.x + ray.dir.z * ray.dir.z; float discriminant = b * b - 4.0f * a * c; if(discriminant < 0.0f) return false; else { float sqrtdisc = sqrtf(discriminant); float depth1 = (-b - sqrtdisc) * 0.5f / a; if(ray.origin.y + depth1 * ray.dir.y < top) { if(ray.origin.y + depth1 * ray.dir.y > bottom) { depth = depth1; lastTestedRayResult.isIntersect = true; lastTestedRayResult.material = this->material; lastTestedRayResult.depth = depth; lastTestedRayResult.point = ray.origin + ray.dir * depth; lastTestedRayResult.object = this; lastTestedRayResult.normal.setDifference(lastTestedRayResult.point, centre); lastTestedRayResult.normal.y = 0.0f; lastTestedRayResult.normal *= 1.0f / radius; return true; } else { float depth2 = (-b + sqrtdisc) * 0.5f / a; float h = (bottom - ray.origin.y) / ray.dir.y; if( h > depth1 && h < depth2) { depth = h; lastTestedRayResult.normal = Vector(0.0f, -1.0f, 0.0f); } else return false; } } else { float depth2 = (-b + sqrtdisc) * 0.5f / a; float h = (top - ray.origin.y) / ray.dir.y; if( h > depth1 && h < depth2) { depth = h; lastTestedRayResult.normal = Vector(0.0f, 1.0f, 0.0f); } else return false; } lastTestedRayResult.isIntersect = true; lastTestedRayResult.material = this->material; lastTestedRayResult.depth = depth; lastTestedRayResult.point = ray.origin + ray.dir * depth; lastTestedRayResult.object = this; return true; } }