Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add the possibility to import course from the decomp of mk64 #316

Merged
merged 51 commits into from
Aug 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
a67236b
start add mk64 course importer
coco875 Feb 29, 2024
43c25b6
add the possibility to import course
coco875 Feb 29, 2024
ebe1688
remove unmodified function
coco875 Feb 29, 2024
758632c
Update panels.py
coco875 Feb 29, 2024
c41cbf2
reformat by using black
coco875 Feb 29, 2024
fe59e90
Update fast64_internal/mk64/__init__.py
coco875 Feb 29, 2024
230cd6f
Update fast64_internal/mk64/f3d_course_parser.py
coco875 Feb 29, 2024
a8eac6a
create MK64F3DContext class
coco875 Feb 29, 2024
6a3a2c1
Merge branch 'mk64' of https://github.com/coco875/fast64 into mk64
coco875 Feb 29, 2024
dfb910b
ok add a mk64/README.md and add getVertexDataStart as a method of F3D…
coco875 Feb 29, 2024
6002ab7
Merge remote-tracking branch 'upstream/main' into mk64
coco875 Feb 29, 2024
955e8e1
Update fast64_internal/mk64/__init__.py
coco875 Feb 29, 2024
0ebed47
add upgrade_changed_props
coco875 Feb 29, 2024
21630a1
Merge branch 'mk64' of https://github.com/coco875/fast64 into mk64
coco875 Feb 29, 2024
ee38f20
fix poll
coco875 Feb 29, 2024
bd0cea7
fix a bug and a error
coco875 Feb 29, 2024
6d0c13b
remove poll from MK64_ImportCourseDLPanel
coco875 Feb 29, 2024
4e77d46
add the options to enable render mode for course
coco875 Mar 2, 2024
a590c15
fix too short argument not be parse
coco875 Mar 4, 2024
b3b916e
change MK64_Properties
coco875 Mar 7, 2024
bd93561
Update f3d_parser.py
coco875 Mar 7, 2024
0e77021
update file who are rename in mk64
coco875 Apr 4, 2024
3d41cb6
Merge branch 'main' into mk64
coco875 Jun 20, 2024
97a0123
reformat with black
coco875 Jun 20, 2024
b4fedd2
fix an import
coco875 Jun 20, 2024
f24435e
Update fast64_internal/mk64/__init__.py
coco875 Jun 20, 2024
a4372f3
Update fast64_internal/mk64/f3d_course_parser.py
coco875 Jun 20, 2024
97230eb
Update fast64_internal/mk64/__init__.py
coco875 Jun 20, 2024
3df043d
Update fast64_internal/mk64/__init__.py
coco875 Jun 20, 2024
8b7e2dd
sort import
coco875 Jun 20, 2024
3d4722a
Update README.md
coco875 Jun 20, 2024
685da73
Update README.md
coco875 Jun 20, 2024
6fdf8d4
Update __init__.py
coco875 Jun 20, 2024
9abb003
Merge remote-tracking branch 'upstream/main' into mk64
coco875 Jul 29, 2024
5f520f8
Update __init__.py
coco875 Jul 29, 2024
fcc6d1a
add properties to mk64
coco875 Jul 29, 2024
f1119c0
rename properties field
coco875 Jul 29, 2024
bd80fb1
remove drawLayer
coco875 Jul 29, 2024
df47e6d
Update __init__.py
coco875 Jul 30, 2024
7541dba
fix enum of game problem
coco875 Jul 30, 2024
e73a86d
Update fast64_internal/mk64/f3d/properties.py
coco875 Jul 30, 2024
5e2964c
move MK64_ImportCourseDL to operators file
coco875 Jul 30, 2024
30f9030
format black
coco875 Jul 30, 2024
2a08f97
forget an import
coco875 Jul 30, 2024
edc0e7b
forget another import
coco875 Jul 30, 2024
77ac333
make some snake_case move panels and scale
coco875 Aug 1, 2024
6930776
fix black
coco875 Aug 1, 2024
f323083
fix snakke_case
coco875 Aug 1, 2024
76a5c64
rename to mk64_model_classes
coco875 Aug 1, 2024
f7d9d4d
Update operators.py
coco875 Aug 1, 2024
5684b13
forget a snake_case
coco875 Aug 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
from .fast64_internal.oot.props_panel_main import OOT_ObjectProperties
from .fast64_internal.utility_anim import utility_anim_register, utility_anim_unregister, ArmatureApplyWithMeshOperator

