(function(){ var vec2, Rect, Rooms, UidGenerator, Wall, Surface, sort, _ if ('window' in this) { vec2 = window.vec2 Rect = window.Rect Surface = window.Surface Rooms = window.Rooms UidGenerator = window.UidGenerator Wall = window.Wall sort = window.sort _ = window._ } else { Rooms = require('./_rooms') UidGenerator = require('../../util/uid') vec2 = require('../../models/vec2') Rect = require('../../models/rect') Wall = require('../../models/wall') Surface = require('../../models/surface') sort = require('../../util/sort') _ = require('lodash') FRONT = 0x1, BACK = 0x2, LEFT = 0x4, RIGHT = 0x8, FLOOR = 0x10, CEILING = 0x20 PI = Math.PI HALF_PI = PI/2 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.grouper = new function(){ var base = this base.list = {} base.uid = new UidGenerator(base.list) base.build = function (){ var walls = [] var collections = base.collect() base.cull(collections) base.group(walls, collections, FRONT) base.group(walls, collections, BACK) base.group(walls, collections, LEFT) base.group(walls, collections, RIGHT) Walls.assign( walls ) Walls.bind() } base.collect = function(){ var collections = {} collections[FRONT] = [] collections[BACK] = [] collections[LEFT] = [] collections[RIGHT] = [] Rooms.forEach(function(room){ room.mx_walls.forEach(function(mx){ var side = mx.side || mx.half_side collections[side].push(mx) }) }) base.cull(collections) return collections } base.cull = function(collections){ [FRONT, BACK, LEFT, RIGHT].forEach(function(side){ var collection = collections[side] var useX = side & FRONT_BACK var useA = side & (FRONT | RIGHT) var last_mx var widthVec, heightVec collection.sort( useX ? sort.compare_zx : sort.compare_xz ) collection.forEach(function(mx){ if (mx.culled) { return } if (last_mx && mx && last_mx.rect.eq(mx.rect)) { // culls half-walls if (last_mx.rect.id == mx.rect.id) { last_mx.height += mx.height/2 last_mx.y += mx.height/4 last_mx.face.y.b += mx.height/2 } last_mx.side = side if (! mx.culled) { scene.remove(mx) mx.destroy() mx.culled = true } return } widthVec = mx.rect[useX ? 'x' : 'y'].clone() heightVec = new vec2( mx.y - mx.height/2, mx.y + mx.height/2 ) mx.face = new Rect( widthVec, heightVec ) last_mx = mx }) }) return collections } base.group = function(walls, collections, side){ var collection = collections[side] var useX = side & FRONT_BACK var useA = side & (FRONT | LEFT) // collection.sort( useX ? sort.compare_zx : sort.compare_xz ) var planes = {} collection.forEach(function(mx){ if (mx.culled) return var edge = mx.rect[useX ? 'y': 'x'][ useA ? 'a': 'b'] planes[edge] = planes[edge] || [] planes[edge].push(mx) }) var edges = _.keys(planes) edges.forEach(function(edge){ var wall planes[edge].forEach(function(mx){ if (wall) { if (useX && wall.vec.b == mx.rect.x.a) { wall.vec.b = mx.rect.x.b wall.mx.push(mx) wall.surface.add(mx.face) return } else if (! useX && wall.vec.b == mx.rect.y.a) { wall.vec.b = mx.rect.y.b wall.mx.push(mx) wall.surface.add(mx.face) return } } wall = new Wall ({ side: side, mx: [ mx ], surface: new Surface( mx.face ), vec: mx.rect[ useX ? 'x' : 'y' ].clone(), edge: mx.rect[ useX ? 'y' : 'x' ][ useA ? 'a' : 'b' ], }) walls.push(wall) }) }) return walls } } })()