mirror of
https://github.com/Sneed-Group/Poodletooth-iLand
synced 2024-12-25 12:42:41 -06:00
126 lines
5.3 KiB
Python
126 lines
5.3 KiB
Python
|
from pandac.PandaModules import Vec3
|
||
|
# Utility functions that are useful to both AI and client CartesianGrid code
|
||
|
|
||
|
class CartesianGridBase:
|
||
|
def isValidZone(self, zoneId):
|
||
|
def checkBounds(self=self, zoneId=zoneId):
|
||
|
if ((zoneId < self.startingZone) or
|
||
|
(zoneId > self.startingZone + self.gridSize * self.gridSize - 1)):
|
||
|
return 0
|
||
|
return 1
|
||
|
if self.style == "Cartesian":
|
||
|
return checkBounds()
|
||
|
elif self.style == "CartesianStated":
|
||
|
if zoneId >= 0 and zoneId < self.startingZone:
|
||
|
return 1
|
||
|
else:
|
||
|
return checkBounds()
|
||
|
else:
|
||
|
return 0
|
||
|
|
||
|
def getZoneFromXYZ(self, pos, wantRowAndCol=False):
|
||
|
# NOTE: pos should be relative to our own grid origin
|
||
|
# Convert a 3d position to a zone
|
||
|
dx = self.cellWidth * self.gridSize * .5
|
||
|
x = pos[0] + dx
|
||
|
y = pos[1] + dx
|
||
|
col = x // self.cellWidth
|
||
|
row = y // self.cellWidth
|
||
|
# Compute which zone we are in
|
||
|
zoneId = int(self.startingZone + ((row * self.gridSize) + col))
|
||
|
|
||
|
if (wantRowAndCol):
|
||
|
return (zoneId,col,row)
|
||
|
else:
|
||
|
return zoneId
|
||
|
|
||
|
def getGridSizeFromSphereRadius(self, sphereRadius, cellWidth, gridRadius):
|
||
|
# NOTE: This ensures that the grid is at least a "gridRadius" number
|
||
|
# of cells larger than the trigger sphere that loads the grid. This
|
||
|
# gives us some room to start setting interest to the grid before we
|
||
|
# expect to see any objects on it.
|
||
|
sphereRadius = max(sphereRadius, gridRadius*cellWidth)
|
||
|
return 2 * (sphereRadius // cellWidth)
|
||
|
|
||
|
def getGridSizeFromSphere(self, sphereRadius, spherePos, cellWidth, gridRadius):
|
||
|
# NOTE: This ensures that the grid is at least a "gridRadius" number
|
||
|
# of cells larger than the trigger sphere that loads the grid. This
|
||
|
# gives us some room to start setting interest to the grid before we
|
||
|
# expect to see any objects on it.
|
||
|
xMax = abs(spherePos[0])+sphereRadius
|
||
|
yMax = abs(spherePos[1])+sphereRadius
|
||
|
sphereRadius = Vec3(xMax,yMax,0).length()
|
||
|
|
||
|
# sphereRadius = max(sphereRadius, gridRadius*cellWidth)
|
||
|
return max(2 * (sphereRadius // cellWidth), 1)
|
||
|
|
||
|
def getZoneCellOrigin(self, zoneId):
|
||
|
# It returns the origin of the zoneCell
|
||
|
# Origin is the top-left corner of zoneCell
|
||
|
dx = self.cellWidth * self.gridSize * .5
|
||
|
zone = zoneId - self.startingZone
|
||
|
row = zone // self.gridSize
|
||
|
col = zone % self.gridSize
|
||
|
x = col * self.cellWidth - dx
|
||
|
y = row * self.cellWidth - dx
|
||
|
|
||
|
return (x, y, 0)
|
||
|
|
||
|
def getZoneCellOriginCenter(self, zoneId):
|
||
|
# Variant of the getZoneCellOrigin. It
|
||
|
# returns the center of the zoneCell
|
||
|
dx = self.cellWidth * self.gridSize * .5
|
||
|
center = self.cellWidth * 0.5
|
||
|
zone = zoneId - self.startingZone
|
||
|
row = zone // self.gridSize
|
||
|
col = zone % self.gridSize
|
||
|
x = col * self.cellWidth - dx + center
|
||
|
y = row * self.cellWidth - dx + center
|
||
|
|
||
|
return (x, y, 0)
|
||
|
|
||
|
#--------------------------------------------------------------------------
|
||
|
# Function: utility function to get all zones in a ring of given radius
|
||
|
# around the given zoneId (so if given a zoneId 34342 and a
|
||
|
# radius of 3, a list of all zones exactly 3 grids away from
|
||
|
# zone 34342 will be returned)
|
||
|
# Parameters: zoneId, center zone to find surrounding zones of
|
||
|
# radius, how far from zoneId to find zones of for it them
|
||
|
# Changes:
|
||
|
# Returns:
|
||
|
#--------------------------------------------------------------------------
|
||
|
def getConcentricZones(self, zoneId, radius):
|
||
|
zones = []
|
||
|
#currZone = zoneId + radius
|
||
|
#numZones = (2 * radius * 8) + 2
|
||
|
# start at upper left
|
||
|
zone = zoneId - self.startingZone
|
||
|
row = zone // self.gridSize
|
||
|
col = zone % self.gridSize
|
||
|
|
||
|
leftOffset = min(col, radius)
|
||
|
rightOffset = min(self.gridSize - (col + 1), radius)
|
||
|
topOffset = min(row, radius)
|
||
|
bottomOffset = min(self.gridSize - (row + 1), radius)
|
||
|
|
||
|
#print "starting examination of grid circle of radius %s"%radius
|
||
|
ulZone = zoneId - leftOffset - topOffset * self.gridSize
|
||
|
#print "left offset is %s and radius is %s"%(leftOffset,radius)
|
||
|
for currCol in range(int(rightOffset + leftOffset + 1)):
|
||
|
if ((currCol == 0 and leftOffset == radius) or (currCol == rightOffset + leftOffset and rightOffset == radius)):
|
||
|
# at either left or right edge of area, look at all rows
|
||
|
possibleRows = range(int(bottomOffset + topOffset + 1))
|
||
|
else:
|
||
|
# in a middle column, only look at top and bottom rows
|
||
|
possibleRows = []
|
||
|
if (topOffset == radius):
|
||
|
possibleRows.append(0)
|
||
|
if (bottomOffset == radius):
|
||
|
possibleRows.append(bottomOffset + topOffset)
|
||
|
#print "on column %s and looking at rows %s"%(currCol,possibleRows)
|
||
|
for currRow in possibleRows:
|
||
|
newZone = ulZone + (currRow * self.gridSize) + currCol
|
||
|
zones.append(int(newZone))
|
||
|
#print " examining zone %s"%newZone
|
||
|
return zones
|