rayzor
diff src/object.cc @ 17:79609d482762
the renderer renders, also fixed an unnoticed matrix conversion problem between scenegraph and min3d
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 14 Apr 2014 07:34:45 +0300 |
parents | a9a948809c6f |
children |
line diff
1.1 --- a/src/object.cc Sun Apr 13 09:54:51 2014 +0300 1.2 +++ b/src/object.cc Mon Apr 14 07:34:45 2014 +0300 1.3 @@ -13,6 +13,11 @@ 1.4 { 1.5 } 1.6 1.7 +Vector3 Object::hit_normal(const RayHit &hit) const 1.8 +{ 1.9 + return Vector3(0, 0, 0); 1.10 +} 1.11 + 1.12 // ---- sphere ---- 1.13 Sphere::Sphere() 1.14 { 1.15 @@ -83,7 +88,7 @@ 1.16 post_draw(); 1.17 } 1.18 1.19 -bool Sphere::intersect(const Ray &wray, float *dist) const 1.20 +bool Sphere::intersect(const Ray &wray, RayHit *hit) const 1.21 { 1.22 Ray ray = transform(get_inv_matrix(), wray); 1.23 1.24 @@ -111,10 +116,21 @@ 1.25 if(t < 1e-4) 1.26 return false; 1.27 1.28 - if(dist) *dist = t; 1.29 + if(hit) { 1.30 + hit->ray = wray; 1.31 + hit->lray = ray; 1.32 + hit->dist = t; 1.33 + hit->obj = this; 1.34 + hit->subobj = 0; 1.35 + } 1.36 return true; 1.37 } 1.38 1.39 +Vector3 Sphere::hit_normal(const RayHit &hit) const 1.40 +{ 1.41 + return hit.lray.origin + hit.lray.dir * hit.dist; 1.42 +} 1.43 + 1.44 // ---- box ---- 1.45 1.46 Box::Box() 1.47 @@ -165,7 +181,57 @@ 1.48 post_draw(); 1.49 } 1.50 1.51 -bool Box::intersect(const Ray &ray, float *dist) const 1.52 +bool Box::intersect(const Ray &wray, RayHit *hit) const 1.53 { 1.54 - return false; // TODO 1.55 + Ray ray = transform(get_inv_matrix(), wray); 1.56 + 1.57 + Vector3 param[2] = { Vector3(-1, -1, -1), Vector3(1, 1, 1) }; 1.58 + Vector3 inv_dir(1.0 / ray.dir.x, 1.0 / ray.dir.y, 1.0 / ray.dir.z); 1.59 + int sign[3] = {inv_dir.x < 0, inv_dir.y < 0, inv_dir.z < 0}; 1.60 + 1.61 + float tmin = (param[sign[0]].x - ray.origin.x) * inv_dir.x; 1.62 + float tmax = (param[1 - sign[0]].x - ray.origin.x) * inv_dir.x; 1.63 + float tymin = (param[sign[1]].y - ray.origin.y) * inv_dir.y; 1.64 + float tymax = (param[1 - sign[1]].y - ray.origin.y) * inv_dir.y; 1.65 + 1.66 + if(tmin > tymax || tymin > tmax) { 1.67 + return false; 1.68 + } 1.69 + if(tymin > tmin) tmin = tymin; 1.70 + if(tymax < tmax) tmax = tymax; 1.71 + 1.72 + float tzmin = (param[sign[2]].z - ray.origin.z) * inv_dir.z; 1.73 + float tzmax = (param[1 - sign[2]].z - ray.origin.z) * inv_dir.z; 1.74 + 1.75 + if(tmin > tzmax || tzmin > tmax) { 1.76 + return false; 1.77 + } 1.78 + if(tzmin > tmin) tmin = tzmin; 1.79 + if(tzmax < tmax) tmax = tzmax; 1.80 + 1.81 + float t = tmin < 1e-4 ? tmax : tmin; 1.82 + if(t >= 1e-4) { 1.83 + if(hit) { 1.84 + hit->dist = t; 1.85 + hit->ray = wray; 1.86 + hit->lray = ray; 1.87 + hit->obj = this; 1.88 + hit->subobj = 0; 1.89 + } 1.90 + return true; 1.91 + } 1.92 + return false; 1.93 } 1.94 + 1.95 +Vector3 Box::hit_normal(const RayHit &hit) const 1.96 +{ 1.97 + Vector3 lpt = hit.lray.origin + hit.lray.dir * hit.dist; 1.98 + 1.99 + if(fabs(lpt.x) > fabs(lpt.y) && fabs(lpt.x) > fabs(lpt.z)) { 1.100 + return Vector3(lpt.x, 0, 0); 1.101 + } 1.102 + if(fabs(lpt.y) > fabs(lpt.z)) { 1.103 + return Vector3(0, lpt.y, 0); 1.104 + } 1.105 + return Vector3(0, 0, lpt.z); 1.106 +}