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 +}