From c0fe6750cc0462adbc2165ac7f8c9cf1e0aea925 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 30 Oct 2014 17:59:44 -0400 Subject: intersection test --- .../javascripts/rectangles/engine/rooms/mover.js | 95 ++++++++++++++++------ 1 file changed, 71 insertions(+), 24 deletions(-) (limited to 'public/assets/javascripts/rectangles') diff --git a/public/assets/javascripts/rectangles/engine/rooms/mover.js b/public/assets/javascripts/rectangles/engine/rooms/mover.js index 121ecec..8ce00fe 100644 --- a/public/assets/javascripts/rectangles/engine/rooms/mover.js +++ b/public/assets/javascripts/rectangles/engine/rooms/mover.js @@ -36,6 +36,18 @@ Rooms.mover = new function(){ // check if we've breached one of the walls.. clamp position if so var collision = base.room.collidesDisc(cam, pos, radius) + if (collision && ! base.noclip) { + cam.x = (collision & LEFT_RIGHT) ? base.room.rect.x.clampDisc(pos.x, radius) : pos.x + cam.z = (collision & FRONT_BACK) ? base.room.rect.y.clampDisc(pos.z, radius) : pos.z + return + } + + // in this case, we appear to have left the room.. + // $(".face.active").removeClass("active") + Walls.clearBodyColor() + base.room = null + } + /* var dz = new vec2( cam.z, pos.z ) dz.normalize() @@ -43,47 +55,82 @@ Rooms.mover = new function(){ var dx = new vec2( cam.x, pos.x ) dx.normalize() + // first check if the cam-pos movement intersects the wall. + // next check if it intersects any of the surface frames + // if we can pass through the wall at this point, we do not need to clamp. + // otherwise, get the distance along the cam-pos vector where we would hit the wall and clamp to it. Walls.list.forEach(function(wall){ + var t = -1 switch (wall.side) { case FRONT: + if (cam.z >= wall.edge + radius && wall.edge + radius >= pos.z && wall.vec.intersects(dx) ) { + t = check_intersection( front_back_intersection, cam, pos, dx, wall, radius ) + } break case BACK: + // console.log(cam.z|0, wall.edge-radius, pos.z|0, wall.vec.intersects(dx)) + if (cam.z <= wall.edge - radius && wall.edge - radius <= pos.z && wall.vec.intersects(dx) ) { + t = check_intersection( front_back_intersection, cam, pos, dx, wall, -radius ) + console.log(t) + } break case LEFT: - if (cam.x >= wall.edge + radius && wall.edge + radius >= pos.x && (wall.vec.intersects(dz) ) { - // intersects the wall.. next check if it intersects any of the surface frames - wall.surface.faces.some(function(face, i){ - // if we can pass through the wall at this point, we do not need to clamp - if (face.y.a === 0 && face.x.intersects(dz)) { - dz.a = pos.z = face.x.clamp(pos.z) - dz.b = cam.z - dz.normalize() - return true - } - }) + if (cam.x >= wall.edge + radius && wall.edge + radius >= pos.x && wall.vec.intersects(dz) ) { + t = check_intersection( left_right_intersection, cam, pos, dz, wall, radius ) } break case RIGHT: - if (cam.x <= wall.edge - radius && wall.edge - radius <= pos.x && (wall.vec.contains(cam.z) || wall.vec.contains(pos.z)) ) { - // intersects + if (cam.x <= wall.edge - radius && wall.edge - radius <= pos.x && wall.vec.intersects(dz) ) { + t = check_intersection( left_right_intersection, cam, pos, dz, wall, -radius ) } break } + if (0 <= t && t <= 1) { + pos.x = cam.x + (pos.x - cam.x) * t + pos.z = cam.z + (pos.z - cam.z) * t + + dz = new vec2( cam.z, pos.z ) + dz.normalize() + + dx = new vec2( cam.x, pos.x ) + dx.normalize() + } }) -*/ - if (collision && ! base.noclip) { - cam.x = (collision & LEFT_RIGHT) ? base.room.rect.x.clampDisc(pos.x, radius) : pos.x - cam.z = (collision & FRONT_BACK) ? base.room.rect.y.clampDisc(pos.z, radius) : pos.z - return - } + function check_intersection(intersection_function, cam, pos, cam_pos_vector, wall, radius) { + var t = -1 + wall.surface.faces.some(function(face, i){ + if (face.y.a == 0 && face.x.intersects(cam_pos_vector)) { + t = intersection_function( cam, pos, wall, face, radius ) + console.log(">>", t) + if (0 <= t && t <= 1) { + return true + } + else { + t = -1 + } + } + return false + }) + return t + } + function left_right_intersection (cam, pos, wall, face, radius) { + var perp_n = (face.x.a - face.x.b) * (wall.edge - cam.z + radius) + var perp_d = (face.x.a - face.x.b) * (pos.z - cam.z) + if (perp_d == 0) return Infinity + return perp_n / perp_d + } + function front_back_intersection (cam, pos, wall, face, radius) { + // va.vx*vb.vy - va.vy*vb.vx + var perp_n = (face.x.b - face.x.a) * (wall.edge - cam.x + radius) + var perp_d = (face.x.b - face.x.a) * (pos.x - cam.x) - // in this case, we appear to have left the room.. - // $(".face.active").removeClass("active") - Walls.clearBodyColor() - base.room = null - } + console.log((pos.x - cam.x), wall.edge - cam.x, radius) + if (perp_d == 0) return Infinity + return perp_n / perp_d + } +*/ // collision test failed, so update position cam.x = pos.x cam.z = pos.z -- cgit v1.2.3-70-g09d2 From 2c2c70965efb50b500799ae7966a42e86bbac480 Mon Sep 17 00:00:00 2001 From: Julie Lala Date: Fri, 31 Oct 2014 10:18:39 -0400 Subject: fix floating point error :-P --- public/assets/javascripts/rectangles/models/rect.js | 6 ++++++ public/assets/javascripts/rectangles/models/vec2.js | 5 ++++- public/assets/test/intersect.html | 15 +++++++++++---- 3 files changed, 21 insertions(+), 5 deletions(-) (limited to 'public/assets/javascripts/rectangles') diff --git a/public/assets/javascripts/rectangles/models/rect.js b/public/assets/javascripts/rectangles/models/rect.js index 00f2c55..c667cf5 100644 --- a/public/assets/javascripts/rectangles/models/rect.js +++ b/public/assets/javascripts/rectangles/models/rect.js @@ -169,6 +169,12 @@ var s = "[" + this.x.toString() + " " + this.y.toString() + "] " + sides return s } + Rect.prototype.exactString = function(){ + var sides = sidesToString(this.sides) + var s = "[" + this.x.exactString() + " " + this.y.exactString() + "] " + sides + return s + } + Rect.prototype.serialize = function(){ return { x: this.x.serialize(), y: this.y.serialize() } } diff --git a/public/assets/javascripts/rectangles/models/vec2.js b/public/assets/javascripts/rectangles/models/vec2.js index 49613c3..f28df54 100644 --- a/public/assets/javascripts/rectangles/models/vec2.js +++ b/public/assets/javascripts/rectangles/models/vec2.js @@ -200,7 +200,10 @@ } vec2.prototype.toString = function(){ - return "[" + ~~this.a + " " + ~~this.b + "]" + return "[" + round(this.a) + " " + round(this.b) + "]" + } + vec2.prototype.exactString = function(){ + return "[" + this.a + " " + this.b + "]" } vec2.prototype.serialize = function(){ return [ ~~this.a, ~~this.b ] diff --git a/public/assets/test/intersect.html b/public/assets/test/intersect.html index 5e16f2e..4e5b0bb 100644 --- a/public/assets/test/intersect.html +++ b/public/assets/test/intersect.html @@ -1,4 +1,5 @@ +
@@ -73,16 +74,21 @@ function draw () { var collinear = is_collinear( intersect, vec_b ) var long_enough_to_intersect = 0 <= t && t <= 1 + var msg if (long_enough_to_intersect && collinear) { ctx.fillStyle = "#f00" + msg = "through" } else if (collinear) { ctx.fillStyle = "#0f0" + msg = "to" } else { ctx.fillStyle = "#000" + msg = "off" } + hud.innerHTML = [intersect.exactString(), vec_b.exactString(), msg].join("
") drawPoint(intersect) } @@ -105,19 +111,20 @@ function perp (va, vb) { } function is_collinear (p, vec) { var on_x, on_y + var pa = round(p.a), pb = round(p.b) if (vec.x.a < vec.y.a) { - on_x = vec.x.a <= p.a && p.a <= vec.y.a + on_x = vec.x.a <= pa && pa <= vec.y.a } else { - on_x = vec.x.a >= p.a && p.a >= vec.y.a + on_x = vec.x.a >= pa && pa >= vec.y.a } if (vec.x.b < vec.y.b) { - on_y = vec.x.b <= p.b && p.b <= vec.y.b + on_y = vec.x.b <= pb && pb <= vec.y.b } else { - on_y = vec.x.b >= p.b && p.b >= vec.y.b + on_y = vec.x.b >= pb && pb >= vec.y.b } return !! (on_x && on_y) -- cgit v1.2.3-70-g09d2 From f599c7edf7e635241e839fc024e4016ae0dcc210 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 31 Oct 2014 16:03:12 -0400 Subject: intersection test 2 - hit-testing on wall structure --- .../javascripts/rectangles/models/surface.js | 9 + public/assets/test/intersect2.html | 218 +++++++++++++++++++++ 2 files changed, 227 insertions(+) create mode 100644 public/assets/test/intersect2.html (limited to 'public/assets/javascripts/rectangles') diff --git a/public/assets/javascripts/rectangles/models/surface.js b/public/assets/javascripts/rectangles/models/surface.js index 3a6c449..fc4aae4 100644 --- a/public/assets/javascripts/rectangles/models/surface.js +++ b/public/assets/javascripts/rectangles/models/surface.js @@ -154,6 +154,15 @@ } return -1 } + Surface.prototype.face_for_x = function(x, min_i){ + min_i = min_i || 0 + for (var i = min_i; i < this.faces.length; i++) { + if (this.faces[i].x.contains(x)) { + return this.faces[i] + } + } + return null + } Surface.prototype.bounds_at_index_with_dimensions = function(index, dimensions){ var faces = this.faces diff --git a/public/assets/test/intersect2.html b/public/assets/test/intersect2.html new file mode 100644 index 0000000..fade288 --- /dev/null +++ b/public/assets/test/intersect2.html @@ -0,0 +1,218 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3-70-g09d2