Path: blob/main/website/GAUSS/js/walkbox-manager.js
2941 views
var WalkBox = function(id)1{2this.id = id;3this.visible = true;4this.polygon = new Polygon();5this.maxScaleFactor = 100;6this.minScaleFactor = 100;7this.deltaScale = 1;8this.walkingSound = null;9this.neighbors = [];10};1112var Neighbor = function(wbId, commonEdge)13{14this.wbId = wbId;15this.commonEdge = commonEdge;16};1718var Polygon = function()19{20this.points = [];21this.edges = [];22this.closed = false;23this.centroid = null;24this.top = null;25this.bottom = null;26this.close = function()27{28this.closed = true;29var points = this.points;30for(var i = 0; i < points.length; i++)31this.edges[i] = [points[i], points[(i + 1) % points.length]];3233this.centroid = getPolygonCentroid(this);34var topAndBottom = getPolygonTopAndBottom(this);35this.top = topAndBottom.top;36this.bottom = topAndBottom.bottom;37};38this.getNearestPointToEdge = function(p, vertex1, vertex2)39{40var sqr = function(x) { return x * x; };41var l2 = sqr(vertex1.getDistance(vertex2));42if (l2 == 0) return vertex1;43var t = ((p.x - vertex1.x) * (vertex2.x - vertex1.x) + (p.y - vertex1.y) * (vertex2.y - vertex1.y)) / l2;44if (t < 0) return vertex1;45if (t > 1) return vertex2;46return new paper.Point(vertex1.x + t * (vertex2.x - vertex1.x), vertex1.y + t * (vertex2.y - vertex1.y));47};48this.getNearestPoint = function(p)49{50var list = [];5152for(var i = 0; i < this.edges.length; i++)53list.push(this.getNearestPointToEdge(p, this.edges[i][0], this.edges[i][1]));5455var minDist = Number.MAX_VALUE;56var minIdx = -1;5758for(var i = 0; i < list.length; i++)59{60var dist = getDistanceFromPoints(p, list[i]);61if(minDist > dist)62{63minDist = dist;64minIdx = i;65}66}6768return list[minIdx];69};70};7172var Point = function(x, y)73{74this.x = x;75this.y = y;76};7778var highlightCloseVertex = function(p, wb, precision)79{80var points = wb.polygon.points;81for(var i = 0; i < points.length; i++)82if(p.x >= points[i].x - precision && p.x < points[i].x + precision)83if(p.y >= points[i].y - precision && p.y < points[i].y + precision)84{85wb.polygon.points[i].highlight = true;86return;87}88};8990var resetVertexHighlighting = function(wb)91{92var points = wb.polygon.points;93for(var i = 0; i < points.length; i++)94wb.polygon.points[i].highlight = false;95};9697var resetVertexLocking = function(wb)98{99var points = wb.polygon.points;100for(var i = 0; i < points.length; i++)101wb.polygon.points[i].locked = false;102};103104var getHighlightedWalkboxVertex = function(wboxes)105{106for(var i in wboxes)107{108var points = wboxes[i].polygon.points;109for(var j = 0; j < points.length; j++)110if(points[j].highlight)111return { wboxId : i, point : points[j] };112}113return null;114};115116var getLockedWalkboxVertex = function(wboxes)117{118for(var i in wboxes)119{120var points = wboxes[i].polygon.points;121for(var j = 0; j < points.length; j++)122if(points[j].locked)123return { wboxId : i, point : points[j] };124}125return null;126};127128var changeLockedWalkboxVertexPosition = function(wboxes, wboxId, x, y)129{130var poly = wboxes[wboxId].polygon;131var points = poly.points;132for(var j = 0; j < points.length; j++)133if(points[j].locked)134{135points[j].x = x;136points[j].y = y;137}138if(poly.closed === true)139poly.close();140};141142var isPointOnLine = function(edge, p, precision)143{144var edgePointA = edge[0];145var edgePointB = edge[1];146147var dist = Math.abs((edgePointB.y - edgePointA.y) * p.x - (edgePointB.x - edgePointA.x) * p.y + edgePointB.x * edgePointA.y148- edgePointB.y * edgePointA.x) / Math.sqrt(Math.pow(edgePointB.y - edgePointA.y, 2)149+ Math.pow(edgePointB.x - edgePointA.x, 2));150151var maxX = Math.max(edgePointA.x, edgePointB.x);152var minX = Math.min(edgePointA.x, edgePointB.x);153var maxY = Math.max(edgePointA.y, edgePointB.y);154var minY = Math.min(edgePointA.y, edgePointB.y);155156if(dist <= precision && (p.x >= minX - 5 && p.x < maxX + 5 && p.y >= minY -5 && p.y < maxY + 5))157return true;158};159160161var highlightCloseEdge = function(p, wb, precision)162{163var edges = wb.polygon.edges;164for(var i = 0; i < edges.length; i++)165if(isPointOnLine(edges[i], p, precision))166{167wb.polygon.edges[i].highlight = true;168return;169}170};171172var getHighlightedWalkboxEdge = function(wboxes)173{174for(var i in wboxes)175{176var edges = wboxes[i].polygon.edges;177for(var j = 0; j < edges.length; j++)178if(edges[j].highlight)179return { wboxId : i, edge : edges[j] };180}181return null;182};183184var lockVertex = function(wb, p)185{186var points = wb.polygon.points;187for(var i = 0; i < points.length; i++)188if(p.x == points[i].x && p.y == points[i].y)189{190wb.polygon.points[i].locked = true;191return;192}193};194195var resetEdgeHighlighting = function(wb)196{197var edges = wb.polygon.edges;198for(var i = 0; i < edges.length; i++)199wb.polygon.edges[i].highlight = false;200};201202var splitEdge = function(wb, edge, newPoint)203{204var edges = wb.polygon.edges;205var points = wb.polygon.points;206var x1 = edge[0].x, y1 = edge[0].y;207for(var i = 0; i < edges.length; i++)208if(edges[i][0].x == edge[0].x && edges[i][0].y == edge[0].y209&& edges[i][1].x == edge[1].x && edges[i][1].y == edge[1].y)210{211wb.polygon.edges.splice(i, 0, [edge[0], new paper.Point(newPoint.x, newPoint.y)]);212wb.polygon.edges[i + 1][0] = new paper.Point(newPoint.x, newPoint.y);213break;214}215for(var i = 0; i < points.length; i++)216if(points[i].x == x1 && points[i].y == y1)217{218wb.polygon.points.splice(i + 1, 0, new paper.Point(newPoint.x, newPoint.y));219break;220}221};222223var getPolygonCentroid = function(poly)224{225var p = new paper.Point(0, 0);226var points = poly.points;227228for(var i = 0; i < points.length; i++)229{230p.x += points[i].x;231p.y += points[i].y;232}233234p.x /= points.length;235p.y /= points.length;236237return p;238};239240var getPolygonTopAndBottom = function(poly)241{242var points = poly.points;243var minY = points[0].y;244var maxY = points[0].y;245246for(var i = 1; i < points.length; i++)247{248if(minY > points[i].y)249minY = points[i].y;250if(maxY < points[i].y)251maxY = points[i].y;252}253254return { top : minY, bottom : maxY };255};256257var getEdgeList = function(room)258{259var edges = {};260for (var key in room.walkBoxes)261{262var _edges = room.walkBoxes[key].polygon.edges;263for (var i = 0; i < _edges.length; i++)264{265var edge_str1 = '(' + _edges[i][0].x + ', ' + _edges[i][0].y + ')';266var edge_str2 = '(' + _edges[i][1].x + ', ' + _edges[i][1].y + ')';267var tmp = edge_str1 + ', ' + edge_str2;268if (tmp in edges)269edges[tmp]['IDs'].push(key);270else271{272tmp = edge_str2 + ', ' + edge_str1;273if (tmp in edges)274edges[tmp]['IDs'].push(key);275else276edges[tmp] = {IDs: [key], edge: _edges[i] };277}278}279}280return edges;281};282283var computeWalkboxNeighbors = function(rooms)284{285for(var i in rooms)286{287var edgeList = getEdgeList(rooms[i]);288for(var key in edgeList)289if(edgeList[key].IDs.length > 1)290{291var IDs = edgeList[key].IDs;292var neighborsList = rooms[i].walkBoxes[IDs[0]].neighbors;293var alreadyPresent = false;294for(var j = 0; j < neighborsList.length; j++)295if(neighborsList[j].wbId === IDs[1]) // has the neighbor already been added?296{297alreadyPresent = true;298break;299}300301if(alreadyPresent === true)302continue;303rooms[i].walkBoxes[IDs[0]].neighbors.push(new Neighbor(IDs[1], edgeList[key].edge));304rooms[i].walkBoxes[IDs[1]].neighbors.push(new Neighbor(IDs[0], edgeList[key].edge));305}306}307308};309310var getWalkboxFromPoint = function(wboxes, p, skipInvisible)311{312for(var i in wboxes)313{314if(skipInvisible === true && wboxes[i].visible === false)315continue;316if (isPointInPoly(wboxes[i].polygon.points, p))317return wboxes[i];318}319return null;320};321322var getCommonEdge = function(wb1, wb2)323{324var edge1 = null, edge2 = null;325326for(var i = 0; i < wb1.neighbors.length; i++)327{328var n = wb1.neighbors[i];329if(n.wbId === wb2.id)330{331edge1 = n.commonEdge;332break;333}334}335336if(!edge1)337return null;338339for(var i = 0; i < wb2.neighbors.length; i++)340{341var n = wb2.neighbors[i];342if(n.wbId === wb1.id)343{344edge2 = n.commonEdge;345break;346}347}348349if(!edge2)350return null;351352if(edge1 !== edge2)353return null;354355return edge1;356};357358var getNearestWalkBox = function(wboxes, point)359{360var wb;361var minDist = Infinity;362var p;363364for(var i in wboxes)365{366if(wboxes[i].visible === false)367continue;368p = wboxes[i].polygon.getNearestPoint(point);369var dist = getDistanceBetweenPoints(p, point);370if (dist < minDist)371{372minDist = dist;373wb = wboxes[i];374}375}376return wb;377};378379var deleteWalkbox = function(roomId, wbId)380{381delete editorMapIdRoom[roomId].walkBoxes[wbId];382};383384