from .fast64_internal.mk64 import MK64_Properties, mk64_register, mk64_unregister

from .fast64_internal.f3d.f3d_material import (
F3D_MAT_CUR_VERSION,
mat_register,
Expand Down Expand Up @@ -61,9 +63,10 @@
}

gameEditorEnum = (
("SM64", "SM64", "Super Mario 64"),
("OOT", "OOT", "Ocarina Of Time"),
("Homebrew", "Homebrew", "Homebrew"),
("SM64", "SM64", "Super Mario 64", 0),
("OOT", "OOT", "Ocarina Of Time", 1),
("MK64", "MK64", "Mario Kart 64", 3),
("Homebrew", "Homebrew", "Homebrew", 2),
)


Expand Down Expand Up @@ -213,6 +216,7 @@ class Fast64_Properties(bpy.types.PropertyGroup):

sm64: bpy.props.PointerProperty(type=SM64_Properties, name="SM64 Properties")
oot: bpy.props.PointerProperty(type=OOT_Properties, name="OOT Properties")
mk64: bpy.props.PointerProperty(type=MK64_Properties, name="MK64 Properties")
settings: bpy.props.PointerProperty(type=Fast64Settings_Properties, name="Fast64 Settings")
renderSettings: bpy.props.PointerProperty(type=Fast64RenderSettings_Properties, name="Fast64 Render Settings")

Expand Down Expand Up @@ -315,6 +319,7 @@ def draw(self, context):
def upgrade_changed_props():
"""Set scene properties after a scene loads, used for migrating old properties"""
SM64_Properties.upgrade_changed_props()
MK64_Properties.upgrade_changed_props()
SM64_ObjectProperties.upgrade_changed_props()
OOT_ObjectProperties.upgrade_changed_props()
for scene in bpy.data.scenes:
Expand Down Expand Up @@ -352,6 +357,8 @@ def gameEditorUpdate(self, context):
self.f3d_type = "F3D"
elif self.gameEditorMode == "OOT":
self.f3d_type = "F3DEX2/LX2"
elif self.gameEditorMode == "MK64":
self.f3d_type = "F3DEX/LX"


# called on add-on enabling
Expand Down Expand Up @@ -381,6 +388,7 @@ def register():
bsdf_conv_register()
sm64_register(True)
oot_register(True)
mk64_register(True)

repo_settings_operators_register()

Expand Down Expand Up @@ -427,6 +435,7 @@ def unregister():
f3d_parser_unregister()
sm64_unregister(True)
oot_unregister(True)
mk64_unregister(True)
mat_unregister()
bsdf_conv_unregister()
bsdf_conv_panel_unregsiter()
Expand Down
29 changes: 14 additions & 15 deletions fast64_internal/f3d/f3d_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -1527,6 +1527,19 @@ def applyTLUT(self, image, tlut):
if invalidIndicesDetected:
print("Invalid LUT Indices detected.")

def getVertexDataStart(self, vertexDataParam: str, f3d: F3D):
matchResult = re.search(r"\&?([A-Za-z0-9\_]*)\s*(\[([^\]]*)\])?\s*(\+(.*))?", vertexDataParam)
if matchResult is None:
raise PluginError("SPVertex param " + vertexDataParam + " is malformed.")

offset = 0
if matchResult.group(3):
offset += math_eval(matchResult.group(3), f3d)
if matchResult.group(5):
offset += math_eval(matchResult.group(5), f3d)

