Skip to content

Commit

Permalink
lvl parser reorg
Browse files Browse the repository at this point in the history
  • Loading branch information
Yanis002 committed Jul 14, 2023
1 parent d97dcd2 commit de8aa98
Show file tree
Hide file tree
Showing 14 changed files with 1,575 additions and 1,497 deletions.
1,496 changes: 0 additions & 1,496 deletions fast64_internal/oot/oot_level_parser.py

This file was deleted.

1 change: 1 addition & 0 deletions fast64_internal/oot/scene/importer/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .scene import parseScene
197 changes: 197 additions & 0 deletions fast64_internal/oot/scene/importer/actor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
import re
import bpy

from ....utility import parentObject, hexOrDecInt
from ...scene.properties import OOTSceneHeaderProperty
from ...oot_utility import setCustomProperty, getEvalParams
from ...oot_constants import ootEnumCamTransition, ootData
from .classes import SharedSceneData
from .constants import actorsWithRotAsParam

from .utility import (
getDataMatch,
createEmptyWithTransform,
getDisplayNameFromActorID,
handleActorWithRotAsParam,
unsetAllHeadersExceptSpecified,
)


def parseTransActorList(
roomObjs: list[bpy.types.Object],
sceneData: str,
transActorListName: str,
sharedSceneData: SharedSceneData,
headerIndex: int,
):
transitionActorList = getDataMatch(sceneData, transActorListName, "TransitionActorEntry", "transition actor list")

regex = r"(?:\{(.*?)\}\s*,)|(?:\{([a-zA-Z0-9\-_.,{}\s]*[^{]*)\},)"
for actorMatch in re.finditer(regex, transitionActorList):
actorMatch = actorMatch.group(0).replace(" ", "").replace("\n", "").replace("{", "").replace("}", "")

params = [value.strip() for value in actorMatch.split(",") if value.strip() != ""]

position = tuple([hexOrDecInt(value) for value in params[5:8]])

rotY = getEvalParams(params[8]) if "DEG_TO_BINANG" in params[8] else params[8]
rotation = tuple([0, hexOrDecInt(rotY), 0])

roomIndexFront = hexOrDecInt(params[0])
camFront = params[1]
roomIndexBack = hexOrDecInt(params[2])
camBack = params[3]
actorID = params[4]
actorParam = params[9]

actorHash = (
roomIndexFront,
camFront,
roomIndexBack,
camBack,
actorID,
position,
rotation,
actorParam,
)
if not sharedSceneData.addHeaderIfItemExists(actorHash, "Transition Actor", headerIndex):
actorObj = createEmptyWithTransform(position, [0, 0, 0] if actorID in actorsWithRotAsParam else rotation)
actorObj.ootEmptyType = "Transition Actor"
actorObj.name = "Transition " + getDisplayNameFromActorID(params[4])
transActorProp = actorObj.ootTransitionActorProperty

sharedSceneData.transDict[actorHash] = actorObj

if roomIndexFront != 255:
parentObject(roomObjs[roomIndexFront], actorObj)
transActorProp.roomIndex = roomIndexBack
else:
parentObject(roomObjs[roomIndexBack], actorObj)
transActorProp.dontTransition = True

setCustomProperty(transActorProp, "cameraTransitionFront", camFront, ootEnumCamTransition)
setCustomProperty(transActorProp, "cameraTransitionBack", camBack, ootEnumCamTransition)

actorProp = transActorProp.actor
setCustomProperty(actorProp, "actorID", actorID, ootData.actorData.ootEnumActorID)
actorProp.actorParam = actorParam
handleActorWithRotAsParam(actorProp, actorID, rotation)
unsetAllHeadersExceptSpecified(actorProp.headerSettings, headerIndex)


def parseEntranceList(
sceneHeader: OOTSceneHeaderProperty, roomObjs: list[bpy.types.Object], sceneData: str, entranceListName: str
):
entranceList = getDataMatch(sceneData, entranceListName, ["EntranceEntry", "Spawn"], "entrance List")

