(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 } 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') 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) Rooms.walls = walls base.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 (last_mx && last_mx.rect.eq(mx.rect)) { 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 mx.culled = true mx.destroy() scene.remove(mx) 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 wall var useX = side & FRONT_BACK var useA = side & (FRONT | RIGHT) // collection.sort( useX ? sort.compare_zx : sort.compare_xz ) collection.forEach(function(mx){ if (mx.culled) return var coplanar = wall && wall.edge == mx.rect[useX ? 'y': 'x'][useA ? 'a': 'b'] if (wall && coplanar) { 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 ({ id: base.uid(), 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 } base.bind = function(){ Rooms.walls.forEach(function(wall){ wall.bind() wall.randomize_colors() }) } } })()