diff options
| author | ryderr <r@okfoc.us> | 2014-10-31 16:57:13 -0400 |
|---|---|---|
| committer | ryderr <r@okfoc.us> | 2014-10-31 16:57:13 -0400 |
| commit | 75e49fa6b145f56e4db14b69c8a32717b5bc7414 (patch) | |
| tree | a843ed780e0520e187d6b01024c69c3561b38c3f | |
| parent | 9a27ee2450fc718c23712a4c9dc63b5dd3b4e405 (diff) | |
| parent | 60e86d8be94281d06d5327d6dad46b98e5df6a62 (diff) | |
Merge branch 'master' of github.com:okfocus/vvalls
| -rw-r--r-- | public/assets/javascripts/rectangles/engine/rooms/mover.js | 95 | ||||
| -rw-r--r-- | public/assets/javascripts/rectangles/models/rect.js | 6 | ||||
| -rw-r--r-- | public/assets/javascripts/rectangles/models/surface.js | 9 | ||||
| -rw-r--r-- | public/assets/javascripts/rectangles/models/vec2.js | 5 | ||||
| -rw-r--r-- | public/assets/javascripts/ui/_router.js | 12 | ||||
| -rw-r--r-- | public/assets/javascripts/vendor/canvasutilities.js | 145 | ||||
| -rw-r--r-- | public/assets/test/intersect.html | 139 | ||||
| -rw-r--r-- | public/assets/test/intersect2.html | 218 |
8 files changed, 604 insertions, 25 deletions
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 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/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/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/javascripts/ui/_router.js b/public/assets/javascripts/ui/_router.js index 0c95664..d5a8e7f 100644 --- a/public/assets/javascripts/ui/_router.js +++ b/public/assets/javascripts/ui/_router.js @@ -18,6 +18,7 @@ var SiteRouter = Router.extend({ routes: { "/": 'home', + "/home": 'home', "/login": 'signin', "/signup": 'signup', @@ -45,7 +46,16 @@ var SiteRouter = Router.extend({ mobileRoutes: { "/": 'home', "/home": 'home', + "/login": 'signin', + "/signup": 'signup', + "/auth/usernameTaken": 'usernameTaken', + "/auth/password": 'passwordReset', + "/auth/forgotPassword": 'passwordForgot', + "/profile": 'profile', + "/profile/edit": 'editProfile', + "/profile/:name": 'profile', + "/project/:name": 'projectViewer', }, @@ -63,10 +73,12 @@ var SiteRouter = Router.extend({ this.route() + /* if (is_mobile) { $(".topLinks").hide() $(".share").hide() } + */ $("body").removeClass("loading") }, diff --git a/public/assets/javascripts/vendor/canvasutilities.js b/public/assets/javascripts/vendor/canvasutilities.js new file mode 100644 index 0000000..011ebb0 --- /dev/null +++ b/public/assets/javascripts/vendor/canvasutilities.js @@ -0,0 +1,145 @@ +var drawArrow = function(ctx, x1, y1, x2, y2, style, which, angle, d) { + 'use strict'; + // Ceason pointed to a problem when x1 or y1 were a string, and concatenation + // would happen instead of addition + if (typeof(x1) == 'string') x1 = parseInt(x1); + if (typeof(y1) == 'string') y1 = parseInt(y1); + if (typeof(x2) == 'string') x2 = parseInt(x2); + if (typeof(y2) == 'string') y2 = parseInt(y2); + style = typeof(style) != 'undefined' ? style : 3; + which = typeof(which) != 'undefined' ? which : 1; // end point gets arrow + angle = typeof(angle) != 'undefined' ? angle : Math.PI / 8; + d = typeof(d) != 'undefined' ? d : 10; + // default to using drawHead to draw the head, but if the style + // argument is a function, use it instead + var toDrawHead = typeof(style) != 'function' ? drawHead : style; + + // For ends with arrow we actually want to stop before we get to the arrow + // so that wide lines won't put a flat end on the arrow. + // + var dist = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); + var ratio = (dist - d / 3) / dist; + var tox, toy, fromx, fromy; + if (which & 1) { + tox = Math.round(x1 + (x2 - x1) * ratio); + toy = Math.round(y1 + (y2 - y1) * ratio); + } else { + tox = x2; + toy = y2; + } + if (which & 2) { + fromx = x1 + (x2 - x1) * (1 - ratio); + fromy = y1 + (y2 - y1) * (1 - ratio); + } else { + fromx = x1; + fromy = y1; + } + + // Draw the shaft of the arrow + ctx.beginPath(); + ctx.moveTo(fromx, fromy); + ctx.lineTo(tox, toy); + ctx.stroke(); + + // calculate the angle of the line + var lineangle = Math.atan2(y2 - y1, x2 - x1); + // h is the line length of a side of the arrow head + var h = Math.abs(d / Math.cos(angle)); + + if (which & 1) { // handle far end arrow head + var angle1 = lineangle + Math.PI + angle; + var topx = x2 + Math.cos(angle1) * h; + var topy = y2 + Math.sin(angle1) * h; + var angle2 = lineangle + Math.PI - angle; + var botx = x2 + Math.cos(angle2) * h; + var boty = y2 + Math.sin(angle2) * h; + toDrawHead(ctx, topx, topy, x2, y2, botx, boty, style); + } + if (which & 2) { // handle near end arrow head + var angle1 = lineangle + angle; + var topx = x1 + Math.cos(angle1) * h; + var topy = y1 + Math.sin(angle1) * h; + var angle2 = lineangle - angle; + var botx = x1 + Math.cos(angle2) * h; + var boty = y1 + Math.sin(angle2) * h; + toDrawHead(ctx, topx, topy, x1, y1, botx, boty, style); + } +} + +var drawHead = function(ctx, x0, y0, x1, y1, x2, y2, style) { + 'use strict'; + if (typeof(x0) == 'string') x0 = parseInt(x0); + if (typeof(y0) == 'string') y0 = parseInt(y0); + if (typeof(x1) == 'string') x1 = parseInt(x1); + if (typeof(y1) == 'string') y1 = parseInt(y1); + if (typeof(x2) == 'string') x2 = parseInt(x2); + if (typeof(y2) == 'string') y2 = parseInt(y2); + var radius = 3; + var twoPI = 2 * Math.PI; + + // all cases do this. + ctx.save(); + ctx.beginPath(); + ctx.moveTo(x0, y0); + ctx.lineTo(x1, y1); + ctx.lineTo(x2, y2); + switch (style) { + case 0: + // curved filled, add the bottom as an arcTo curve and fill + var backdist = Math.sqrt(((x2 - x0) * (x2 - x0)) + ((y2 - y0) * (y2 - y0))); + ctx.arcTo(x1, y1, x0, y0, .55 * backdist); + ctx.fill(); + break; + case 1: + // straight filled, add the bottom as a line and fill. + ctx.beginPath(); + ctx.moveTo(x0, y0); + ctx.lineTo(x1, y1); + ctx.lineTo(x2, y2); + ctx.lineTo(x0, y0); + ctx.fill(); + break; + case 2: + // unfilled head, just stroke. + ctx.stroke(); + break; + case 3: + //filled head, add the bottom as a quadraticCurveTo curve and fill + var cpx = (x0 + x1 + x2) / 3; + var cpy = (y0 + y1 + y2) / 3; + ctx.quadraticCurveTo(cpx, cpy, x0, y0); + ctx.fill(); + break; + case 4: + //filled head, add the bottom as a bezierCurveTo curve and fill + var cp1x, cp1y, cp2x, cp2y, backdist; + var shiftamt = 5; + if (x2 == x0) { + // Avoid a divide by zero if x2==x0 + backdist = y2 - y0; + cp1x = (x1 + x0) / 2; + cp2x = (x1 + x0) / 2; + cp1y = y1 + backdist / shiftamt; + cp2y = y1 - backdist / shiftamt; + } else { + backdist = Math.sqrt(((x2 - x0) * (x2 - x0)) + ((y2 - y0) * (y2 - y0))); + var xback = (x0 + x2) / 2; + var yback = (y0 + y2) / 2; + var xmid = (xback + x1) / 2; + var ymid = (yback + y1) / 2; + + var m = (y2 - y0) / (x2 - x0); + var dx = (backdist / (2 * Math.sqrt(m * m + 1))) / shiftamt; + var dy = m * dx; + cp1x = xmid - dx; + cp1y = ymid - dy; + cp2x = xmid + dx; + cp2y = ymid + dy; + } + + ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x0, y0); + ctx.fill(); + break; + } + ctx.restore(); +} diff --git a/public/assets/test/intersect.html b/public/assets/test/intersect.html new file mode 100644 index 0000000..4e5b0bb --- /dev/null +++ b/public/assets/test/intersect.html @@ -0,0 +1,139 @@ +<canvas id="canvas"></canvas> +<div id="hud"></div> + +<script src="/assets/javascripts/util.js"></script> +<script src="/assets/javascripts/vendor/tube.js"></script> +<script src="/assets/javascripts/rectangles/util/constants.js"></script> +<script src="/assets/javascripts/rectangles/util/mouse.js"></script> +<script src="/assets/javascripts/rectangles/models/vec2.js"></script> +<script src="/assets/javascripts/rectangles/models/rect.js"></script> +<script src="/assets/javascripts/vendor/canvasutilities.js"></script> +<script> + +var ctx = canvas.getContext('2d') + +var w = canvas.width = 600 +var h = canvas.height = 400 + +var vec_a = new Rect( 100, 120, 50, 100 ) +var vec_b = new Rect( 20, 200, 120, 120 ) +var vecs = [ vec_a, vec_b ] +var points = [ vec_a.x, vec_a.y, vec_b.x, vec_b.y ] +var r = 4 + +var vec_c = new Rect() +vec_c.x = vec_a.x +vec_c.y = vec_b.x + +var intersect = new vec2 () + +var dragging = false, dragging_a, dragging_b +var delta = new vec2( 0, 0 ) + +var mymouse = new mouse({ + el: canvas, + down: function(e, cursor){ + points.some(function(p){ + if (-cursor.x.a > p.a - r && -cursor.x.a < p.a + r && + cursor.y.a > p.b - r && cursor.y.a < p.b + r) { + dragging_a = p.a + dragging_b = p.b + dragging = p + return true + } + }) + }, + drag: function(e, cursor){ + if (! dragging) return + delta = cursor.delta() + delta.a = - delta.a + dragging.a = dragging_a + delta.a + dragging.b = dragging_b + delta.b + }, + up: function(e, cursor, new_cursor){ + delta.zero() + dragging.dragging = false + dragging = false + }, +}) + +function draw () { + ctx.fillStyle = "#fff" + ctx.fillRect(0,0,w,h) + + ctx.fillStyle = "#bbb" + points.forEach(drawPoint) + + drawLine(vec_a.x, vec_a.y, "#f00") + drawLine(vec_b.x, vec_b.y, "#00f") + drawLine(vec_a.x, vec_b.x, "#080") + + var t = perp(vec_c, vec_b) / ( perp(vec_a, vec_b) || 0.0000001 ) + intersect.a = vec_a.x.a + ( vec_a.y.a - vec_a.x.a ) * t + intersect.b = vec_a.x.b + ( vec_a.y.b - vec_a.x.b ) * t + + 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("<br>") + + drawPoint(intersect) +} +function drawLine (pa, pb, color) { + ctx.fillStyle = color + ctx.strokeStyle = color + var x1 = pa.a + var y1 = pa.b + var x2 = pb.a + var y2 = pb.b + drawArrow(ctx, x1, y1, x2, y2) +} +function drawPoint (p) { + var x = p.a - r + var y = p.b - r + ctx.fillRect(x, y, r*2, r*2) +} +function perp (va, vb) { + return (va.y.a - va.x.a) * (vb.y.b - vb.x.b) - (va.y.b - va.x.b) * (vb.y.a - vb.x.a) +} +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 <= pa && pa <= vec.y.a + } + else { + on_x = vec.x.a >= pa && pa >= vec.y.a + } + + if (vec.x.b < vec.y.b) { + on_y = vec.x.b <= pb && pb <= vec.y.b + } + else { + on_y = vec.x.b >= pb && pb >= vec.y.b + } + + return !! (on_x && on_y) +} + +function animate(){ + requestAnimationFrame(animate) + draw() +} +animate() + +</script> diff --git a/public/assets/test/intersect2.html b/public/assets/test/intersect2.html new file mode 100644 index 0000000..3df9f30 --- /dev/null +++ b/public/assets/test/intersect2.html @@ -0,0 +1,218 @@ +<style> +body,html{margin:0;padding:0;} +#hud { position: absolute; top: 0; left: 0; pointer-events: none; } +</style> +<canvas id="canvas"></canvas> +<div id="hud"></div> + +<script src="/assets/javascripts/util.js"></script> +<script src="/assets/javascripts/vendor/tube.js"></script> +<script src="/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js"></script> +<script src="/assets/javascripts/vendor/bower_components/lodash/dist/lodash.min.js"></script> +<script src="/assets/javascripts/mx/mx.js"></script> +<script src="/assets/javascripts/mx/extensions/mx.scene.js"></script> +<script src="/assets/javascripts/rectangles/util/constants.js"></script> +<script src="/assets/javascripts/rectangles/util/mouse.js"></script> +<script src="/assets/javascripts/rectangles/util/sort.js"></script> +<script src="/assets/javascripts/rectangles/util/uid.js"></script> +<script src="/assets/javascripts/rectangles/models/vec2.js"></script> +<script src="/assets/javascripts/rectangles/models/rect.js"></script> +<script src="/assets/javascripts/rectangles/models/room.js"></script> +<script src="/assets/javascripts/rectangles/models/surface.js"></script> +<script src="/assets/javascripts/rectangles/models/wall.js"></script> +<script src="/assets/javascripts/rectangles/models/floor.js"></script> +<script src="/assets/javascripts/rectangles/engine/rooms/_rooms.js"></script> +<script src="/assets/javascripts/rectangles/engine/rooms/_walls.js"></script> +<script src="/assets/javascripts/rectangles/engine/rooms/clipper.js"></script> +<script src="/assets/javascripts/rectangles/engine/rooms/builder.js"></script> +<script src="/assets/javascripts/rectangles/engine/rooms/grouper.js"></script> +<script src="/assets/javascripts/vendor/canvasutilities.js"></script> +<script> + +var ctx = canvas.getContext('2d') +var scene = new MX.Scene() + +var w = canvas.width = window.innerWidth +var h = canvas.height = window.innerHeight + +var cursor = new Rect( 150, 250, 150, 250 ) +var wall_vec = new Rect ( 0, 0, 0, 0 ) +var points = [ cursor.x, cursor.y ] + +var origins = new Rect() +origins.x = cursor.x +origins.y = wall_vec.x + +var radius = 1 + +var rect = new Rect( new vec2(100,400), new vec2(100,400) ) +var east = new Rect( new vec2(200,600), new vec2(100,400) ) +var corner = new Rect( new vec2(300,700), new vec2(300,700) ) +var peninsula = new Rect( new vec2(400,600), new vec2(600,800) ) +var peninsula2 = new Rect( new vec2(650,750), new vec2(350,450) ) + +var rect_room = new Room({ id: "rect", rect: rect, height: 2 }) +var east_room = new Room({ id: "east", rect: east, height: 2 }) +var corner_room = new Room({ id: "corner", rect: corner, height: 2 }) +var peninsula_room = new Room({ id: "peninsula", rect: peninsula, height: 3 }) +var peninsula2_room = new Room({ id: "peninsula2", rect: peninsula2, height: 1 }) + +Rooms.add( rect_room ) +Rooms.add( east_room ) +Rooms.add( corner_room ) +Rooms.add( peninsula_room ) +Rooms.add( peninsula2_room ) + +Rooms.clipper.update() +Rooms.builder.build() +Rooms.grouper.build() + +var r = 4 + +var intersect = new vec2 () + +var dragging = false, dragging_a, dragging_b +var delta = new vec2( 0, 0 ) + +var mymouse = new mouse({ + el: canvas, + down: function(e, cursor){ + points.some(function(p){ + if (-cursor.x.a > p.a - r && -cursor.x.a < p.a + r && + cursor.y.a > p.b - r && cursor.y.a < p.b + r) { + dragging_a = p.a + dragging_b = p.b + dragging = p + return true + } + }) + }, + drag: function(e, cursor){ + if (! dragging) return + delta = cursor.delta() + delta.a = - delta.a + dragging.a = dragging_a + delta.a + dragging.b = dragging_b + delta.b + }, + up: function(e, cursor, new_cursor){ + delta.zero() + dragging.dragging = false + dragging = false + }, +}) + +function draw () { + ctx.fillStyle = "#fff" + ctx.fillRect(0,0,w,h) + + Rooms.forEach(function(room, i){ + ctx.fillStyle = "#eee" + ctx.fillRect(room.rect.x.a, room.rect.y.a, room.rect.width(), room.rect.height()) + }) + + ctx.fillStyle = "#333" + points.forEach(drawPoint) + + drawLine(cursor.x, cursor.y, "#f00") + hud.innerHTML = "" + Walls.list.forEach(function(wall, i){ + if (wall.side & LEFT_RIGHT) { + wall_vec.x.a = wall.edge + wall_vec.x.b = wall.vec.a + wall_vec.y.a = wall.edge + wall_vec.y.b = wall.vec.b + } + else { + wall_vec.x.a = wall.vec.a + wall_vec.x.b = wall.edge + wall_vec.y.a = wall.vec.b + wall_vec.y.b = wall.edge + } + drawLine(wall_vec.x, wall_vec.y, "#888", true) + drawLine(origins.x, origins.y, "rgba(0,0,0,0.1)") + + var t = perp(origins, wall_vec) / ( perp(cursor, wall_vec) || 0.0000001 ) + intersect.a = cursor.x.a + ( cursor.y.a - cursor.x.a ) * t + intersect.b = cursor.x.b + ( cursor.y.b - cursor.x.b ) * t + + var collinear = is_collinear( intersect, wall_vec ) + var long_enough_to_intersect = 0 <= t && t <= 1 + var actually_intersects = false + var intersecting_face + var msg + + if (long_enough_to_intersect && collinear) { + if (wall.side & LEFT_RIGHT) { + intersecting_face = wall.surface.face_for_x(intersect.b) + } + else { + intersecting_face = wall.surface.face_for_x(intersect.a) + } + actually_intersects = !! (intersecting_face && intersecting_face.y.a == 0) + } + + if (actually_intersects) { + ctx.fillStyle = "#f00" + msg = "through" + } + else if (collinear) { + ctx.fillStyle = "#0f0" + msg = "to" + } + else { + ctx.fillStyle = "rgba(0,0,0,0.1)" + msg = "off" + } + + drawPoint(intersect) + if (intersecting_face) { + hud.innerHTML += intersecting_face.y.a + "<br>" + } + }) + +} +function drawLine (pa, pb, color, headless) { + ctx.fillStyle = color + ctx.strokeStyle = color + var x1 = pa.a + var y1 = pa.b + var x2 = pb.a + var y2 = pb.b + drawArrow(ctx, x1, y1, x2, y2, 3, headless ? 0 : 1) +} +function drawPoint (p) { + var x = p.a - r + var y = p.b - r + ctx.fillRect(x, y, r*2, r*2) +} +function perp (va, vb) { + return (va.y.a - va.x.a) * (vb.y.b - vb.x.b) - (va.y.b - va.x.b) * (vb.y.a - vb.x.a) +} +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 <= pa && pa <= vec.y.a + } + else { + on_x = vec.x.a >= pa && pa >= vec.y.a + } + + if (vec.x.b < vec.y.b) { + on_y = vec.x.b <= pb && pb <= vec.y.b + } + else { + on_y = vec.x.b >= pb && pb >= vec.y.b + } + + return !! (on_x && on_y) +} + +function animate(){ + requestAnimationFrame(animate) + draw() +} +animate() + +</script> |
