Rooms.mover = new function(){ var base = this base.room = null base.noclip = false base.init = function(){ base.bind() base.update(scene.camera) } base.bind = function(){ app.on("move", base.update) keys.on("backslash", function(e){ if ( ! (e.ctrlKey || e.metaKey) ) return base.noclip = ! base.noclip base.room = null app.movements.gravity( ! base.noclip ) }) } base.update = function(pos){ var radius = scene.camera.radius cam.y = pos.y // if we were in a room already.. if (base.room) { // check if we're still in the room if (base.room.rect.containsDisc(pos.x, pos.z, radius)) { cam.x = pos.x cam.z = pos.z return } // 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() 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) ) { 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.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() } }) 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) 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 // determine what room we are in now var intersects = Rooms.filter(function(r){ return r.rect.contains(pos.x, pos.z) }) // did we actually enter a room? if (intersects.length) { base.room = intersects[0] if (! base.noclip) { Walls.setBodyColor() } app.tube("change-room", { room: base.room }) } } }