# HG changeset patch # User John Tsiombikas # Date 1401136452 -10800 # Node ID 09028848f276d4a94a31f916f7a14a36bd454848 # Parent e9da2916bc79e54e6aaab529b6bc70a1235b1cb6 - implemented Box object intersection - implemented interactive camera manipulation diff -r e9da2916bc79 -r 09028848f276 liberebus/src/erebus.cc --- a/liberebus/src/erebus.cc Mon May 26 05:41:28 2014 +0300 +++ b/liberebus/src/erebus.cc Mon May 26 23:34:12 2014 +0300 @@ -210,13 +210,13 @@ ctx->scn->add_object(sph); ctx->scn->add_node(sph_node); - sph = new Sphere; - sph->mtl.set_attrib("diffuse", Color(0.3, 0.4, 1.0)); - sph_node = new SceneNode(sph); - sph_node->set_position(Vector3(0, -251.0, 0)); - sph_node->set_scaling(Vector3(250.0, 250.0, 250.0)); - ctx->scn->add_object(sph); - ctx->scn->add_node(sph_node); + Box *box = new Box; + box->mtl.set_attrib("diffuse", Color(0.9, 0.8, 0.75)); + SceneNode *box_node = new SceneNode(box); + box_node->set_position(Vector3(0, -1.25, 0)); + box_node->set_scaling(Vector3(5, 0.5, 5)); + ctx->scn->add_object(box); + ctx->scn->add_node(box_node); Sphere *lt = new Sphere; lt->mtl.set_attrib("emissive", Color(10, 10, 10)); @@ -304,11 +304,38 @@ bool erb_input_mouse_motion(struct erebus *ctx, int x, int y) { - if(!ctx) return false; + bool res = false; + + if(!ctx) return res; + + int dx = x - ctx->mouse_pos[0]; + int dy = y - ctx->mouse_pos[1]; + + if(dx || dy) { + TargetCamera *cam = (TargetCamera*)ctx->scn->get_active_camera(); + if(cam && ctx->bnstate[0]) { + Vector3 cpos = cam->get_position(); + float mag = cpos.length(); + + float theta = atan2(cpos.z / mag, cpos.x / mag) + DEG_TO_RAD(dx * 0.5); + float phi = acos(cpos.y / mag) + DEG_TO_RAD(dy * 0.5); + + if(phi < 0) phi = 0; + if(phi > M_PI) phi = M_PI; + + cpos.x = cos(theta) * sin(phi) * mag; + cpos.y = cos(phi) * mag; + cpos.z = sin(theta) * sin(phi) * mag; + cam->set_position(cpos); + + erb_begin_frame(ctx, 0); + res = true; + } + } ctx->mouse_pos[0] = x; ctx->mouse_pos[1] = y; - return false; + return res; } bool erb_input_6dof_button(struct erebus *ctx, int bn, bool pressed) diff -r e9da2916bc79 -r 09028848f276 liberebus/src/geomobj.cc --- a/liberebus/src/geomobj.cc Mon May 26 05:41:28 2014 +0300 +++ b/liberebus/src/geomobj.cc Mon May 26 23:34:12 2014 +0300 @@ -102,7 +102,71 @@ bool Box::intersect(const Ray &ray, RayHit *hit) const { + Vector3 param[2] = {Vector3{-0.5, -0.5, -0.5}, Vector3{0.5, 0.5, 0.5}}; + Vector3 inv_dir{1.0f / ray.dir.x, 1.0f / ray.dir.y, 1.0f / ray.dir.z}; + int sign[3] = {inv_dir.x < 0, inv_dir.y < 0, inv_dir.z < 0}; + + float tmin = (param[sign[0]].x - ray.origin.x) * inv_dir.x; + float tmax = (param[1 - sign[0]].x - ray.origin.x) * inv_dir.x; + float tymin = (param[sign[1]].y - ray.origin.y) * inv_dir.y; + float tymax = (param[1 - sign[1]].y - ray.origin.y) * inv_dir.y; + + if(tmin > tymax || tymin > tmax) { + return false; + } + if(tymin > tmin) { + tmin = tymin; + } + if(tymax < tmax) { + tmax = tymax; + } + + float tzmin = (param[sign[2]].z - ray.origin.z) * inv_dir.z; + float tzmax = (param[1 - sign[2]].z - ray.origin.z) * inv_dir.z; + + if(tmin > tzmax || tzmin > tmax) { + return false; + } + if(tzmin > tmin) { + tmin = tzmin; + } + if(tzmax < tmax) { + tmax = tzmax; + } + + float t = tmin < 1e-4 ? tmax : tmin; + if(t >= 1e-4) { + if(hit) { + hit->obj = this; + hit->dist = t; + } + return true; + } return false; + +} + +#define BOX_EXT 0.499999 +Vector3 Box::calc_normal(const RayHit &hit) const +{ + Vector3 pt = hit.local_ray.origin + hit.local_ray.dir * hit.dist; + if(pt.x > BOX_EXT) return Vector3(1, 0, 0); + if(pt.x < -BOX_EXT) return Vector3(-1, 0, 0); + if(pt.y > BOX_EXT) return Vector3(0, 1, 0); + if(pt.y < -BOX_EXT) return Vector3(0, -1, 0); + if(pt.z > BOX_EXT) return Vector3(0, 0, 1); + if(pt.z < -BOX_EXT) return Vector3(0, 0, -1); + return Vector3(0, 0, 0); // shouldn't happen unless numerical precision is fucked +} + +Vector3 Box::calc_tangent(const RayHit &hit) const +{ + return Vector3(1, 0, 0); // TODO +} + +Vector2 Box::calc_texcoords(const RayHit &hit) const +{ + return Vector2(0, 0); // TODO } // --- class Triangle --- diff -r e9da2916bc79 -r 09028848f276 liberebus/src/geomobj.h --- a/liberebus/src/geomobj.h Mon May 26 05:41:28 2014 +0300 +++ b/liberebus/src/geomobj.h Mon May 26 23:34:12 2014 +0300 @@ -34,6 +34,10 @@ class Box : public GeomObject { public: bool intersect(const Ray &ray, RayHit *hit = 0) const override; + + Vector3 calc_normal(const RayHit &hit) const override; + Vector3 calc_tangent(const RayHit &hit) const override; + Vector2 calc_texcoords(const RayHit &hit) const override; }; class Triangle : public GeomObject { diff -r e9da2916bc79 -r 09028848f276 liberebus/src/rt.cc --- a/liberebus/src/rt.cc Mon May 26 05:41:28 2014 +0300 +++ b/liberebus/src/rt.cc Mon May 26 23:34:12 2014 +0300 @@ -30,6 +30,7 @@ const Ray &ray = hit.world_ray; Vector3 norm = hit.calc_normal(); + //return norm * 0.5 + Vector3(0.5, 0.5, 0.5); Vector2 texcoords = hit.calc_texcoords(); Color color = mtl->get_attrib_color("diffuse", texcoords.x, texcoords.y);