forked from Fast-64/fast64
-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathpathways.py
More file actions
119 lines (92 loc) · 3.94 KB
/
Copy pathpathways.py
File metadata and controls
119 lines (92 loc) · 3.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
from dataclasses import dataclass, field
from mathutils import Matrix
from bpy.types import Object
from ....utility import PluginError, CData, indent, writeXMLData
from ...oot_utility import getObjectList
from ..utility import Utility
@dataclass
class Path:
"""This class defines a pathway"""
name: str
points: list[tuple[int, int, int]] = field(default_factory=list)
def getC(self):
"""Returns the pathway position array"""
pathData = CData()
pathName = f"Vec3s {self.name}"
# .h
pathData.header = f"extern {pathName}[];\n"
# .c
pathData.source = (
f"{pathName}[]"
+ " = {\n"
+ "\n".join(
indent + "{ " + ", ".join(f"{round(curPoint):5}" for curPoint in point) + " }," for point in self.points
)
+ "\n};\n\n"
)
return pathData
def getXML(self):
"""Returns the pathway position list as an XML ``str``"""
data = "<Pathway>\n"
pathDataElement = indent * 1 + "<PathDataElement>\n"
for point in self.points:
pointData = indent * 2 + "<Point "
pointData += f"X='{round(point.x):5}' "
pointData += f"Y='{round(point.y):5}' "
pointData += f"Z='{round(point.z):5}'/>\n"
pathDataElement += pointData
data += pathDataElement
data += "</Pathway>\n"
@dataclass
class ScenePathways:
"""This class hosts pathways array data"""
name: str
pathList: list[Path]
@staticmethod
def new(name: str, sceneObj: Object, transform: Matrix, headerIndex: int):
pathFromIndex: dict[int, Path] = {}
pathObjList = getObjectList(sceneObj.children_recursive, "CURVE", splineType="Path")
for obj in pathObjList:
relativeTransform = transform @ sceneObj.matrix_world.inverted() @ obj.matrix_world
pathProps = obj.ootSplineProperty
isHeaderValid = Utility.isCurrentHeaderValid(pathProps.headerSettings, headerIndex)
if isHeaderValid and Utility.validateCurveData(obj):
if pathProps.index not in pathFromIndex:
pathFromIndex[pathProps.index] = Path(
f"{name}List{pathProps.index:02}",
[relativeTransform @ point.co.xyz for point in obj.data.splines[0].points],
)
else:
raise PluginError(f"ERROR: Path index already used ({obj.name})")
pathFromIndex = dict(sorted(pathFromIndex.items()))
if list(pathFromIndex.keys()) != list(range(len(pathFromIndex))):
raise PluginError("ERROR: Path indices are not consecutive!")
return ScenePathways(name, list(pathFromIndex.values()))
def getCmd(self):
"""Returns the path list scene command"""
return indent + f"SCENE_CMD_PATH_LIST({self.name}),\n" if len(self.pathList) > 0 else ""
def getC(self):
"""Returns a ``CData`` containing the C data of the pathway array"""
pathData = CData()
pathListData = CData()
listName = f"Path {self.name}[{len(self.pathList)}]"
# .h
pathListData.header = f"extern {listName};\n"
# .c
pathListData.source = listName + " = {\n"
for path in self.pathList:
pathListData.source += indent + "{ " + f"ARRAY_COUNTU({path.name}), {path.name}" + " },\n"
pathData.append(path.getC())
pathListData.source += "};\n\n"
pathData.append(pathListData)
return pathData
def getXML(self, dirPath):
"""Returns an XML ``str`` containing the data of the pathway array"""
data = "<Pathways>\n"
for path in self.pathList:
filePath = os.join(dirPath, path.name)
pathToXML = path.toXML()
writeXMLData(pathToXML, filePath)
data += indent * 1 + f"<Pathway FilePath='{filePath}'/>\n"
data += "</Pathways>\n"
return data