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