Skip to content
Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
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
30 changes: 30 additions & 0 deletions fast64_internal/mk64/mk64_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,36 @@
"RAMP": 255,
}

enum_clip_types = [
("CLIP_NONE", "CLIP_NONE", "CLIP_NONE"),
("CLIP_DEFAULT", "CLIP_DEFAULT", "CLIP_DEFAULT"),
("CLIP_SINGLE_SIDED_WALL", "CLIP_SINGLE_SIDED_WALL", "CLIP_SINGLE_SIDED_WALL"),
("CLIP_SURFACE", "CLIP_SURFACE", "CLIP_SURFACE"),
("CLIP_DOUBLE_SIDED_WALL", "CLIP_DOUBLE_SIDED_WALL", "CLIP_DOUBLE_SIDED_WALL"),
]

CLIP_TYPE_ENUM = {
"CLIP_NONE": 0,
"CLIP_DEFAULT": 1,
"CLIP_SINGLE_SIDED_WALL": 2,
"CLIP_SURFACE": 3,
"CLIP_DOUBLE_SIDED_WALL": 4,
}

enum_draw_layer_types = [
("DRAW_INVISIBLE", "DRAW_INVISIBLE", "DRAW_INVISIBLE"),
("DRAW_OPAQUE", "DRAW_OPAQUE", "DRAW_OPAQUE"),
("DRAW_TRANSLUCENT", "DRAW_TRANSLUCENT", "DRAW_TRANSLUCENT"),
("DRAW_TRANSLUCENT_NO_ZBUFFER", "DRAW_TRANSLUCENT_NO_ZBUFFER", "DRAW_TRANSLUCENT_NO_ZBUFFER"),
]

DRAW_LAYER_ENUM = {
"DRAW_INVISIBLE": 0,
"DRAW_OPAQUE": 1,
"DRAW_TRANSLUCENT": 2,
"DRAW_TRANSLUCENT_NO_ZBUFFER": 3,
}