# see also start position list
entrances = []
for entranceMatch in re.finditer(rf"\{{(.*?)\}}\s*,", entranceList, flags=re.DOTALL):
params = [value.strip() for value in entranceMatch.group(1).split(",") if value.strip() != ""]
roomIndex = hexOrDecInt(params[1])
spawnIndex = hexOrDecInt(params[0])

entrances.append((spawnIndex, roomIndex))

if len(entrances) > 1 and entrances[-1] == (0, 0):
entrances.pop()
sceneHeader.appendNullEntrance = True

return entrances


def parseActorInfo(actorMatch: re.Match, nestedBrackets: bool) -> tuple[str, list[int], list[int], str]:
if nestedBrackets:
actorID = actorMatch.group(1).strip()
position = tuple(
[hexOrDecInt(value.strip()) for value in actorMatch.group(2).split(",") if value.strip() != ""]
)
rotation = tuple(
[
hexOrDecInt(getEvalParams(value.strip()))
for value in actorMatch.group(3).split(",")
if value.strip() != ""
]
)
actorParam = actorMatch.group(4).strip()
else:
params = [getEvalParams(value.strip()) for value in actorMatch.group(1).split(",")]
actorID = params[0]
position = tuple([hexOrDecInt(value) for value in params[1:4]])
rotation = tuple([hexOrDecInt(value) for value in params[4:7]])
actorParam = params[7]

return actorID, position, rotation, actorParam


def parseSpawnList(
roomObjs: list[bpy.types.Object],
sceneData: str,
spawnListName: str,
entranceList: list[tuple[str, str]],
sharedSceneData: SharedSceneData,
headerIndex: int,
):
# see also start position list
spawnList = getDataMatch(sceneData, spawnListName, "ActorEntry", "spawn list")
index = 0
regex, nestedBrackets = getActorRegex(spawnList)
for spawnMatch in re.finditer(regex, spawnList, flags=re.DOTALL):
actorID, position, rotation, actorParam = parseActorInfo(spawnMatch, nestedBrackets)
spawnIndex, roomIndex = [value for value in entranceList if value[0] == index][0]
actorHash = (actorID, position, rotation, actorParam, spawnIndex, roomIndex)

if not sharedSceneData.addHeaderIfItemExists(actorHash, "Entrance", headerIndex):
spawnObj = createEmptyWithTransform(position, [0, 0, 0] if actorID in actorsWithRotAsParam else rotation)
spawnObj.ootEmptyType = "Entrance"
spawnObj.name = "Entrance"
spawnProp = spawnObj.ootEntranceProperty
spawnProp.spawnIndex = spawnIndex
spawnProp.customActor = actorID != "ACTOR_PLAYER"
actorProp = spawnProp.actor
setCustomProperty(actorProp, "actorID", actorID, ootData.actorData.ootEnumActorID)
actorProp.actorParam = actorParam
handleActorWithRotAsParam(actorProp, actorID, rotation)
unsetAllHeadersExceptSpecified(actorProp.headerSettings, headerIndex)

sharedSceneData.entranceDict[actorHash] = spawnObj

parentObject(roomObjs[roomIndex], spawnObj)
index += 1


def getActorRegex(actorList: list[str]):
nestedBrackets = re.search(r"\{[^\}]*\{", actorList) is not None
if nestedBrackets:
regex = r"\{(.*?),\s*\{(.*?)\}\s*,\s*\{(.*?)\}\s*,(.*?)\}\s*,"
else:
regex = r"\{(.*?)\}\s*,"

return regex, nestedBrackets


def parseActorList(
roomObj: bpy.types.Object, sceneData: str, actorListName: str, sharedSceneData: SharedSceneData, headerIndex: int
):
actorList = getDataMatch(sceneData, actorListName, "ActorEntry", "actor list")
regex, nestedBrackets = getActorRegex(actorList)

for actorMatch in re.finditer(regex, actorList, flags=re.DOTALL):
actorHash = parseActorInfo(actorMatch, nestedBrackets) + (roomObj.ootRoomHeader.roomIndex,)

if not sharedSceneData.addHeaderIfItemExists(actorHash, "Actor", headerIndex):
actorID, position, rotation, actorParam, roomIndex = actorHash

