From 51077c2fe8c160743a67303fb516126bb98afff7 Mon Sep 17 00:00:00 2001 From: Owl Date: Fri, 22 Aug 2025 00:15:50 -0400 Subject: changes until now - test --- .python-version | 1 - README.md | 30 ++++++++++++------------------ __init__.py | 31 +++++++++++++------------------ basic_settings.py | 2 +- bck_funcs.py | 30 ++++++++++++++++++------------ smg_common.py | 28 ++++++++++++++++++++++++++-- 6 files changed, 70 insertions(+), 52 deletions(-) delete mode 100644 .python-version diff --git a/.python-version b/.python-version deleted file mode 100644 index 475ba51..0000000 --- a/.python-version +++ /dev/null @@ -1 +0,0 @@ -3.7 diff --git a/README.md b/README.md index d21b3dd..6727c20 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,14 @@ # Blenxy -Epic Blender 2.79 template for Super Mario Galaxy modeling (honest work). +Blender 2.79 template for Super Mario Galaxy stuff. # TODO -- Be aware of future BCK importer bugs. +- Be aware of future BCK importer/export bugs. - Import "Inherit Parent Scale" data from BMD/BDL models into an already imported DAE model. -- Make a BCK exporter. +- Try to import directly a BMD/BDL model (one can dream). +- Learn about other model related file formats +- Learn how to modify Blender's UI through its Python API to make "custom editors". - ... # Features @@ -15,36 +17,28 @@ Epic Blender 2.79 template for Super Mario Galaxy modeling (honest work). - Custom Collada exporter for conversion with SuperBMD. - Reference axis `SMG axis` shows on all 3d models to guide the visualization of a mesh in the Super Mario Galaxy coordinate system (Y up). - Custom mesurement unit `Galaxy Unit` (or GU in short) that is used to mimic the game's original modelling environment (1 GU is 1 centimeter). -- Epic Mario model like the default cube in Blender when starting the template (truly the most important part of the template >:]). +- Epic Mario model like the default cube in Blender when starting the template. - OBJ importer for NeoKCLCreate OBJs. - OBJ exporter for KCL conversion. -- BCK animation importer (with some importing options, read them). +- BCK animation importer for SMG (with some importing options, read them). +- BCK animation exporter for SMG (with some exporter options, read them). - ... # Installation -- Go to releases -- Locate the last release +- Go to tags +- Locate the last tag - Download the `blenxy.zip` file - Open Blender and go to File > Application Templates > Install Template from File... - Search and select the `blenxy.zip` file - The extension will download the python modules it needs in the first execution and automatically close Blender after installation (errors might happen here so open blender in CMD/Terminal to keep track of them). - If everything went nicely, enjoy the extension! -# Contribute - -If you want to contribute or report an issue open a new issue in **Issues**. I will answer when I have time. - # Thanks to - Tarsa for the J3D Animation Editor program (JAE). - Gabbo for pointing me out the Blender Python API reference. - RenolY2 for J3DView and SuperBMD. -- The authors of the material I could read about BMD/BDL. +- The authors of the material I could read about BMD/BDL/BCK. - The many stackoverflow threads (or similar forums/pages) in which Blender Python API issues/facts are discussed. - -# Changelog - -- Added BCK importer. -- Added OBJ importer/exporter. -- Collada importer/exporter updated. It still relies in Blender's default Collada importer/exporter. It is consistent enough to keep it this way for a long time. +- The git repository hosting service I am using. diff --git a/__init__.py b/__init__.py index 7873723..da57085 100644 --- a/__init__.py +++ b/__init__.py @@ -1,27 +1,25 @@ -''' -To load stuff that assumes a Blender scene is already loaded -I need to wait for the BLEND file of the template to load and -then add the functions and stuff I want after said file loads. -The use of "bpy.app.handlers" and "persistent" help in this case -for some reason I don't undertand yet >:] (but meh, it works) +# To load stuff that assumes a Blender scene is already loaded +# I need to wait for the BLEND file of the template to load and +# then add the functions and stuff I want after said file loads. +# The use of "bpy.app.handlers" and "persistent" help in this case +# for some reason I don't undertand yet >:] (but meh, it works) -References: -https://s-nako.work/2020/09/blender-error-attributeerror-_restrictcontext-object-has-no-attribute-view_layer/ -https://web.archive.org/web/20210925181415/https://blenderbrew.com/custom-application-templates-in-blender/ -''' +# References: +# https://s-nako.work/2020/09/blender-error-attributeerror-_restrictcontext-object-has-no-attribute-view_layer/ +# https://web.archive.org/web/20210925181415/https://blenderbrew.com/custom-application-templates-in-blender/ import bpy from bpy.app.handlers import persistent -################################################# # define function that sets all the blenxy stuff: # galaxy unit, custom collada exporter/importer # custom CSV animation file (for BCK) exporter/importer @persistent def set_blenxy_env(dummy): # "dummy" is a variable that is somehow - # passed to set_blenxy_env when called by - # bpy.app.handlers.load_post.append + # passed to set_blenxy_env when called by + # bpy.app.handlers.load_post.append + from . import required_modules # install needed modules for bundled python (awful) from . import basic_settings # settings blenxy has from . import collada_superbmd_import # custom importer for SuperBMD collada files @@ -29,16 +27,13 @@ def set_blenxy_env(dummy): # "dummy" is a variable that is somehow from . import obj_kcl_export # custom exporter for OBJ files (Collision) from . import obj_neokclcreate_import # custom importer for OBJ files (Colllision, NeoKCLCreate) from . import bck_import # custom importer for SMG BCK files - # ~ from . import bck_export # custom exporter for SMG BCK files - # ~ from . import csv_anim_bck_export # exporter for CSV files for BCK conversion + from . import bck_export # custom exporter for SMG BCK files # more scripts can be added here + # ... - -############################# # register/unregister stuff # for set_blenxy_env function - def register(): print("\nWelcome to Blenxy!\n") print("Setting environment...") diff --git a/basic_settings.py b/basic_settings.py index 96b9b07..8f41ec5 100644 --- a/basic_settings.py +++ b/basic_settings.py @@ -88,6 +88,6 @@ scene.frame_preview_start = 0 scene.frame_current = 0 scene.frame_preview_end = 100 bpy.context.user_preferences.view.use_mouse_depth_navigate = True -bpy.context.user_preferences.view.use_zoom_to_mouse = True +# ~ bpy.context.user_preferences.view.use_zoom_to_mouse = True print("Done with the basic settings!\n") diff --git a/bck_funcs.py b/bck_funcs.py index 8ea2c72..d8c1162 100644 --- a/bck_funcs.py +++ b/bck_funcs.py @@ -1,4 +1,5 @@ import os, struct, math +from . import smg_common # python file to read the important information out of a BCK file # will try its best to decode the information either on big/little endian @@ -200,7 +201,7 @@ class smg_bck_anim: bck_raw_info = None bck_error_str = "bck-error: " bck_anim_error_str = "bck-anim-error: " -pad_str = "This is padding data to alignme" +pad_str = "hoot" f = None # main function @@ -563,7 +564,7 @@ def create_smg_bck_raw(anim): # header raw.header.magic = "J3D1" raw.header.ftype = "btp1" - raw.header.file_size = 32 # update later + raw.header.file_size = 0 # update later raw.header.section_count = 1 raw.header.unknown1 = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, @@ -576,7 +577,7 @@ def create_smg_bck_raw(anim): # ank1 section raw.ank1.magic = "ANK1" - raw.ank1.size = 36 # update at the end + raw.ank1.size = 0 # update at the end raw.ank1.loop_mode = anim.loop_mode raw.ank1.rot_lshift = 0 # update now raw.ank1.anim_length = anim.anim_length @@ -706,15 +707,20 @@ def create_smg_bck_raw(anim): raw.ank1.scale_arr_length = len(raw.ank1.scale_arr) raw.ank1.rot_arr_length = len(raw.ank1.rot_arr) raw.ank1.transl_arr_length = len(raw.ank1.transl_arr) - raw.ank1.anim_data_offset = 0x40 - raw.ank1.scale_arr_offset = None - raw.ank1.rot_arr_offset = None - raw.ank1.transl_arr_offset = None - raw.ank1.anim_data = [] # list of length bone_count - raw.ank1.scale_arr = [] # list of length scale_arr_length - raw.ank1.rot_arr = [] # list of length rot_arr_length - raw.ank1.transl_arr = [] # list of length transl_arr_length - + pad_str = smg_common.padding() + raw.ank1.anim_data_offset = 0x40 # yes + raw.ank1.scale_arr_offset = raw.ank1.anim_data_offset + (raw.ank1.bone_count * 9 * 6) + raw.ank1.scale_arr_offset += len(pad_str.string_fill(32, raw.ank1.scale_arr_offset)) + raw.ank1.rot_arr_offset = raw.ank1.scale_arr_offset + (raw.ank1.scale_arr_length * 4) + raw.ank1.rot_arr_offset += len(pad_str.string_fill(32, raw.ank1.rot_arr_offset)) + raw.ank1.transl_arr_offset = raw.ank1.rot_arr_offset + (raw.ank1.rot_arr_length * 2) + raw.ank1.transl_arr_offset += len(pad_str.string_fill(32, raw.ank1.transl_arr_offset)) + # section size and file size + raw.ank1.size = raw.ank1.transl_arr_offset + (raw.ank1.transl_arr_length * 4) + raw.ank1.size += len(pad_str.string_fill(32, raw.ank1.size)) + 1 + raw.header.file_size = 32 + raw.ank1.size + + # done! return raw # write smg_bck_raw diff --git a/smg_common.py b/smg_common.py index c278382..3c7bb0f 100644 --- a/smg_common.py +++ b/smg_common.py @@ -1,6 +1,30 @@ -# paddng string -padding = +# padding stuff +# padding string +class padding(): + + # the fill string + def __init__(self): + self.string = "This is padding data to alignme" + + # return the padding string to align data at a + # given start_index with a specific byte_alignment + def string_fill(self, byte_alignment, start_index): + # check the variables first + if ((type(start_index) != int) + or (type(byte_alignment) != int) + or (start_index < 0) + or (byte_alignment != 4 and byte_alignment != 32): + return None + # return the fill string + i = 0 + rtn = "" + while (start_index % byte_alignment != 0): + rtn += self.padding[i] + i += 1 + start_index += 1 + return rtn + # name tables # read name tables found in SMG binary files -- cgit v1.2.3-70-g09d2