return matchResult.group(1), offset

def processCommands(self, dlData: str, dlName: str, dlCommands: "list[ParsedMacro]"):
callStack = [F3DParsedCommands(dlName, dlCommands, 0)]
while len(callStack) > 0:
Expand All @@ -1540,7 +1553,7 @@ def processCommands(self, dlData: str, dlName: str, dlCommands: "list[ParsedMacr

# print(command.name + " " + str(command.params))
if command.name == "gsSPVertex":
vertexDataName, vertexDataOffset = getVertexDataStart(command.params[0], self.f3d)
vertexDataName, vertexDataOffset = self.getVertexDataStart(command.params[0], self.f3d)
parseVertexData(dlData, vertexDataName, self)
self.addVertices(command.params[1], command.params[2], vertexDataName, vertexDataOffset)
elif command.name == "gsSPMatrix":
Expand Down Expand Up @@ -1951,20 +1964,6 @@ def parseDLData(dlData: str, dlName: str):
return dlCommands


def getVertexDataStart(vertexDataParam: str, f3d: F3D):
matchResult = re.search(r"\&?([A-Za-z0-9\_]*)\s*(\[([^\]]*)\])?\s*(\+(.*))?", vertexDataParam)
if matchResult is None:
raise PluginError("SPVertex param " + vertexDataParam + " is malformed.")

offset = 0
if matchResult.group(3):
offset += math_eval(matchResult.group(3), f3d)
if matchResult.group(5):
offset += math_eval(matchResult.group(5), f3d)

return matchResult.group(1), offset


def parseVertexData(dlData: str, vertexDataName: str, f3dContext: F3DContext):
if vertexDataName in f3dContext.vertexData:
return f3dContext.vertexData[vertexDataName]
Expand Down
9 changes: 9 additions & 0 deletions fast64_internal/mk64/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Mario Kart 64

## Importing Course Display Lists
It's similar to the F3D Importer, you select the file where you have the display list, set the name of the display list you want to import and the path to the decomp. (by default courses are split in segments so it's better to use the cinematic version, usually the last display list in course_data.inc.c).

Example of configuration:
- d_course_wario_stadium_dl_CA78
- path/to/mk64/courses/wario_stadium/course_data.inc.c
- path/to/mk64
54 changes: 54 additions & 0 deletions fast64_internal/mk64/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import bpy
from bpy.props import FloatProperty
from bpy.types import PropertyGroup
from bpy.utils import register_class, unregister_class
from .f3d.properties import MK64CourseDLImportSettings, f3d_props_register, f3d_props_unregister
from .f3d.operators import MK64_ImportCourseDL
from .f3d.panels import MK64_ImportCourseDLPanel
from ..render_settings import on_update_render_settings


class MK64_Properties(PropertyGroup):
"""Global MK64 Scene Properties found under scene.fast64.mk64"""

# Import Course DL
course_DL_import_settings: bpy.props.PointerProperty(type=MK64CourseDLImportSettings)
scale: FloatProperty(name="F3D Blender Scale", default=100, update=on_update_render_settings)

@staticmethod
def upgrade_changed_props():
pass


mk64_classes = (MK64_Properties,)

mk64_panel_classes = (
MK64_ImportCourseDL,
MK64_ImportCourseDLPanel,
)


def mk64_panel_register():
for cls in mk64_panel_classes:
register_class(cls)


def mk64_panel_unregister():
for cls in mk64_panel_classes:
unregister_class(cls)


def mk64_register(registerPanels):
f3d_props_register()
for cls in mk64_classes:
register_class(cls)
if registerPanels:
mk64_panel_register()


