Check that the line between two tile-coord endpoints stays entirely * inside walkable, zero-cost cells. Stricter than just sampling along * the line — it also checks the diagonal-corner-adjacent cells so the * line can never "scrape past" a wall corner. * * Both endpoint
(startPos, endPos)
| 624 | * @returns {boolean} |
| 625 | * @private */ |
| 626 | isLineClear(startPos, endPos) |
| 627 | { |
| 628 | ASSERT(isVector2(startPos) && isVector2(endPos), 'isLineClear needs Vector2 endpoints'); |
| 629 | ASSERT(this.isNodeClear(startPos.x, startPos.y) && this.isNodeClear(endPos.x, endPos.y), |
| 630 | 'isLineClear endpoints must be in-bounds and clear'); |
| 631 | |
| 632 | const dx = endPos.x - startPos.x; |
| 633 | const dy = endPos.y - startPos.y; |
| 634 | const adx = abs(dx); |
| 635 | const ady = abs(dy); |
| 636 | const sx = sign(dx); |
| 637 | const sy = sign(dy); |
| 638 | let x = startPos.x; |
| 639 | let y = startPos.y; |
| 640 | |
| 641 | if (ady === adx) |
| 642 | { |
| 643 | // Pure diagonal. |
| 644 | while (x !== endPos.x) |
| 645 | { |
| 646 | if (x !== startPos.x) |
| 647 | { |
| 648 | if (!this.isNodeClear(x, y)) return false; |
| 649 | if (!this.isNodeClear(x, y - sy)) return false; |
| 650 | } |
| 651 | if (!this.isNodeClear(x, y + sy)) return false; |
| 652 | x += sx; |
| 653 | y += sy; |
| 654 | } |
| 655 | if (!this.isNodeClear(endPos.x, endPos.y - sy)) return false; |
| 656 | } |
| 657 | else if (ady < adx) |
| 658 | { |
| 659 | // Mostly horizontal. |
| 660 | if (dy === 0) |
| 661 | { |
| 662 | // Purely horizontal. |
| 663 | x += sx; |
| 664 | while (x !== endPos.x) |
| 665 | { |
| 666 | if (!this.isNodeClear(x, y)) return false; |
| 667 | x += sx; |
| 668 | } |
| 669 | } |
| 670 | else |
| 671 | { |
| 672 | let lastY = startPos.y; |
| 673 | while (x !== endPos.x) |
| 674 | { |
| 675 | y = startPos.y + Math.trunc((dy * (x - startPos.x)) / dx); |
| 676 | if (lastY !== y) |
| 677 | { |
| 678 | if (!this.isNodeClear(x - sx, y + sy)) return false; |
| 679 | if (!this.isNodeClear(x, y - sy)) return false; |
| 680 | } |
| 681 | lastY = y; |
| 682 | if (x !== startPos.x) |
| 683 | { |
no test coverage detected