private int GetDistance(BBNode a, BBNode b) { int distX = Mathf.Abs(a.Coordinate.x - b.Coordinate.x); int distY = Mathf.Abs(a.Coordinate.y - b.Coordinate.y); if (distX > distY) { return this.diagonalMultiplier * distY + this.straightMultiplier * (distX - distY); } return this.diagonalMultiplier * distX + this.straightMultiplier * (distY - distX); }
// EDAN30 Photorealistic Computer Graphics - Magnus Andersson // http://fileadmin.cs.lth.se/cs/Education/EDAN30/lectures/S2-bvh.pdf public void Split() { const int TARGET_LEAF_SIZE = 4; if (m_children == null || m_children.Count < TARGET_LEAF_SIZE) { return; } // get centers and sort on the largest axis var centers = m_children.Select(o => new Tuple <BBNode, Vector3>(o, Util.GetBoundingBoxCenter(o.m_bbox))); var dimx = m_bbox.Max.X - m_bbox.Min.X; var dimy = m_bbox.Max.Y - m_bbox.Min.Y; var dimz = m_bbox.Max.Z - m_bbox.Min.Z; if (dimx >= dimy && dimx >= dimz) { centers = centers.OrderBy(o => o.Item2.X); } else if (dimy >= dimz) { centers = centers.OrderBy(o => o.Item2.Y); } else { centers = centers.OrderBy(o => o.Item2.Z); } var left = new BBNode(); var right = new BBNode(); int i = 0; int mid = m_children.Count / 2; foreach (var n in centers) { if (i++ < mid) { left.m_children.Add(n.Item1); } else { right.m_children.Add(n.Item1); } } left.UpdateBBox(); right.UpdateBBox(); m_children.Clear(); m_children.Add(left); m_children.Add(right); left.Split(); right.Split(); }
private static void AssertParse(string code, BBNode expected) { Logger.LogMessage("Testing: {0}", code); Logger.LogMessage("Expected: {0}", expected); var gotten = BBParser.Parse(code); Logger.LogMessage("Gotten: "); foreach (var got in gotten) { Logger.LogMessage(" {0}", got); } var firstGotten = gotten[0]; Assert.IsTrue(expected.StructurallyEquals(firstGotten)); }
public List<BBNode> GetNeighbours(BBNode node) { List<BBNode> neighbhours = new List<BBNode>(); // Checks adjacent nodes and adds them to list if within grid for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { if (x == 0 && y == 0) { continue; } BBCoordinate checkCoordinate = new BBCoordinate(node.Coordinate.x + x, node.Coordinate.y + y); if (this.IsCoordinateInBounds(checkCoordinate)) { neighbhours.Add(grid[checkCoordinate.x, checkCoordinate.y]); } } } return neighbhours; }
public void CreateGrid() { this.grid = new BBNode[this.gridSize.x, this.gridSize.y]; Vector3 worldBottomLeft = transform.position - Vector3.right * this.gridWorldSize.x / 2 - Vector3.up * this.gridWorldSize.y / 2; // Creates path grid starting from bottom left for (int x = 0; x < this.gridSize.x / this.nodeDiameter; x++) { for (int y = 0; y < this.gridSize.y / this.nodeDiameter; y++) { Vector3 worldPoint = worldBottomLeft + Vector3.right * (x + this.nodeRadius) + Vector3.up * (y + this.nodeRadius) + BBSceneConstants.collidedGroundVect; bool isWalkable = !(Physics.CheckSphere(worldPoint, this.nodeRadius - .01f, this.unwalkableMask)); BBNode newNode = new BBNode(isWalkable, worldPoint, new BBCoordinate(x, y), 0); grid[x, y] = newNode; if (isWalkable) { this.uninhabitedNodes.Add(newNode); } } } }
/// <summary> /// Whether this node is structurally equivalent to another node /// </summary> /// <param name="node">The node to compare against</param> /// <returns></returns> public abstract bool StructurallyEquals(BBNode node);
// Checks if adjacent horizontal and vertical nodes would be cut off during a diagonal move public bool IsDiagonalMoveValid(BBNode startNode, BBNode targetNode, BBCoordinate bound) { //Set Indices accordingly and check if valid int horizontalX = (targetNode.Coordinate.x < startNode.Coordinate.x) ? startNode.Coordinate.x - bound.x : startNode.Coordinate.x + bound.x; if ((horizontalX < 0) || (horizontalX >= this.gridSize.x)) { return false; } int verticalY = (targetNode.Coordinate.y < startNode.Coordinate.y) ? startNode.Coordinate.y - bound.y : startNode.Coordinate.y + bound.y; if ((verticalY < 0) || (verticalY >= this.gridSize.y)) { return false; } BBCoordinate horizontalIndex = new BBCoordinate(horizontalX, startNode.Coordinate.y); BBCoordinate verticalIndex = new BBCoordinate(startNode.Coordinate.x, verticalY); return (grid[horizontalIndex.x, horizontalIndex.y].IsWalkable && grid[verticalIndex.x, verticalIndex.y].IsWalkable); }
public bool IsDiagonalMove(BBNode startNode, BBNode targetNode) { return (startNode.Coordinate.x != targetNode.Coordinate.x && startNode.Coordinate.y != targetNode.Coordinate.y); }
public Vector3 WorldPointFromNode(BBNode node) { return this.WorldPointFromCoordinate(node.Coordinate); }
public bool IsOpenNode(BBNode node) { return this.IsOpenNodeAtCoordinate(node.Coordinate); }
private Vector3[] RetracePath(BBNode startNode, BBNode endNode) { List<BBNode> path = new List<BBNode>(); BBNode currentNode = endNode; //Bubble back up to original node while (currentNode != startNode) { path.Add(currentNode); currentNode = currentNode.Parent; } Vector3[] waypoints = this.SimplifyPath(path); Array.Reverse(waypoints); return waypoints; }
public virtual void Update() { if (this.knockback != null) { this.TakeKnockback(this.knockback); } BBNode currentInhabitedNode = this.gridController.NodeFromWorldPoint(transform.position); // If previous node not set, set and increment inhabited count if (this.previousInhabitedNode == null) { this.previousInhabitedNode = currentInhabitedNode; this.previousInhabitedNode.InhabitedCount++; if (this.gridController.UnhibitedNodes.Contains(this.previousInhabitedNode)) { this.gridController.UnhibitedNodes.Remove(this.previousInhabitedNode); } } else if (!currentInhabitedNode.Equals(this.previousInhabitedNode)) { //If moving to new node, decrement other count and increase own this.previousInhabitedNode.InhabitedCount--; if (this.previousInhabitedNode.InhabitedCount < 0) { BBErrorHelper.DLog(BBErrorConstants.InvalidValueUpdate, "Inhabited node count went below zero"); } if (this.previousInhabitedNode.InhabitedCount == 0 && !this.gridController.UnhibitedNodes.Contains(this.previousInhabitedNode)) { this.gridController.UnhibitedNodes.Add(this.previousInhabitedNode); } this.previousInhabitedNode = currentInhabitedNode; if (this.gridController.UnhibitedNodes.Contains(this.previousInhabitedNode)) { this.gridController.UnhibitedNodes.Remove(this.previousInhabitedNode); } this.previousInhabitedNode.InhabitedCount++; } }