JumpSegmentBuilder.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. using System;
  2. using System.Collections.Generic;
  3. using DotRecast.Core;
  4. namespace DotRecast.Detour.Extras.Jumplink
  5. {
  6. class JumpSegmentBuilder
  7. {
  8. public JumpSegment[] Build(JumpLinkBuilderConfig acfg, EdgeSampler es)
  9. {
  10. int n = es.end[0].gsamples.Length;
  11. int[][] sampleGrid = RcArrayUtils.Of<int>(n, es.end.Count);
  12. for (int j = 0; j < es.end.Count; j++)
  13. {
  14. for (int i = 0; i < n; i++)
  15. {
  16. sampleGrid[i][j] = -1;
  17. }
  18. }
  19. // Fill connected regions
  20. int region = 0;
  21. for (int j = 0; j < es.end.Count; j++)
  22. {
  23. for (int i = 0; i < n; i++)
  24. {
  25. if (sampleGrid[i][j] == -1)
  26. {
  27. GroundSample p = es.end[j].gsamples[i];
  28. if (!p.validTrajectory)
  29. {
  30. sampleGrid[i][j] = -2;
  31. }
  32. else
  33. {
  34. var queue = new Queue<int[]>();
  35. queue.Enqueue(new int[] { i, j });
  36. Fill(es, sampleGrid, queue, acfg.agentClimb, region);
  37. region++;
  38. }
  39. }
  40. }
  41. }
  42. JumpSegment[] jumpSegments = new JumpSegment[region];
  43. for (int i = 0; i < jumpSegments.Length; i++)
  44. {
  45. jumpSegments[i] = new JumpSegment();
  46. }
  47. // Find longest segments per region
  48. for (int j = 0; j < es.end.Count; j++)
  49. {
  50. int l = 0;
  51. int r = -2;
  52. for (int i = 0; i < n + 1; i++)
  53. {
  54. if (i == n || sampleGrid[i][j] != r)
  55. {
  56. if (r >= 0)
  57. {
  58. if (jumpSegments[r].samples < l)
  59. {
  60. jumpSegments[r].samples = l;
  61. jumpSegments[r].startSample = i - l;
  62. jumpSegments[r].groundSegment = j;
  63. }
  64. }
  65. if (i < n)
  66. {
  67. r = sampleGrid[i][j];
  68. }
  69. l = 1;
  70. }
  71. else
  72. {
  73. l++;
  74. }
  75. }
  76. }
  77. return jumpSegments;
  78. }
  79. private void Fill(EdgeSampler es, int[][] sampleGrid, Queue<int[]> queue, float agentClimb, int region)
  80. {
  81. while (queue.TryDequeue(out var ij))
  82. {
  83. int i = ij[0];
  84. int j = ij[1];
  85. if (sampleGrid[i][j] == -1)
  86. {
  87. GroundSample p = es.end[j].gsamples[i];
  88. sampleGrid[i][j] = region;
  89. float h = p.p.y;
  90. if (i < sampleGrid.Length - 1)
  91. {
  92. AddNeighbour(es, queue, agentClimb, h, i + 1, j);
  93. }
  94. if (i > 0)
  95. {
  96. AddNeighbour(es, queue, agentClimb, h, i - 1, j);
  97. }
  98. if (j < sampleGrid[0].Length - 1)
  99. {
  100. AddNeighbour(es, queue, agentClimb, h, i, j + 1);
  101. }
  102. if (j > 0)
  103. {
  104. AddNeighbour(es, queue, agentClimb, h, i, j - 1);
  105. }
  106. }
  107. }
  108. }
  109. private void AddNeighbour(EdgeSampler es, Queue<int[]> queue, float agentClimb, float h, int i, int j)
  110. {
  111. GroundSample q = es.end[j].gsamples[i];
  112. if (q.validTrajectory && Math.Abs(q.p.y - h) < agentClimb)
  113. {
  114. queue.Enqueue(new int[] { i, j });
  115. }
  116. }
  117. }
  118. }