def mk64_unregister(registerPanel):
for cls in reversed(mk64_classes):
unregister_class(cls)
if registerPanel:
mk64_panel_unregister()
f3d_props_unregister()
94 changes: 94 additions & 0 deletions fast64_internal/mk64/f3d/operators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import bpy
from bpy.types import Operator
from ..mk64_model_classes import MK64F3DContext, parse_course_vtx
from ...f3d.f3d_material import createF3DMat
from ...f3d.f3d_gbi import get_F3D_GBI
from ...f3d.f3d_parser import getImportData, importMeshC
from ...utility import raisePluginError
from .properties import MK64CourseDLImportSettings


class MK64_ImportCourseDL(Operator):
# set bl_ properties
bl_idname = "scene.fast64_mk64_course_import_dl"
bl_label = "Import Course DL"
bl_options = {"REGISTER", "UNDO", "PRESET"}

# Called on demand (i.e. button press, menu item)
# Can also be called from operator search menu (Spacebar)
def execute(self, context):
obj = None
if context.mode != "OBJECT":
bpy.ops.object.mode_set(mode="OBJECT")

try:
import_settings: MK64CourseDLImportSettings = context.scene.fast64.mk64.course_DL_import_settings
name = import_settings.name
import_path = bpy.path.abspath(import_settings.path)
base_path = bpy.path.abspath(import_settings.base_path)
scale_value = context.scene.fast64.mk64.scale

remove_doubles = import_settings.remove_doubles
import_normals = import_settings.import_normals
draw_layer = "Opaque"

paths = [import_path]

if "course_data" in import_path:
paths += [import_path.replace("course_data", "course_displaylists.inc")]

paths += [
import_path.replace("course_data", "course_textures.linkonly").replace(
"course_displaylists.inc", "course_textures.linkonly"
)
]

data = getImportData(paths)

material = createF3DMat(None)
f3d_mat = material.f3d_mat
f3d_mat.rdp_settings.set_rendermode = import_settings.enable_render_Mode_Default
f3d_mat.combiner1.A = "TEXEL0"
f3d_mat.combiner1.B = "0"
f3d_mat.combiner1.C = "SHADE"
f3d_mat.combiner1.D = "0"
f3d_mat.combiner1.A_alpha = "TEXEL0"
f3d_mat.combiner1.B_alpha = "0"
f3d_mat.combiner1.C_alpha = "SHADE"
f3d_mat.combiner1.D_alpha = "0"
f3d_mat.combiner2.name = ""
f3d_mat.combiner2.A = "TEXEL0"
f3d_mat.combiner2.B = "0"
f3d_mat.combiner2.C = "SHADE"
f3d_mat.combiner2.D = "0"
f3d_mat.combiner2.A_alpha = "TEXEL0"
f3d_mat.combiner2.B_alpha = "0"
f3d_mat.combiner2.C_alpha = "SHADE"
f3d_mat.combiner2.D_alpha = "0"

f3d_context = MK64F3DContext(get_F3D_GBI(), base_path, material)
if "course_displaylists" in import_path or "course_data" in import_path:
vertex_path = import_path.replace("course_displaylists.inc", "course_vertices.inc").replace(
"course_data", "course_vertices.inc"
)
print(vertex_path)
f3d_context.vertexData["0x4000000"] = parse_course_vtx(vertex_path, f3d_context.f3d)

importMeshC(
data,
name,
scale_value,
remove_doubles,
import_normals,
draw_layer,
f3d_context,
)

self.report({"INFO"}, "Success!")
return {"FINISHED"}

except Exception as e:
if context.mode != "OBJECT":
bpy.ops.object.mode_set(mode="OBJECT")
raisePluginError(self, e)
return {"CANCELLED"} # must return a set
25 changes: 25 additions & 0 deletions fast64_internal/mk64/f3d/panels.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from .properties import MK64CourseDLImportSettings
from .operators import MK64_ImportCourseDL
from ...panels import MK64_Panel
from ...utility import prop_split


class MK64_ImportCourseDLPanel(MK64_Panel):
bl_idname = "MK64_PT_import_course_DL"
bl_label = "MK64 Import Course DL"
bl_options = set() # default to open
bl_order = 0 # force to front

