| 655 | } |
| 656 | |
| 657 | dtStatus dtTileCache::buildNavMeshTile(const dtCompressedTileRef ref, dtNavMesh* navmesh) |
| 658 | { |
| 659 | dtAssert(m_talloc); |
| 660 | dtAssert(m_tcomp); |
| 661 | |
| 662 | unsigned int idx = decodeTileIdTile(ref); |
| 663 | if (idx > (unsigned int)m_params.maxTiles) |
| 664 | return DT_FAILURE | DT_INVALID_PARAM; |
| 665 | const dtCompressedTile* tile = &m_tiles[idx]; |
| 666 | unsigned int salt = decodeTileIdSalt(ref); |
| 667 | if (tile->salt != salt) |
| 668 | return DT_FAILURE | DT_INVALID_PARAM; |
| 669 | |
| 670 | m_talloc->reset(); |
| 671 | |
| 672 | NavMeshTileBuildContext bc(m_talloc); |
| 673 | const int walkableClimbVx = (int)(m_params.walkableClimb / m_params.ch); |
| 674 | dtStatus status; |
| 675 | |
| 676 | // Decompress tile layer data. |
| 677 | status = dtDecompressTileCacheLayer(m_talloc, m_tcomp, tile->data, tile->dataSize, &bc.layer); |
| 678 | if (dtStatusFailed(status)) |
| 679 | return status; |
| 680 | |
| 681 | // Rasterize obstacles. |
| 682 | for (int i = 0; i < m_params.maxObstacles; ++i) |
| 683 | { |
| 684 | const dtTileCacheObstacle* ob = &m_obstacles[i]; |
| 685 | if (ob->state == DT_OBSTACLE_EMPTY || ob->state == DT_OBSTACLE_REMOVING) |
| 686 | continue; |
| 687 | if (contains(ob->touched, ob->ntouched, ref)) |
| 688 | { |
| 689 | if (ob->type == DT_OBSTACLE_CYLINDER) |
| 690 | { |
| 691 | dtMarkCylinderArea(*bc.layer, tile->header->bmin, m_params.cs, m_params.ch, |
| 692 | ob->cylinder.pos, ob->cylinder.radius, ob->cylinder.height, 0); |
| 693 | } |
| 694 | else if (ob->type == DT_OBSTACLE_BOX) |
| 695 | { |
| 696 | dtMarkBoxArea(*bc.layer, tile->header->bmin, m_params.cs, m_params.ch, |
| 697 | ob->box.bmin, ob->box.bmax, 0); |
| 698 | } |
| 699 | else if (ob->type == DT_OBSTACLE_ORIENTED_BOX) |
| 700 | { |
| 701 | dtMarkBoxArea(*bc.layer, tile->header->bmin, m_params.cs, m_params.ch, |
| 702 | ob->orientedBox.center, ob->orientedBox.halfExtents, ob->orientedBox.rotAux, 0); |
| 703 | } |
| 704 | } |
| 705 | } |
| 706 | |
| 707 | // Build navmesh |
| 708 | status = dtBuildTileCacheRegions(m_talloc, *bc.layer, walkableClimbVx); |
| 709 | if (dtStatusFailed(status)) |
| 710 | return status; |
| 711 | |
| 712 | bc.lcset = dtAllocTileCacheContourSet(m_talloc); |
| 713 | if (!bc.lcset) |
| 714 | return DT_FAILURE | DT_OUT_OF_MEMORY; |
no test coverage detected