diff options
Diffstat (limited to 'public/assets/javascripts/rectangles/engine/rooms/builder.js')
| -rw-r--r-- | public/assets/javascripts/rectangles/engine/rooms/builder.js | 529 |
1 files changed, 281 insertions, 248 deletions
diff --git a/public/assets/javascripts/rectangles/engine/rooms/builder.js b/public/assets/javascripts/rectangles/engine/rooms/builder.js index 49e55dc..6b565c2 100644 --- a/public/assets/javascripts/rectangles/engine/rooms/builder.js +++ b/public/assets/javascripts/rectangles/engine/rooms/builder.js @@ -1,295 +1,328 @@ +(function(){ -Rooms.builder = new function(){ - var base = this + var vec2, Rect, Room, sort, UidGenerator, _ + if ('window' in this) { + vec2 = window.vec2 + Rect = window.Rect + Room = window.Room + sort = window.sort + UidGenerator = window.UidGenerator + _ = window._ + } + else { + vec2 = require('../../models/vec2') + Rect = require('../../models/rect') + Room = require('../../models/room') + sort = require('../../util/sort') + UidGenerator = require('../../util/uid') + _ = require('lodash') + FRONT = 0x1, BACK = 0x2, LEFT = 0x4, RIGHT = 0x8, FLOOR = 0x10, CEILING = 0x20 + TOP = CEILING, BOTTOM = FLOOR + function sidesToString(sides){ + var s = "" + if (sides & FRONT) s += "front " + if (sides & BACK) s += "back " + if (sides & LEFT) s += "left " + if (sides & RIGHT) s += "right " + if (sides & TOP) s += "top " + if (sides & BOTTOM) s += "bottom " + return s + } + } + + + Rooms.builder = new function(){ + var base = this - var els = [] + var els = [] - base.init = function(){ - base.bind() - } + base.init = function(){ + base.bind() + } - base.bind = function(){ - app.on("clip", rebuild) - } + base.bind = function(){ + app.on("clip", rebuild) + } - function rebuild(){ - if (window.scene) { - clear() - build() - bind() + function rebuild(){ + if (window.scene) { + clear() + build() + bind() + } } - } - function build (){ - Rooms.regions.forEach(function(region){ - build_walls(region).forEach(function(el){ - els.push(el) - scene.add(el) + function build (){ + Rooms.regions.forEach(function(region){ + build_walls(region).forEach(function(el){ + els.push(el) + scene.add(el) + }) }) - }) - Rooms.sorted_by_height().forEach(function(room){ - build_floors(room).forEach(function(el){ - els.push(el) - scene.add(el) + Rooms.sorted_by_height().forEach(function(room){ + build_floors(room).forEach(function(el){ + els.push(el) + scene.add(el) + }) }) - }) - } + } - function bind (){ - Rooms.forEach(function(room){ - room.walls = room.group_mx_walls() - room.walls.forEach(function(wall){ - Rooms.walls[ wall.id ] = wall - wall.bind() - wall.randomize_colors() + function bind (){ + Rooms.forEach(function(room){ + room.walls = room.group_mx_walls() + room.walls.forEach(function(wall){ + Rooms.walls[ wall.id ] = wall + wall.bind() + wall.randomize_colors() + }) }) - }) - } + } - function clear (){ - els.forEach(function(el){ - scene.remove(el) - el.destroy && el.destroy() - }) - els = [] - } + function clear (){ + els.forEach(function(el){ + scene.remove(el) + el.destroy && el.destroy() + }) + els = [] + } - function build_walls (region){ - var room = Rooms.list[ region.id ] + function build_walls (region){ + var room = Rooms.list[ region.id ] - var list = [], el = null + var list = [], el = null - var width = region.x.length() - var depth = region.y.length() - var height = room.height + var width = region.x.length() + var depth = region.y.length() + var height = room.height - if (region.sides & FRONT) { - el = make_wall('.front') - el.width = width - el.height = height - el.rotationY = PI - el.x = region.x.a + width/2 - el.y = height/2 - el.z = region.y.a - el.rect = region - el.side = FRONT - room.mx_walls.push(el) - list.push(el) - } - if (region.sides & BACK) { - var el = make_wall('.back') - el.width = width - el.height = height - el.rotationY = 0 - el.x = region.x.b - width/2 - el.y = height/2 - el.z = region.y.b - el.rect = region - el.side = BACK - room.mx_walls.push(el) - list.push(el) - } - if (region.sides & LEFT) { - el = make_wall('.left') - el.rotationY = HALF_PI - el.height = height - el.width = depth - el.x = region.x.a - el.y = height/2 - el.z = region.y.a + depth/2 - el.rect = region - el.side = LEFT - room.mx_walls.push(el) - list.push(el) - } - if (region.sides & RIGHT) { - el = make_wall('.right') - el.rotationY = -HALF_PI - el.height = height - el.width = depth - el.x = region.x.b - el.y = height/2 - el.z = region.y.b - depth/2 - el.rect = region - el.side = RIGHT - room.mx_walls.push(el) - list.push(el) - } + if (region.sides & FRONT) { + el = make_wall('.front') + el.width = width + el.height = height + el.rotationY = PI + el.x = region.x.a + width/2 + el.y = height/2 + el.z = region.y.a + el.rect = region + el.side = FRONT + room.mx_walls.push(el) + list.push(el) + } + if (region.sides & BACK) { + var el = make_wall('.back') + el.width = width + el.height = height + el.rotationY = 0 + el.x = region.x.b - width/2 + el.y = height/2 + el.z = region.y.b + el.rect = region + el.side = BACK + room.mx_walls.push(el) + list.push(el) + } + if (region.sides & LEFT) { + el = make_wall('.left') + el.rotationY = HALF_PI + el.height = height + el.width = depth + el.x = region.x.a + el.y = height/2 + el.z = region.y.a + depth/2 + el.rect = region + el.side = LEFT + room.mx_walls.push(el) + list.push(el) + } + if (region.sides & RIGHT) { + el = make_wall('.right') + el.rotationY = -HALF_PI + el.height = height + el.width = depth + el.x = region.x.b + el.y = height/2 + el.z = region.y.b - depth/2 + el.rect = region + el.side = RIGHT + room.mx_walls.push(el) + list.push(el) + } - return list - } + return list + } - function build_floors(room){ - var list = [], el = null + function build_floors(room){ + var list = [], el = null - var constructed = room.intersects.filter(function(room){ return room.constructed }) - sort_rooms_by_height(constructed) + var constructed = room.intersects.filter(function(room){ return room.constructed }) + sort.rooms_by_height(constructed) - if (constructed.length > 0) { - // render the regions that don't intersect with anything we've already rendered - // if the height is different, calculate the overlapping sides and render half-walls - room.regions.forEach(function(region){ - var intersected = false - for (var i = 0; i < constructed.length; i++) { - if (constructed[i].rect.contains(region)) { - intersected = true - // r.sides = 0xf - // half_sides - } - else if (constructed[i].rect.intersects(region)) { - intersected = true - if (room.height < constructed[i].height) { - var ceiling_walls = make_ceiling_walls( room, constructed[i], region ) - list = list.concat(ceiling_walls) + if (constructed.length > 0) { + // render the regions that don't intersect with anything we've already rendered + // if the height is different, calculate the overlapping sides and render half-walls + room.regions.forEach(function(region){ + var intersected = false + for (var i = 0; i < constructed.length; i++) { + if (constructed[i].rect.contains(region)) { + intersected = true + // r.sides = 0xf + // half_sides + } + else if (constructed[i].rect.intersects(region)) { + intersected = true + if (room.height < constructed[i].height) { + var ceiling_walls = make_ceiling_walls( room, constructed[i], region ) + list = list.concat(ceiling_walls) + } } } - } - if (! intersected) { - el = make_floor(room, region) - list.push( el ) - room.mx_floor.push(el) + if (! intersected) { + el = make_floor(room, region) + list.push( el ) + room.mx_floor.push(el) - el = make_ceiling(room, region) - list.push( el ) - room.mx_ceiling.push(el) - } - }) + el = make_ceiling(room, region) + list.push( el ) + room.mx_ceiling.push(el) + } + }) - } - else { - // render floor and ceiling for the entire rectangle - el = make_floor(room, room.rect) - list.push( el ) - room.mx_floor.push(el) + } + else { + // render floor and ceiling for the entire rectangle + el = make_floor(room, room.rect) + list.push( el ) + room.mx_floor.push(el) - el = make_ceiling(room, room.rect) - list.push( el ) - room.mx_ceiling.push(el) - } + el = make_ceiling(room, room.rect) + list.push( el ) + room.mx_ceiling.push(el) + } - room.constructed = true - return list - } + room.constructed = true + return list + } - function make_ceiling_walls( lo, hi, region ){ - var list = [] + function make_ceiling_walls( lo, hi, region ){ + var list = [] - var width = region.x.length() - var depth = region.y.length() - var height = hi.height - lo.height + var width = region.x.length() + var depth = region.y.length() + var height = hi.height - lo.height - if (! (region.half_sides & LEFT) && region.x.a == hi.rect.x.a) { - el = make_wall('.left') - el.rotationY = HALF_PI - el.height = height - el.width = depth - el.x = region.x.a - el.y = lo.height + height/2 - el.z = region.y.a + depth/2 - el.rect = region - list.push(el) - hi.mx_walls.push(el) - region.half_sides |= LEFT - el.half_side = LEFT - } + if (! (region.half_sides & LEFT) && region.x.a == hi.rect.x.a) { + el = make_wall('.left') + el.rotationY = HALF_PI + el.height = height + el.width = depth + el.x = region.x.a + el.y = lo.height + height/2 + el.z = region.y.a + depth/2 + el.rect = region + list.push(el) + hi.mx_walls.push(el) + region.half_sides |= LEFT + el.half_side = LEFT + } - if (! (region.half_sides & RIGHT) && region.x.b == hi.rect.x.b) { - el = make_wall('.right') - el.rotationY = -HALF_PI - el.height = height - el.width = depth - el.x = region.x.b - el.y = lo.height + height/2 - el.z = region.y.b - depth/2 - el.rect = region - list.push(el) - hi.mx_walls.push(el) - region.half_sides |= RIGHT - el.half_side = RIGHT + if (! (region.half_sides & RIGHT) && region.x.b == hi.rect.x.b) { + el = make_wall('.right') + el.rotationY = -HALF_PI + el.height = height + el.width = depth + el.x = region.x.b + el.y = lo.height + height/2 + el.z = region.y.b - depth/2 + el.rect = region + list.push(el) + hi.mx_walls.push(el) + region.half_sides |= RIGHT + el.half_side = RIGHT + } + + if (! (region.half_sides & FRONT) && region.y.a == hi.rect.y.a) { + el = make_wall('.front') + el.width = width + el.height = height + el.rotationY = PI + el.x = region.x.a + width/2 + el.y = lo.height + height/2 + el.z = region.y.a + el.rect = region + list.push(el) + hi.mx_walls.push(el) + region.half_sides |= FRONT + el.half_side = FRONT + } + + if (! (region.half_sides & BACK) && region.y.b == hi.rect.y.b) { + el = make_wall('.back') + el.width = width + el.height = height + el.rotationY = 0 + el.x = region.x.b - width/2 + el.y = lo.height + height/2 + el.z = region.y.b + el.rect = region + list.push(el) + hi.mx_walls.push(el) + region.half_sides |= BACK + el.half_side = BACK + } + return list } - if (! (region.half_sides & FRONT) && region.y.a == hi.rect.y.a) { - el = make_wall('.front') + function make_floor(room, region){ + var width = region.x.length() + var depth = region.y.length() + + var el = make_wall('.floor') + el.height = depth el.width = width - el.height = height - el.rotationY = PI el.x = region.x.a + width/2 - el.y = lo.height + height/2 - el.z = region.y.a + el.y = 0 + el.z = region.y.a + depth/2 + el.rotationX = PI/2 el.rect = region - list.push(el) - hi.mx_walls.push(el) - region.half_sides |= FRONT - el.half_side = FRONT + el.side = FLOOR + return el } + function make_ceiling(room, region){ + var width = region.x.length() + var depth = region.y.length() + var height = room.height - if (! (region.half_sides & BACK) && region.y.b == hi.rect.y.b) { - el = make_wall('.back') + var el = make_wall('.ceiling') + el.height = depth el.width = width - el.height = height - el.rotationY = 0 - el.x = region.x.b - width/2 - el.y = lo.height + height/2 - el.z = region.y.b + el.x = region.x.a + width/2 + el.y = height + el.z = region.y.a + depth/2 + el.rotationX = -PI/2 el.rect = region - list.push(el) - hi.mx_walls.push(el) - region.half_sides |= BACK - el.half_side = BACK + el.side = CEILING + return el } - return list - } - function make_floor(room, region){ - var width = region.x.length() - var depth = region.y.length() - - var el = make_wall('.floor') - el.height = depth - el.width = width - el.x = region.x.a + width/2 - el.y = 0 - el.z = region.y.a + depth/2 - el.rotationX = PI/2 - el.rect = region - el.side = FLOOR - return el - } - function make_ceiling(room, region){ - var width = region.x.length() - var depth = region.y.length() - var height = room.height + function make_wall(klass){ + var el = new MX.Object3D(".face" + (klass || "")) + el.width = el.height = el.scaleX = el.scaleY = el.scaleZ = 1 + el.z = el.y = el.x = 0 + el.side = 0 + el.type = "Face" + el.el.style.opacity = 1.0 + el.side = 0 + el.rect = null + el.destroy = function(){ + this.el = this.rect = null + } - var el = make_wall('.ceiling') - el.height = depth - el.width = width - el.x = region.x.a + width/2 - el.y = height - el.z = region.y.a + depth/2 - el.rotationX = -PI/2 - el.rect = region - el.side = CEILING - return el - } + // possible if walls are opaque + // el.el.classList.add("backface-hidden") - function make_wall(klass){ - var el = new MX.Object3D(".face" + (klass || "")) - el.width = el.height = el.scaleX = el.scaleY = el.scaleZ = 1 - el.z = el.y = el.x = 0 - el.side = 0 - el.type = "Face" - el.el.style.opacity = 1.0 - el.side = 0 - el.rect = null - el.destroy = function(){ - this.el = this.rect = null + return el } - // possible if walls are opaque - // el.el.classList.add("backface-hidden") - - return el } -} - +})() |