enum_actor_types = [
("Piranha_Plant", "Piranha Plant", "Piranha Plant"),
("Other", "Other", "Other"),
Expand Down
113 changes: 91 additions & 22 deletions fast64_internal/mk64/mk64_course.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
# ------------------------------------------------------------------------
from __future__ import annotations

from bpy.props import FloatVectorProperty
import bpy

import os, struct, math
from pathlib import Path
from mathutils import Vector, Euler, Matrix
from dataclasses import dataclass, fields

from .mk64_constants import MODEL_HEADER, SURFACE_TYPE_ENUM
from .mk64_constants import MODEL_HEADER, SURFACE_TYPE_ENUM, CLIP_TYPE_ENUM, DRAW_LAYER_ENUM
from .mk64_properties import MK64_ObjectProperties, MK64_CurveProperties

from ..f3d.f3d_writer import exportF3DCommon, getInfoDict, TriangleConverterInfo, saveStaticModel
Expand Down Expand Up @@ -53,12 +54,22 @@ class MK64_BpyCourse:

def __init__(self, course_root: bpy.types.Object):
self.root = course_root
self.log_file = os.path.join(os.path.expanduser("~"), "mk64_debug.txt")

def make_mk64_course_from_bpy(self, context: bpy.Types.Context, scale: float, mat_write_method: GfxMatWriteMethod):
def debug(self, message: str):
"""Append a message to the log file."""
timestamp = datetime.now().strftime("%H:%M:%S")
with open(self.log_file, "a") as f:
f.write(f"[{timestamp}] {message}\n")

def make_mk64_course_from_bpy(self, context: bpy.Types.Context, scale: float, mat_write_method: GfxMatWriteMethod, logging_func):
"""
Creates a MK64_fModel class with all model data ready to exported to c
also generates lists for items, pathing and collision (in future)
"""

logging_func({'INFO'}, "IS IT WORKING?!?!?!?")

fModel = MK64_fModel(self.root, mat_write_method)
# create duplicate objects to export from
transform = Matrix.Diagonal(Vector((scale, scale, scale))).to_4x4()
Expand All @@ -69,13 +80,34 @@ def make_mk64_course_from_bpy(self, context: bpy.Types.Context, scale: float, ma

# retrieve data for items and pathing
def loop_children(obj, fModel, parent_transform):
logging_func({'INFO'},"LOOPING OVER OBJECTS!")
for child in obj.children:
if child.type == "MESH":
self.export_f3d_from_obj(context, child, fModel, parent_transform @ child.matrix_local)
if self.is_mk64_actor(child):
self.add_actor(child, parent_transform, fModel)
if child.type == "CURVE":
self.add_path(child, parent_transform, fModel)
splines = child.data.splines
if not splines:
return

if len(splines) > 1:
self.report(
{'WARNING'},
f"Curve '{child.name}' has multiple splines. Only the first will be exported."
)

spline = splines[0]
logging_func({'INFO'}, f"Checking child: {child.name}, type: {child.type}")
logging_func({'INFO'}, f"spline type: {spline.type}")

if spline.type == 'BEZIER':
logging_func({'INFO'},"FOUND BEZIER")
self.add_curve(child, parent_transform, fModel)
elif spline.type == 'NURBS':
logging_func({'INFO'},"FOUND NURBS")
self.add_path(child, parent_transform, fModel, logging_func)

if child.children:
loop_children(child, fModel, parent_transform @ child.matrix_local)

Expand All @@ -93,7 +125,7 @@ def add_actor(self, obj: bpy.Types.Object, transform: Matrix, fModel: FModel):
fModel.actors.append(MK64_Actor(position, mk64_props.actor_type))
return

def add_path(self, obj: bpy.Types.Object, transform: Matrix, fModel: FModel):
def add_curve(self, obj: bpy.Types.Object, transform: Matrix, fModel: FModel):
curve_data = obj.data

points = []
Expand All @@ -120,17 +152,60 @@ def add_path(self, obj: bpy.Types.Object, transform: Matrix, fModel: FModel):
fModel.path.append(MK64_Path(points))
return

def add_path(self, obj: bpy.types.Object, transform: Matrix, fModel: FModel, logging_func):
logging_func({'INFO'},"MAKING PATH")
depsgraph = bpy.context.evaluated_depsgraph_get()

logging_func({'INFO'},"GOT GRAPH")
eval_obj = obj.evaluated_get(depsgraph)
logging_func({'INFO'},"EVALULATE GRAPH")
mesh = eval_obj.to_mesh(preserve_all_data_layers=True, depsgraph=bpy.context.evaluated_depsgraph_get())
logging_func({'INFO'},"OBJ TO MESH")
if not mesh:
logging_func({'INFO'},"NO MESH")
return

points = []
logging_func({'INFO'},"Mesh Len " + str(len(mesh.vertices)))
for v in mesh.vertices:
world_pos = transform @ eval_obj.matrix_world @ v.co
points.append((
int(round(world_pos.x)),
int(round(world_pos.y)),
int(round(world_pos.z)),
0,
))

eval_obj.to_mesh_clear()

if points:
fModel.path.append(MK64_Path(points))

# look into speeding this up by calculating just the apprent
# transform using transformMatrix vs clearing parent and applying
# transform
def export_f3d_from_obj(
self, context: bpy.Types.Context, obj: bpy.types.Object, fModel: MK64_fModel, transformMatrix: Matrix
):
mk64_props: MK64_ObjectProperties = obj.fast64.mk64
mk_props: MK64_Properties = context.scene.fast64.mk64
if obj and obj.type == "MESH":
# Export as object


# Export as normal geometry
try:
with context.temp_override(active_object=obj, selected_objects=[obj]):
bpy.ops.object.parent_clear(type="CLEAR_KEEP_TRANSFORM")
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True, properties=False)
# Treat transparent objects like a normal object which means the position is exported.
# This is required for z-sort so that they are rendered over-top of each other correctly.
# Normal geometry is placed at 0,0,0 and the vertices are used for positionnig instead.
if mk64_props.draw_layer in {'DRAW_TRANSLUCENT', 'DRAW_TRANSLUCENT_NO_ZBUFFER'}:
mk64_props.location = obj.matrix_world.to_translation() * mk_props.scale
transformMatrix.translation = Vector((0.0, 0.0, 0.0))
bpy.ops.object.transform_apply(location=False, rotation=True, scale=True, properties=False)
else:
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True, properties=False)
infoDict = getInfoDict(obj)
triConverterInfo = TriangleConverterInfo(obj, None, fModel.f3d, transformMatrix, infoDict)
fMeshes = saveStaticModel(
Expand Down Expand Up @@ -167,18 +242,10 @@ def __init__(self, rt: bpy.types.Object, mat_write_method, name="mk64"):
# parent override so I can keep track of original mesh data
# to lookup collision data later
def onAddMesh(self, fMesh: FMesh, obj: bpy.Types.Object):
if not self.has_mk64_collision(obj):
return
mk64_props: MK64_ObjectProperties = obj.fast64.mk64
self.track_sections.append(MK64_TrackSection(fMesh.draw.name, mk64_props.col_type, 255, 0))
self.track_sections.append(MK64_TrackSection(fMesh.draw.name, mk64_props.surface_type, mk64_props.section_id, mk64_props.clip_type, mk64_props.draw_layer, mk64_props.location))
return

def has_mk64_collision(self, obj: bpy.Types.Object):
if obj.type != "MESH":
return False
mk64_props: MK64_ObjectProperties = obj.fast64.mk64
return mk64_props.has_col

def to_c(self, *args):
export_data = super().to_c(*args)
export_data.staticData.append(self.to_c_track_actors())
Expand Down Expand Up @@ -268,19 +335,17 @@ def to_xml_track_sections(self, *args):
if not self.track_sections:
return

lines.append("<TrackSections XMLSucks=\"1\">")
for i, section in enumerate(self.track_sections):

sections = "\n\t".join([
f"<Section gfx_path=\"{internal_path}/{section.gfx_list_name}\" surface=\"{SURFACE_TYPE_ENUM[section.surface_type]}\" section=\"{section.section_id:#04x}\" flags=\"{section.flags:#04x}\" />"
for section in self.track_sections
f"<Section gfx_path=\"{internal_path}/{section.gfx_list_name}\" surface=\"{SURFACE_TYPE_ENUM[section.surface_type]}\" section=\"{section.section_id:#04x}\" flags=\"{CLIP_TYPE_ENUM[section.clip]}\" drawlayer=\"{DRAW_LAYER_ENUM[section.drawLayer]}\" x=\"{section.location[0]:.6f}\" y=\"{section.location[1]:.6f}\" z=\"{section.location[2]:.6f}\" />"
])

lines.extend((
f"<TrackSections XMLSucks=\"1\">",
f"\t{sections}",
"</TrackSections>"
))

lines.append("</TrackSections>")
data = "\n".join(lines)
writeXMLData(data, os.path.join(export_dir, "data_track_sections"))

Expand Down Expand Up @@ -343,14 +408,16 @@ class MK64_TrackSection:
gfx_list_name: str
surface_type: str
section_id: Int
flags: Int
clip: Int
drawLayer: Int
location: FloatVectorProperty

def to_c(self):
data = (
self.gfx_list_name,
self.surface_type,
f"0x{self.section_id:X}",
f"0x{self.flags:X}",
f"0x{self.clip:X}",
)
return f"{{ {', '.join(data)} }}"

Expand Down Expand Up @@ -393,6 +460,7 @@ def to_c(self):
return "\n".join(lines)

def to_xml(self):
print("PATH TO XML TEST")
lines = []
for x, y, z, pid in self.points:
lines.append(f"{{ {x}, {y}, {z}, {pid} }},")
Expand Down Expand Up @@ -447,7 +515,8 @@ def export_course_xml(obj: bpy.types.Object, context: bpy.types.Context, export_

bpy_course = MK64_BpyCourse(obj)

mk64_fModel = bpy_course.make_mk64_course_from_bpy(context, scale, mat_write_method)
logging_func({'INFO'}, "EXPORT_XML")
mk64_fModel = bpy_course.make_mk64_course_from_bpy(context, scale, mat_write_method, logging_func)

bpy_course.cleanup_course()

Expand Down
10 changes: 6 additions & 4 deletions fast64_internal/mk64/mk64_properties.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import bpy
from bpy.props import StringProperty, BoolProperty, EnumProperty, IntProperty, FloatProperty, PointerProperty
from bpy.props import StringProperty, BoolProperty, EnumProperty, IntProperty, FloatProperty, PointerProperty, FloatVectorProperty
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

from .mk64_constants import enum_surface_types, enum_actor_types
from .mk64_constants import enum_surface_types, enum_clip_types, enum_draw_layer_types, enum_actor_types

from ..render_settings import on_update_render_settings

Expand Down Expand Up @@ -118,9 +118,11 @@ class MK64_ObjectProperties(PropertyGroup):
actor_type: EnumProperty(name="Actor Type", items=enum_actor_types)

# for mesh objects
has_col: BoolProperty(name="Has Collision", default=True)
col_type: EnumProperty(name="Collision Type", items=enum_surface_types, default="SURFACE_DEFAULT")
surface_type: EnumProperty(name="Collision Type", items=enum_surface_types, default="SURFACE_DEFAULT")
section_id: IntProperty(name="section_id", default=255, min=0, max=255)
clip_type: EnumProperty(name="clip_type", items=enum_clip_types, default="CLIP_DEFAULT")
draw_layer: EnumProperty(name="draw_layer", items=enum_draw_layer_types, default="DRAW_OPAQUE")
location: FloatVectorProperty(name="Location", default=(0,0,0), size=3, description="location")


class MK64_CurveProperties(PropertyGroup):
Expand Down
Loading