Skip to content

Commit ef3d994

Browse files
committed
Kinda working A* - however, it doesn't yet give a path, for some reason, it only shows all explored nodes, before finding the end o.o
1 parent 686f009 commit ef3d994

File tree

3 files changed

+143
-74
lines changed

3 files changed

+143
-74
lines changed
Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,79 @@
1+
from copy import deepcopy
12
from typing import Dict, Set, List, Tuple
23
from Blobtory.Scripts.planet_former.NodeRef import NodeRef, NodeKey
4+
from queue import PriorityQueue
5+
from multipledispatch import dispatch
6+
7+
8+
def GetDist(pFrom: Tuple[float, float, float, float],
9+
pTo: Tuple[float, float, float, float]):
10+
return (abs(pFrom[0] - pTo[0]) +
11+
abs(pFrom[1] - pTo[1]) +
12+
abs(pFrom[2] - pTo[2]))
13+
14+
15+
def ReconstructPath(cameFrom: Dict[NodeRef, NodeKey], current: NodeKey):
16+
totalPath: List[Tuple[float, float, float, float]] = [current.point]
17+
for key in cameFrom.keys():
18+
current = cameFrom[key]
19+
totalPath.insert(0, current.point)
20+
21+
return totalPath
322

423

524
class AStar:
625
nodeDict: Dict
26+
keyList: List[NodeKey]
727

828
def __init__(self, nodeDict: Dict):
929
self.nodeDict = nodeDict
30+
self.keyList = list(self.nodeDict.keys())
31+
32+
def GetKeyNodeFromRef(self, p: NodeRef) -> NodeKey:
33+
return self.keyList[self.keyList.index(p.point)]
34+
35+
def GetKeyNodeFromPoint(self, p: Tuple[float, float, float, float]) -> NodeKey:
36+
return self.keyList[self.keyList.index(p)]
37+
38+
def GetH(self, p: NodeKey) -> float:
39+
return 1/p.weight
1040

1141
def GetPathFromTo(self,
1242
pFrom: Tuple[float, float, float, float],
1343
pTo: Tuple[float, float, float, float]
1444
) -> List[Tuple[float, float, float, float]]:
15-
neighboursNeighbourPoints = []
45+
startNode = self.GetKeyNodeFromPoint(pFrom)
46+
47+
openSet = PriorityQueue()
48+
openSet.put((0, startNode))
49+
cameFrom: Dict[NodeRef, NodeKey] = {}
50+
51+
gScore = {nodeKey: float("inf") for nodeKey in self.nodeDict.keys()}
52+
gScore[pFrom] = 0
53+
54+
fScore = deepcopy(gScore)
55+
fScore[pFrom] = self.GetH(startNode)
56+
57+
openSetTable = {startNode}
58+
59+
while not openSet.empty():
60+
setVal = openSet.get()
61+
current: NodeKey = setVal[1]
62+
openSetTable.remove(current)
1663

17-
neighbourPointsTo: Set[NodeRef] = self.nodeDict[pTo]
18-
neighbourPointsFrom: Set[NodeRef] = self.nodeDict[pFrom]
64+
if current == pTo:
65+
return ReconstructPath(cameFrom, current)
1966

20-
for point in neighbourPointsTo:
21-
# keyList = list(self.nodeDict.keys())
22-
# print(keyList[keyList.index(point)].point)
23-
points = self.nodeDict[point]
24-
neighboursNeighbourPoints.extend([point.point for point in points])
67+
neighbourPoints: Set[NodeRef] = self.nodeDict[current]
68+
for neighbourPoint in neighbourPoints:
69+
tentativeGScore = gScore[current] + GetDist(current.point, neighbourPoint.point)
2570

26-
for point in neighbourPointsFrom:
27-
points = self.nodeDict[point]
28-
neighboursNeighbourPoints.extend([point.point for point in points])
71+
if tentativeGScore < gScore[neighbourPoint]:
72+
cameFrom[neighbourPoint] = current
73+
gScore[neighbourPoint] = tentativeGScore
74+
fScore[neighbourPoint] = gScore[neighbourPoint] + self.GetH(self.GetKeyNodeFromRef(neighbourPoint))
75+
if neighbourPoint not in openSetTable:
76+
openSet.put((fScore[neighbourPoint], neighbourPoint))
77+
openSetTable.add(neighbourPoint)
2978

