CartesianGridBase.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. from pandac.PandaModules import Vec3
  2. # Utility functions that are useful to both AI and client CartesianGrid code
  3. class CartesianGridBase:
  4. def isValidZone(self, zoneId):
  5. def checkBounds(self=self, zoneId=zoneId):
  6. if ((zoneId < self.startingZone) or
  7. (zoneId > self.startingZone + self.gridSize * self.gridSize - 1)):
  8. return 0
  9. return 1
  10. if self.style == "Cartesian":
  11. return checkBounds()
  12. elif self.style == "CartesianStated":
  13. if zoneId >= 0 and zoneId < self.startingZone:
  14. return 1
  15. else:
  16. return checkBounds()
  17. else:
  18. return 0
  19. def getZoneFromXYZ(self, pos, wantRowAndCol=False):
  20. # NOTE: pos should be relative to our own grid origin
  21. # Convert a 3d position to a zone
  22. dx = self.cellWidth * self.gridSize * .5
  23. x = pos[0] + dx
  24. y = pos[1] + dx
  25. col = x // self.cellWidth
  26. row = y // self.cellWidth
  27. # Compute which zone we are in
  28. zoneId = int(self.startingZone + ((row * self.gridSize) + col))
  29. if (wantRowAndCol):
  30. return (zoneId,col,row)
  31. else:
  32. return zoneId
  33. def getGridSizeFromSphereRadius(self, sphereRadius, cellWidth, gridRadius):
  34. # NOTE: This ensures that the grid is at least a "gridRadius" number
  35. # of cells larger than the trigger sphere that loads the grid. This
  36. # gives us some room to start setting interest to the grid before we
  37. # expect to see any objects on it.
  38. sphereRadius = max(sphereRadius, gridRadius*cellWidth)
  39. return 2 * (sphereRadius // cellWidth)
  40. def getGridSizeFromSphere(self, sphereRadius, spherePos, cellWidth, gridRadius):
  41. # NOTE: This ensures that the grid is at least a "gridRadius" number
  42. # of cells larger than the trigger sphere that loads the grid. This
  43. # gives us some room to start setting interest to the grid before we
  44. # expect to see any objects on it.
  45. xMax = abs(spherePos[0])+sphereRadius
  46. yMax = abs(spherePos[1])+sphereRadius
  47. sphereRadius = Vec3(xMax,yMax,0).length()
  48. # sphereRadius = max(sphereRadius, gridRadius*cellWidth)
  49. return max(2 * (sphereRadius // cellWidth), 1)
  50. def getZoneCellOrigin(self, zoneId):
  51. # It returns the origin of the zoneCell
  52. # Origin is the top-left corner of zoneCell
  53. dx = self.cellWidth * self.gridSize * .5
  54. zone = zoneId - self.startingZone
  55. row = zone // self.gridSize
  56. col = zone % self.gridSize
  57. x = col * self.cellWidth - dx
  58. y = row * self.cellWidth - dx
  59. return (x, y, 0)
  60. def getZoneCellOriginCenter(self, zoneId):
  61. # Variant of the getZoneCellOrigin. It
  62. # returns the center of the zoneCell
  63. dx = self.cellWidth * self.gridSize * .5
  64. center = self.cellWidth * 0.5
  65. zone = zoneId - self.startingZone
  66. row = zone // self.gridSize
  67. col = zone % self.gridSize
  68. x = col * self.cellWidth - dx + center
  69. y = row * self.cellWidth - dx + center
  70. return (x, y, 0)
  71. #--------------------------------------------------------------------------
  72. # Function: utility function to get all zones in a ring of given radius
  73. # around the given zoneId (so if given a zoneId 34342 and a
  74. # radius of 3, a list of all zones exactly 3 grids away from
  75. # zone 34342 will be returned)
  76. # Parameters: zoneId, center zone to find surrounding zones of
  77. # radius, how far from zoneId to find zones of for it them
  78. # Changes:
  79. # Returns:
  80. #--------------------------------------------------------------------------
  81. def getConcentricZones(self, zoneId, radius):
  82. zones = []
  83. #currZone = zoneId + radius
  84. #numZones = (2 * radius * 8) + 2
  85. # start at upper left
  86. zone = zoneId - self.startingZone
  87. row = zone // self.gridSize
  88. col = zone % self.gridSize
  89. leftOffset = min(col, radius)
  90. rightOffset = min(self.gridSize - (col + 1), radius)
  91. topOffset = min(row, radius)
  92. bottomOffset = min(self.gridSize - (row + 1), radius)
  93. #print "starting examination of grid circle of radius %s"%radius
  94. ulZone = zoneId - leftOffset - topOffset * self.gridSize
  95. #print "left offset is %s and radius is %s"%(leftOffset,radius)
  96. for currCol in range(int(rightOffset + leftOffset + 1)):
  97. if ((currCol == 0 and leftOffset == radius) or (currCol == rightOffset + leftOffset and rightOffset == radius)):
  98. # at either left or right edge of area, look at all rows
  99. possibleRows = range(int(bottomOffset + topOffset + 1))
  100. else:
  101. # in a middle column, only look at top and bottom rows
  102. possibleRows = []
  103. if (topOffset == radius):
  104. possibleRows.append(0)
  105. if (bottomOffset == radius):
  106. possibleRows.append(bottomOffset + topOffset)
  107. #print "on column %s and looking at rows %s"%(currCol,possibleRows)
  108. for currRow in possibleRows:
  109. newZone = ulZone + (currRow * self.gridSize) + currCol
  110. zones.append(int(newZone))
  111. #print " examining zone %s"%newZone
  112. return zones