erebus

changeset 18:09028848f276

- implemented Box object intersection - implemented interactive camera manipulation
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 26 May 2014 23:34:12 +0300
parents e9da2916bc79
children 6204e4d3f445
files liberebus/src/erebus.cc liberebus/src/geomobj.cc liberebus/src/geomobj.h liberebus/src/rt.cc
diffstat 4 files changed, 105 insertions(+), 9 deletions(-) [+]
line diff
     1.1 --- a/liberebus/src/erebus.cc	Mon May 26 05:41:28 2014 +0300
     1.2 +++ b/liberebus/src/erebus.cc	Mon May 26 23:34:12 2014 +0300
     1.3 @@ -210,13 +210,13 @@
     1.4  	ctx->scn->add_object(sph);
     1.5  	ctx->scn->add_node(sph_node);
     1.6  
     1.7 -	sph = new Sphere;
     1.8 -	sph->mtl.set_attrib("diffuse", Color(0.3, 0.4, 1.0));
     1.9 -	sph_node = new SceneNode(sph);
    1.10 -	sph_node->set_position(Vector3(0, -251.0, 0));
    1.11 -	sph_node->set_scaling(Vector3(250.0, 250.0, 250.0));
    1.12 -	ctx->scn->add_object(sph);
    1.13 -	ctx->scn->add_node(sph_node);
    1.14 +	Box *box = new Box;
    1.15 +	box->mtl.set_attrib("diffuse", Color(0.9, 0.8, 0.75));
    1.16 +	SceneNode *box_node = new SceneNode(box);
    1.17 +	box_node->set_position(Vector3(0, -1.25, 0));
    1.18 +	box_node->set_scaling(Vector3(5, 0.5, 5));
    1.19 +	ctx->scn->add_object(box);
    1.20 +	ctx->scn->add_node(box_node);
    1.21  
    1.22  	Sphere *lt = new Sphere;
    1.23  	lt->mtl.set_attrib("emissive", Color(10, 10, 10));
    1.24 @@ -304,11 +304,38 @@
    1.25  
    1.26  bool erb_input_mouse_motion(struct erebus *ctx, int x, int y)
    1.27  {
    1.28 -	if(!ctx) return false;
    1.29 +	bool res = false;
    1.30 +
    1.31 +	if(!ctx) return res;
    1.32 +
    1.33 +	int dx = x - ctx->mouse_pos[0];
    1.34 +	int dy = y - ctx->mouse_pos[1];
    1.35 +
    1.36 +	if(dx || dy) {
    1.37 +		TargetCamera *cam = (TargetCamera*)ctx->scn->get_active_camera();
    1.38 +		if(cam && ctx->bnstate[0]) {
    1.39 +			Vector3 cpos = cam->get_position();
    1.40 +			float mag = cpos.length();
    1.41 +
    1.42 +			float theta = atan2(cpos.z / mag, cpos.x / mag) + DEG_TO_RAD(dx * 0.5);
    1.43 +			float phi = acos(cpos.y / mag) + DEG_TO_RAD(dy * 0.5);
    1.44 +
    1.45 +			if(phi < 0) phi = 0;
    1.46 +			if(phi > M_PI) phi = M_PI;
    1.47 +
    1.48 +			cpos.x = cos(theta) * sin(phi) * mag;
    1.49 +			cpos.y = cos(phi) * mag;
    1.50 +			cpos.z = sin(theta) * sin(phi) * mag;
    1.51 +			cam->set_position(cpos);
    1.52 +
    1.53 +			erb_begin_frame(ctx, 0);
    1.54 +			res = true;
    1.55 +		}
    1.56 +	}
    1.57  
    1.58  	ctx->mouse_pos[0] = x;
    1.59  	ctx->mouse_pos[1] = y;
    1.60 -	return false;
    1.61 +	return res;
    1.62  }
    1.63  
    1.64  bool erb_input_6dof_button(struct erebus *ctx, int bn, bool pressed)
     2.1 --- a/liberebus/src/geomobj.cc	Mon May 26 05:41:28 2014 +0300
     2.2 +++ b/liberebus/src/geomobj.cc	Mon May 26 23:34:12 2014 +0300
     2.3 @@ -102,7 +102,71 @@
     2.4  
     2.5  bool Box::intersect(const Ray &ray, RayHit *hit) const
     2.6  {
     2.7 +	Vector3 param[2] = {Vector3{-0.5, -0.5, -0.5}, Vector3{0.5, 0.5, 0.5}};
     2.8 +	Vector3 inv_dir{1.0f / ray.dir.x, 1.0f / ray.dir.y, 1.0f / ray.dir.z};
     2.9 +	int sign[3] = {inv_dir.x < 0, inv_dir.y < 0, inv_dir.z < 0};
    2.10 +
    2.11 +	float tmin = (param[sign[0]].x - ray.origin.x) * inv_dir.x;
    2.12 +	float tmax = (param[1 - sign[0]].x - ray.origin.x) * inv_dir.x;
    2.13 +	float tymin = (param[sign[1]].y - ray.origin.y) * inv_dir.y;
    2.14 +	float tymax = (param[1 - sign[1]].y - ray.origin.y) * inv_dir.y;
    2.15 +
    2.16 +	if(tmin > tymax || tymin > tmax) {
    2.17 +		return false;
    2.18 +	}
    2.19 +	if(tymin > tmin) {
    2.20 +		tmin = tymin;
    2.21 +	}
    2.22 +	if(tymax < tmax) {
    2.23 +		tmax = tymax;
    2.24 +	}
    2.25 +
    2.26 +	float tzmin = (param[sign[2]].z - ray.origin.z) * inv_dir.z;
    2.27 +	float tzmax = (param[1 - sign[2]].z - ray.origin.z) * inv_dir.z;
    2.28 +
    2.29 +	if(tmin > tzmax || tzmin > tmax) {
    2.30 +		return false;
    2.31 +	}
    2.32 +	if(tzmin > tmin) {
    2.33 +		tmin = tzmin;
    2.34 +	}
    2.35 +	if(tzmax < tmax) {
    2.36 +		tmax = tzmax;
    2.37 +	}
    2.38 +
    2.39 +	float t = tmin < 1e-4 ? tmax : tmin;
    2.40 +	if(t >= 1e-4) {
    2.41 +		if(hit) {
    2.42 +			hit->obj = this;
    2.43 +			hit->dist = t;
    2.44 +		}
    2.45 +		return true;
    2.46 +	}
    2.47  	return false;
    2.48 +
    2.49 +}
    2.50 +
    2.51 +#define BOX_EXT		0.499999
    2.52 +Vector3 Box::calc_normal(const RayHit &hit) const
    2.53 +{
    2.54 +	Vector3 pt = hit.local_ray.origin + hit.local_ray.dir * hit.dist;
    2.55 +	if(pt.x > BOX_EXT) return Vector3(1, 0, 0);
    2.56 +	if(pt.x < -BOX_EXT) return Vector3(-1, 0, 0);
    2.57 +	if(pt.y > BOX_EXT) return Vector3(0, 1, 0);
    2.58 +	if(pt.y < -BOX_EXT) return Vector3(0, -1, 0);
    2.59 +	if(pt.z > BOX_EXT) return Vector3(0, 0, 1);
    2.60 +	if(pt.z < -BOX_EXT) return Vector3(0, 0, -1);
    2.61 +	return Vector3(0, 0, 0);	// shouldn't happen unless numerical precision is fucked
    2.62 +}
    2.63 +
    2.64 +Vector3 Box::calc_tangent(const RayHit &hit) const
    2.65 +{
    2.66 +	return Vector3(1, 0, 0);	// TODO
    2.67 +}
    2.68 +
    2.69 +Vector2 Box::calc_texcoords(const RayHit &hit) const
    2.70 +{
    2.71 +	return Vector2(0, 0);	// TODO
    2.72  }
    2.73  
    2.74  // --- class Triangle ---
     3.1 --- a/liberebus/src/geomobj.h	Mon May 26 05:41:28 2014 +0300
     3.2 +++ b/liberebus/src/geomobj.h	Mon May 26 23:34:12 2014 +0300
     3.3 @@ -34,6 +34,10 @@
     3.4  class Box : public GeomObject {
     3.5  public:
     3.6  	bool intersect(const Ray &ray, RayHit *hit = 0) const override;
     3.7 +
     3.8 +	Vector3 calc_normal(const RayHit &hit) const override;
     3.9 +	Vector3 calc_tangent(const RayHit &hit) const override;
    3.10 +	Vector2 calc_texcoords(const RayHit &hit) const override;
    3.11  };
    3.12  
    3.13  class Triangle : public GeomObject {
     4.1 --- a/liberebus/src/rt.cc	Mon May 26 05:41:28 2014 +0300
     4.2 +++ b/liberebus/src/rt.cc	Mon May 26 23:34:12 2014 +0300
     4.3 @@ -30,6 +30,7 @@
     4.4  	const Ray &ray = hit.world_ray;
     4.5  
     4.6  	Vector3 norm = hit.calc_normal();
     4.7 +	//return norm * 0.5 + Vector3(0.5, 0.5, 0.5);
     4.8  	Vector2 texcoords = hit.calc_texcoords();
     4.9  
    4.10  	Color color = mtl->get_attrib_color("diffuse", texcoords.x, texcoords.y);