30-
return neighboursNeighbourPoints
79+
return []

Blobtory/Scripts/planet_former/NodeRef.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ def __getitem__(self, key):
1414
def __eq__(self, other):
1515
return hash(self) == hash(other)
1616

17+
def __str__(self):
18+
return str(self.point)
19+
20+
def __repr__(self):
21+
return str(self.point)
22+
1723

1824
class NodeKey:
1925
point: (float, float, float, float)
@@ -29,4 +35,10 @@ def __getitem__(self, key):
2935
return self.point[key]
3036

3137
def __eq__(self, other):
32-
return hash(self) == hash(other)
38+
return hash(self) == hash(other)
39+
40+
def __str__(self):
41+
return str(self.point)
42+
43+
def __repr__(self):
44+
return str(self.point)

Blobtory/Scripts/planet_former/PlanetGenerator.py

Lines changed: 69 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
class PlanetGenerator:
1818
shouldUpdatePhysicsMeshes = False
1919
aStarHandler: AStar
20+
listOfItems = None
21+
examplePointFrom: NodeKey
2022

2123
def __init__(self, winCreator: WindowCreator, gridSize: int, radius: float):
2224
self.radius = radius
@@ -58,6 +60,18 @@ def __init__(self, winCreator: WindowCreator, gridSize: int, radius: float):
5860
self.RegenPlanet()
5961
self.winCreator.base.taskMgr.doMethodLater(1, self.UpdatePhysicsMesh, "Planet Physics Updater")
6062

63+
self.winCreator.base.accept("r", self.NextPoint)
64+
65+
def NextPoint(self):
66+
examplePointTo: NodeKey = next(self.listOfItems)
67+
68+
self.sphere3.setPos(examplePointTo[0], examplePointTo[1], examplePointTo[2])
69+
PipelineInstancing.RenderThisModelAtVertexes(self.sphere1,
70+
self.aStarHandler.GetPathFromTo(
71+
self.examplePointFrom.point,
72+
examplePointTo.point),
73+
self.winCreator)
74+
6175
def RegenPlanet(self):
6276
self.winCreator.baseData.debuggerPlanetFormer.Inform("Regenerating planet")
6377
self.cubeformerNav.GenerateNoiseSphere(self.radius)
@@ -72,67 +86,61 @@ def UpdatePlanet(self):
7286

7387
def UpdatePhysicsMesh(self, task):
7488
if self.shouldUpdatePhysicsMeshes:
75-
# Generate marching
76-
self.marchingCubesNav.EdgeGenerator()
77-
self.marchingCubesNav.MarchCube()
78-
79-
# Extract Mesh Data (Tri Indexes and Vertexes)
80-
self.winCreator.base.graphicsEngine.extractTextureData(self.marchingCubesNav.edgeVertexBuffer,
81-
self.winCreator.base.win.gsg)
82-
ramImageVertex = self.marchingCubesNav.edgeVertexBuffer.getRamImage()
83-
output = np.frombuffer(ramImageVertex, dtype=np.float32)
84-
output: np.ndarray = output.reshape((self.marchingCubesNav.size[2],
85-
self.marchingCubesNav.size[1],
86-
self.marchingCubesNav.size[0]*3, 4))
87-
88-
self.winCreator.base.graphicsEngine.extractTextureData(self.marchingCubesNav.triangleBuffer,
89-
self.winCreator.base.win.gsg)
90-
ramImage = self.marchingCubesNav.triangleBuffer.getRamImage()
91-
outputTriangle = memoryview(ramImage).cast("i")
92-
93-
# Restructure that data to be a node network instead using a dictionary
94-
outputR = map(tuple, output.reshape((self.marchingCubesNav.size[0]*3 *
95-
self.marchingCubesNav.size[1] *
96-
self.marchingCubesNav.size[2], 4)))
97-
nodeDict = dict((NodeKey(el), set([])) for el in outputR)
98-
del outputR
99-
100-
buffer = np.empty(12, dtype=int)
101-
102-
triagIndexCount = self.marchingCubesNav.vertexCount * 4
103-
for count, x in enumerate(outputTriangle):
104-
buffer[count % 12] = x
105-
if count % 12 == 11:
106-
v1: NodeRef = NodeRef(tuple(output[buffer[2], buffer[1], buffer[0]]))
107-
v2: NodeRef = NodeRef(tuple(output[buffer[6], buffer[5], buffer[4]]))
108-
v3: NodeRef = NodeRef(tuple(output[buffer[10], buffer[9], buffer[8]]))
109-
110-
nodeDict[v1].add(v2)
111-
nodeDict[v1].add(v3)
112-
113-
nodeDict[v2].add(v1)
114-
nodeDict[v2].add(v3)
115-
116-
nodeDict[v3].add(v2)
117-
nodeDict[v3].add(v1)
118-
119-
if count > triagIndexCount:
120-
break
121-
listOfItems = (item[0] for item in nodeDict.items() if len(item[1]) > 0)
122-
123-
examplePointFrom: NodeKey = next(listOfItems)
124-
for i in range(128): next(listOfItems)
125-
examplePointTo: NodeKey = next(listOfItems)
126-
127-
self.sphere2.setPos(examplePointFrom[0], examplePointFrom[1], examplePointFrom[2])
128-
self.sphere3.setPos(examplePointTo[0], examplePointTo[1], examplePointTo[2])
129-
130-
self.aStarHandler = AStar(nodeDict)
131-
PipelineInstancing.RenderThisModelAtVertexes(self.sphere1,
132-
self.aStarHandler.GetPathFromTo(
133-
examplePointFrom.point,
134-
examplePointTo.point),
135-
self.winCreator)
89+
self.GenerateAStarPather()
13690