# called every frame
def draw(self, context):
col = self.layout.column()
col.scale_y = 1.1 # extra padding

col.operator(MK64_ImportCourseDL.bl_idname)
course_DL_import_settings: MK64CourseDLImportSettings = context.scene.fast64.mk64.course_DL_import_settings
course_DL_import_settings.draw_props(col)
prop_split(col, context.scene.fast64.mk64, "scale", "Scale")

box = col.box().column()
box.label(text="All data must be contained within file.")
box.label(text="The only exception are pngs converted to inc.c.")
38 changes: 38 additions & 0 deletions fast64_internal/mk64/f3d/properties.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from bpy.props import StringProperty, BoolProperty
from bpy.types import PropertyGroup, UILayout
from bpy.utils import register_class, unregister_class
from ...utility import prop_split
from ...f3d.f3d_material import ootEnumDrawLayers


class MK64CourseDLImportSettings(PropertyGroup):
name: StringProperty(name="Name")
path: StringProperty(name="Directory", subtype="FILE_PATH")
base_path: StringProperty(name="Directory", subtype="FILE_PATH")
remove_doubles: BoolProperty(name="Remove Doubles", default=True)
import_normals: BoolProperty(name="Import Normals", default=True)
enable_render_Mode_Default: BoolProperty(name="Set Render Mode by Default", default=True)

def draw_props(self, layout: UILayout):
prop_split(layout, self, "name", "Name")
prop_split(layout, self, "path", "File")
prop_split(layout, self, "base_path", "Base Path")
layout.prop(self, "remove_doubles")
layout.prop(self, "import_normals")

layout.prop(self, "enable_render_Mode_Default")


mk64_dl_writer_classes = [
MK64CourseDLImportSettings,
]


def f3d_props_register():
for cls in mk64_dl_writer_classes:
register_class(cls)


def f3d_props_unregister():
for cls in reversed(mk64_dl_writer_classes):
unregister_class(cls)
56 changes: 56 additions & 0 deletions fast64_internal/mk64/mk64_model_classes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import re
from mathutils import Vector
from ..f3d.f3d_gbi import F3D
from ..f3d.f3d_parser import F3DContext, math_eval
from ..f3d.f3d_writer import F3DVert
from ..utility import PluginError, readFile, unpackNormal


def course_vertex_format_patterns():
# position, uv, color/normal
return (
# decomp format
r"\{\s*"
r"\{+([^,\}]*),([^,\}]*),([^,\}]*)\}\s*,\s*"
r"\{([^,\}]*),([^,\}]*)\}\s*,\s*"
r"\{MACRO_COLOR_FLAG\(([^,\}]*),([^,\}]*),([^,\}]*),([^,\}])*\),([^,\}]*)\}\s*"
r"\}"
)


def parse_course_vtx(path: str, f3d):
data = readFile(path)
pattern = course_vertex_format_patterns()
vertexData = []
for values in re.findall(pattern, data, re.DOTALL):
values = [math_eval(g, f3d) for g in values]
vertexData.append(
F3DVert(
Vector(values[0:3]),
Vector(values[3:5]),
Vector(values[5:8]),
unpackNormal(values[8]),
values[9],
)
)
return vertexData


class MK64F3DContext(F3DContext):
def getVertexDataStart(self, vertexDataParam: str, f3d: F3D):
matchResult = re.search(r"\&?([A-Za-z0-9\_]*)\s*(\[([^\]]*)\])?\s*(\+(.*))?", vertexDataParam)
if matchResult is None:
raise PluginError(f"SPVertex param {vertexDataParam} is malformed.")

offset = 0
if matchResult.group(3):
offset += math_eval(matchResult.group(3), f3d)
if matchResult.group(5):
offset += math_eval(matchResult.group(5), f3d)

name = matchResult.group(1)

if matchResult.group(1).startswith("0x04"):
offset = (int(matchResult.group(1), 16) - 0x04000000) // 16
name = hex(0x04000000)
return name, offset
Loading
Loading