Skip to content

Commit

Permalink
Add support for loading BCK animations with J3DUltra
Browse files Browse the repository at this point in the history
  • Loading branch information
LagoLunatic committed Jan 18, 2024
1 parent 2e26421 commit 00e5210
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 19 deletions.
3 changes: 2 additions & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
url = https://github.com/LagoLunatic/gclib.git
[submodule "PyJ3DUltra"]
path = PyJ3DUltra
url = https://github.com/Astral-C/PyJ3DUltra.git
url = https://github.com/LagoLunatic/PyJ3DUltra.git
branch = gcft
2 changes: 1 addition & 1 deletion PyJ3DUltra
Submodule PyJ3DUltra updated 2 files
+1 −1 J3DUltra
+318 −19 src/main.cpp
16 changes: 11 additions & 5 deletions gcft_ui/j3d_tab.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,14 +163,20 @@ def import_j3d_by_data(self, data, j3d_name):

def load_anim_by_data(self, data, anim_name):
j3d = J3D(data)
if j3d.file_type[:3] != "brk":
max_frame = None
if j3d.file_type[:3] == "bck":
bck = j3d
max_frame = bck.ank1.duration-1
self.ui.j3d_viewer.load_bck(bck)
elif j3d.file_type[:3] == "brk":
brk = j3d
max_frame = brk.trk1.duration-1
self.ui.j3d_viewer.load_brk(brk)
else:
return
brk = j3d

self.ui.j3d_viewer.load_brk(brk)

self.ui.anim_slider.setMinimum(0)
self.ui.anim_slider.setMaximum(brk.trk1.duration-1)
self.ui.anim_slider.setMaximum(max_frame)
self.ui.anim_slider.setValue(0)

self.ui.anim_pause_button.setDisabled(False)
Expand Down
51 changes: 40 additions & 11 deletions gcft_ui/j3d_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ def __init__(self, parent):
self.base_center = np.zeros(3)
self.aspect = 1.0
self.model = None
self.joint_anim = None
self.color_anim = None
self.camera = Camera(
distance=self.base_cam_dist,
Expand Down Expand Up @@ -268,6 +269,7 @@ def unload_model(self):
self.hide()

def unload_anims(self):
self.joint_anim = None
self.color_anim = None

def guesstimate_model_bbox(self, j3d_model: J3D) -> tuple[np.ndarray, np.ndarray]:
Expand Down Expand Up @@ -366,6 +368,23 @@ def get_preview_compatible_j3d(self, orig_j3d: J3D) -> J3D:
else:
return orig_j3d

def load_bck(self, bck: J3D):
self.bck = bck

if self.model is None:
return

if bck.ank1.anims_count != self.j3d.jnt1.joint_count:
error_message = "This animation is not for this model.\nThe loaded BCK animation has animations for %s joints, while the currently loaded model has %s joints." % (
self.window().stringify_number(bck.ank1.anims_count, min_hex_chars=2),
self.window().stringify_number(self.j3d.jnt1.joint_count, min_hex_chars=2),
)
QMessageBox.warning(self, "Wrong joint count", error_message)
return

self.model.attachBck(data=fs.read_all_bytes(self.bck.data))
self.joint_anim = self.model.getBck()

def load_brk(self, brk: J3D):
self.brk = brk

Expand All @@ -382,20 +401,27 @@ def load_brk(self, brk: J3D):
# brk. maybe make a separate func: load_model vs reload_model

def set_anim_frame(self, frame: int):
if self.color_anim is None:
return

self.color_anim.setFrame(frame, True)

self.should_update_render = True
for anim in [self.joint_anim, self.color_anim]:
if anim is None:
continue
anim.setFrame(frame, True)
self.should_update_render = True

def set_anim_paused(self, paused: bool):
if self.color_anim is None:
for anim in [self.joint_anim, self.color_anim]:
if anim is None:
continue
anim.setPaused(paused)

def tick_anims(self, delta_time: float):
if delta_time <= 0:
return

# Note: J3DUltra does not currently support animation playback, so this does nothing.
frame = self.color_anim.getFrame()
self.color_anim.setFrame(int(frame), paused)
for anim in [self.joint_anim, self.color_anim]:
if anim is None:
continue
anim.tick(delta_time)
self.should_update_render = True

def calculate_light_pos(self, frac):
angle = (frac % 1.0) * np.pi*2
Expand Down Expand Up @@ -628,7 +654,8 @@ def update(self):

def process_frame(self):
current_time = time.monotonic()
self.total_time_elapsed += (current_time - self.last_render_time)
delta_time = current_time - self.last_render_time
self.total_time_elapsed += delta_time
self.last_render_time = current_time

if self.context() is None:
Expand All @@ -640,6 +667,8 @@ def process_frame(self):
if self.animate_light:
self.update_lights()

self.tick_anims(delta_time)

if self.should_update_render:
self.update()
self.should_update_render = False
Expand Down
2 changes: 1 addition & 1 deletion gclib

0 comments on commit 00e5210

Please sign in to comment.