13791
self.shouldUpdatePhysicsMeshes = False
13892
return Task.again
93+
94+
def GenerateAStarPather(self):
95+
# Generate marching
96+
self.marchingCubesNav.EdgeGenerator()
97+
self.marchingCubesNav.MarchCube()
98+
99+
# Extract Mesh Data (Tri Indexes and Vertexes)
100+
self.winCreator.base.graphicsEngine.extractTextureData(self.marchingCubesNav.edgeVertexBuffer,
101+
self.winCreator.base.win.gsg)
102+
ramImageVertex = self.marchingCubesNav.edgeVertexBuffer.getRamImage()
103+
output = np.frombuffer(ramImageVertex, dtype=np.float32)
104+
output: np.ndarray = output.reshape((self.marchingCubesNav.size[2],
105+
self.marchingCubesNav.size[1],
106+
self.marchingCubesNav.size[0] * 3, 4))
107+
108+
self.winCreator.base.graphicsEngine.extractTextureData(self.marchingCubesNav.triangleBuffer,
109+
self.winCreator.base.win.gsg)
110+
ramImage = self.marchingCubesNav.triangleBuffer.getRamImage()
111+
outputTriangle = memoryview(ramImage).cast("i")
112+
113+
# Restructure that data to be a node network instead using a dictionary
114+
outputR = map(tuple, output.reshape((self.marchingCubesNav.size[0] * 3 *
115+
self.marchingCubesNav.size[1] *
116+
self.marchingCubesNav.size[2], 4)))
117+
nodeDict = dict((NodeKey(el), set([])) for el in outputR)
118+
del outputR
119+
120+
buffer = np.empty(12, dtype=int)
121+
122+
triagIndexCount = self.marchingCubesNav.vertexCount * 4
123+
for count, x in enumerate(outputTriangle):
124+
buffer[count % 12] = x
125+
if count % 12 == 11:
126+
v1: NodeRef = NodeRef(tuple(output[buffer[2], buffer[1], buffer[0]]))
127+
v2: NodeRef = NodeRef(tuple(output[buffer[6], buffer[5], buffer[4]]))
128+
v3: NodeRef = NodeRef(tuple(output[buffer[10], buffer[9], buffer[8]]))
129+
130+
nodeDict[v1].add(v2)
131+
nodeDict[v1].add(v3)
132+
133+
nodeDict[v2].add(v1)
134+
nodeDict[v2].add(v3)
135+
136+
nodeDict[v3].add(v2)
137+
nodeDict[v3].add(v1)
138+
139+
if count > triagIndexCount:
140+
break
141+
self.listOfItems = (item[0] for item in nodeDict.items() if len(item[1]) > 0)
142+
143+
self.examplePointFrom: NodeKey = next(self.listOfItems)
144+
self.sphere2.setPos(self.examplePointFrom[0], self.examplePointFrom[1], self.examplePointFrom[2])
145+
146+
self.aStarHandler = AStar(nodeDict)

0 commit comments

Comments
 (0)