actorObj = createEmptyWithTransform(position, [0, 0, 0] if actorID in actorsWithRotAsParam else rotation)
actorObj.ootEmptyType = "Actor"
actorObj.name = getDisplayNameFromActorID(actorID)
actorProp = actorObj.ootActorProperty

setCustomProperty(actorProp, "actorID", actorID, ootData.actorData.ootEnumActorID)
actorProp.actorParam = actorParam
handleActorWithRotAsParam(actorProp, actorID, rotation)
unsetAllHeadersExceptSpecified(actorProp.headerSettings, headerIndex)

sharedSceneData.actorDict[actorHash] = actorObj

parentObject(roomObj, actorObj)
59 changes: 59 additions & 0 deletions fast64_internal/oot/scene/importer/classes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from ....utility import PluginError
from ...oot_utility import getHeaderSettings
from .constants import headerNames


class SharedSceneData:
def __init__(
self,
scenePath: str,
includeMesh: bool,
includeCollision: bool,
includeActors: bool,
includeCullGroups: bool,
includeLights: bool,
includeCameras: bool,
includePaths: bool,
includeWaterBoxes: bool,
):
self.actorDict = {} # actor hash : blender object
self.entranceDict = {} # actor hash : blender object
self.transDict = {} # actor hash : blender object
self.pathDict = {} # path hash : blender object

self.scenePath = scenePath
self.includeMesh = includeMesh
self.includeCollision = includeCollision
self.includeActors = includeActors
self.includeCullGroups = includeCullGroups
self.includeLights = includeLights
self.includeCameras = includeCameras
self.includePaths = includePaths
self.includeWaterBoxes = includeWaterBoxes

def addHeaderIfItemExists(self, hash, itemType: str, headerIndex: int):
if itemType == "Actor":
dictToAdd = self.actorDict
elif itemType == "Entrance":
dictToAdd = self.entranceDict
elif itemType == "Transition Actor":
dictToAdd = self.transDict
elif itemType == "Curve":
dictToAdd = self.pathDict
else:
raise PluginError(f"Invalid empty type for shared actor handling: {itemType}")

if hash not in dictToAdd:
return False

actorObj = dictToAdd[hash]
headerSettings = getHeaderSettings(actorObj)

if headerIndex < 4:
setattr(headerSettings, headerNames[headerIndex], True)
else:
cutsceneHeaders = headerSettings.cutsceneHeaders
if len([header for header in cutsceneHeaders if header.headerIndex == headerIndex]) == 0:
cutsceneHeaders.add().headerIndex = headerIndex

return True
25 changes: 25 additions & 0 deletions fast64_internal/oot/scene/importer/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
headerNames = ["childDayHeader", "childNightHeader", "adultDayHeader", "adultNightHeader"]

actorsWithRotAsParam = {
"ACTOR_EN_BOX": "Z",
"ACTOR_EN_WOOD02": "Z",
"ACTOR_DOOR_ANA": "Z",
"ACTOR_EN_ENCOUNT1": "Z",
"ACTOR_EN_MA1": "Z",
"ACTOR_EN_WONDER_ITEM": "Z",
"ACTOR_EN_WONDER_TALK": "Z",
"ACTOR_EN_WONDER_TALK2": "Z",
"ACTOR_OBJ_BEAN": "Z",
"ACTOR_EN_OKARINA_TAG": "Z",
"ACTOR_EN_GOROIWA": "Z",
"ACTOR_EN_DAIKU": "Z",
"ACTOR_EN_SIOFUKI": "XYZ",
"ACTOR_ELF_MSG2": "XYZ",
"ACTOR_OBJ_MAKEOSHIHIKI": "Z",
"ACTOR_EN_GELDB": "Z",
"ACTOR_OBJ_KIBAKO2": "XZ",
"ACTOR_EN_GO2": "Z",
"ACTOR_EN_KAKASI2": "Z",
"ACTOR_EN_KAKASI3": "Z",
"ACTOR_OBJ_TIMEBLOCK": "Z",
}
Loading

0 comments on commit de8aa98

Please sign in to comment.