diff --git a/assets/genshin_tab.png b/assets/genshin_tab.png new file mode 100644 index 00000000..20aaf6c3 Binary files /dev/null and b/assets/genshin_tab.png differ diff --git a/assets/pgr_tab.png b/assets/pgr_tab.png new file mode 100644 index 00000000..7f90c11b Binary files /dev/null and b/assets/pgr_tab.png differ diff --git a/assets/star_rail_tab.png b/assets/star_rail_tab.png new file mode 100644 index 00000000..dc4c768a Binary files /dev/null and b/assets/star_rail_tab.png differ diff --git a/setup_wizard/README.md b/setup_wizard/README.md index d15a51ae..0d3fda13 100644 --- a/setup_wizard/README.md +++ b/setup_wizard/README.md @@ -6,6 +6,7 @@ The goal of this tool is to streamline the character setup process. Whether it's **Important**: This tool is intended to be used with: * Festivity's Genshin Impact Shader, found here: https://github.com/festivize/Blender-miHoYo-Shaders +* Festivity's Honkai: Star Rail Shader, found here: https://github.com/festivities/Blender-StellarToon * Nya222's Honkai: Star Rail Shader, found here: https://discord.com/channels/894925535870865498/1127604826885328926 (Omatsuri Discord Server) * JaredNyts' Punishing: Gray Raven Shader, found here: https://discord.com/channels/894925535870865498/1186597049198727259 (Omatsuri Discord Server) @@ -26,21 +27,15 @@ The goal of this tool is to streamline the character setup process. Whether it's ## Tutorials/Screenshots ### Screenshot of the Tool -![alt text](https://cdn.discordapp.com/attachments/890116796034711595/1014970456572436530/unknown.png) +![alt text](/assets/genshin_tab.png) +![alt text](/assets/star_rail_tab.png) +![alt text](/assets/pgr_tab.png) ### Tutorials -Download Tutorials: -- Installation and "One Click" Simplified Setup (First Time Setup, No Cached Data) - - https://cdn.discordapp.com/attachments/1015585109639974922/1015585432026763284/SetupWizardUI_v1-0_Installation_and_Simplified_Setup.mp4 -- 4 Step Menu: Basic Setup (First Time Setup, No Cached Data) - - https://cdn.discordapp.com/attachments/1015585109639974922/1015587153058746499/SetupWizardUI_v1-0_Basic_Setup_-_No_Cache.mp4 -- 4 Step Menu: Basic Setup (Post-First Time Setup, with Cached Data) - - https://cdn.discordapp.com/attachments/1015585109639974922/1015746432482943057/SetupWizardUI_v1-0_Basic_Setup_with_Cache.mp4 -- Advanced Setup (Post-First Time Setup, with Cached Data) - - https://cdn.discordapp.com/attachments/1015585109639974922/1015587532362223698/SetupWizardUI_v1-0_Advanced_Setup_with_Cache.mp4 - - +A few kind souls have created some video tutorials (for educational purposes, not officially endorsed) +* (Micchi — Genshin Impact-focused) https://youtu.be/S7mFQveRNcc +* (fnoji — Honkia Star Rail-focused) https://www.youtube.com/watch?v=QY37vbfrLh4 diff --git a/setup_wizard/__init__.py b/setup_wizard/__init__.py index 9cb96662..fff03d3e 100644 --- a/setup_wizard/__init__.py +++ b/setup_wizard/__init__.py @@ -1,7 +1,7 @@ bl_info = { "name": "HoYoverse Setup Wizard", "author": "Mken, OctavoPE, Enthralpy", - "version": (2, 6, 1), + "version": (2, 6, 2), "blender": (3, 3, 0), "location": "3D View > Sidebar > Genshin Impact / Honkai Star Rail / Punishing Gray Raven", "description": "An addon to streamline the character model setup process when using Festivity, Nya222's or JaredNyts' Shaders", diff --git a/setup_wizard/domain/shader_material_names.py b/setup_wizard/domain/shader_material_names.py index 0bfa2c84..a8bb09e1 100644 --- a/setup_wizard/domain/shader_material_names.py +++ b/setup_wizard/domain/shader_material_names.py @@ -27,6 +27,7 @@ class ShaderMaterialNames: WEAPON_TRANS = '' # Serval HANDBAG = '' # Sampo KENDAMA = '' # Sparkle + COAT = '' # Feixiao # HSR: StellarToon BASE = '' BASE_OUTLINES = '' @@ -91,6 +92,7 @@ class Nya222HonkaiStarRailShaderMaterialNames(ShaderMaterialNames): WEAPON02 = f'{MATERIAL_PREFIX}Weapon02' HANDBAG = f'{MATERIAL_PREFIX}Handbag' KENDAMA = f'{MATERIAL_PREFIX}Kendama' # Sparkle + COAT = f'{MATERIAL_PREFIX}Coat' # Feixiao class StellarToonShaderMaterialNames(ShaderMaterialNames): @@ -123,6 +125,7 @@ class StellarToonShaderMaterialNames(ShaderMaterialNames): WEAPON_TRANS = f'{MATERIAL_PREFIX}Weapon_Trans' HANDBAG = f'{MATERIAL_PREFIX}Handbag' KENDAMA = f'{MATERIAL_PREFIX}Kendama' # Sparkle + COAT = f'{MATERIAL_PREFIX}Coat' # Feixiao class JaredNytsPunishingGrayRavenShaderMaterialNames(ShaderMaterialNames): diff --git a/setup_wizard/geometry_nodes_setup/geometry_nodes_setups.py b/setup_wizard/geometry_nodes_setup/geometry_nodes_setups.py index 36a39850..8dd22459 100644 --- a/setup_wizard/geometry_nodes_setup/geometry_nodes_setups.py +++ b/setup_wizard/geometry_nodes_setup/geometry_nodes_setups.py @@ -46,7 +46,7 @@ NAME_OF_OUTLINE_4_MASK_INPUT: NAME_OF_OUTLINE_4_MATERIAL_INPUT } -meshes_to_create_geometry_nodes_on = [ +gi_meshes_to_create_outlines_on = [ 'Body', 'Face', 'Face_Eye', @@ -61,18 +61,30 @@ 'Wriothesley_Gauntlet_R_Model', 'Screw', # Aranara 'Hat', # Aranara - # HSR +] + +hsr_meshes_to_create_outlines_on = [ 'Hair', 'Weapon', 'Weapon01', 'Weapon02', - # PGR +] + +pgr_meshes_to_create_outlines_on = [ 'Down', 'Upper', 'Cloth', 'Clothes', ] +meshes_to_create_outlines_on = \ + gi_meshes_to_create_outlines_on + \ + hsr_meshes_to_create_outlines_on + \ + pgr_meshes_to_create_outlines_on + +meshes_to_create_light_vectors_on = meshes_to_create_outlines_on + [ + 'Brow' +] class GameGeometryNodesSetupFactory: def create(game_type: GameType, blender_operator: Operator, context: Context): @@ -243,7 +255,7 @@ def __init__(self, blender_operator, context): def setup_geometry_nodes(self): self.clone_outlines(self.material_names) - for mesh_name in meshes_to_create_geometry_nodes_on: + for mesh_name in meshes_to_create_outlines_on: for object_name, object_data in bpy.context.scene.objects.items(): if object_data.type == 'MESH' and (mesh_name == object_name or f'_{mesh_name}' in object_name): self.create_geometry_nodes_modifier(f'{object_name}{BODY_PART_SUFFIX}') @@ -289,11 +301,11 @@ def setup_geometry_nodes(self): # character_armature = [obj for obj in bpy.data.objects if obj.type == 'ARMATURE'][0] # Expecting 1 armature in scene # character_armature_mesh_names = [obj.name for obj in character_armature.children if obj.type == 'MESH'] - for mesh_name in meshes_to_create_geometry_nodes_on: # It is important that this is created and placed before Outlines!! + for mesh_name in meshes_to_create_light_vectors_on: # It is important that this is created and placed before Outlines!! for object_name, object_data in bpy.context.scene.objects.items(): if object_data.type == 'MESH' and (mesh_name == object_name or f'_{mesh_name}' in object_name): self.create_light_vectors_modifier(f'{object_name}{BODY_PART_SUFFIX}') - for mesh_name in meshes_to_create_geometry_nodes_on: + for mesh_name in meshes_to_create_outlines_on: for object_name, object_data in bpy.context.scene.objects.items(): if object_data.type == 'MESH' and (mesh_name == object_name or f'_{mesh_name}' in object_name): self.create_geometry_nodes_modifier(f'{object_name}{BODY_PART_SUFFIX}') @@ -384,7 +396,7 @@ def __init__(self, blender_operator, context, material_names, outline_node_group def setup_geometry_nodes(self): self.clone_outlines(self.material_names) - for mesh_name in meshes_to_create_geometry_nodes_on: + for mesh_name in meshes_to_create_outlines_on: for object_name, object_data in bpy.context.scene.objects.items(): if object_data.type == 'MESH' and (mesh_name == object_name or f'_{mesh_name}' in object_name): self.create_geometry_nodes_modifier(f'{object_name}{BODY_PART_SUFFIX}') @@ -433,7 +445,7 @@ def setup_geometry_nodes(self): if object_data.type == 'MESH' and (mesh_name == object_name or f'_{mesh_name}' in object_name): light_vectors_modifier = self.create_light_vectors_modifier(f'{object_name}{BODY_PART_SUFFIX}') self.__set_light_vectors_default_output_attributes(light_vectors_modifier) - for mesh_name in meshes_to_create_geometry_nodes_on: + for mesh_name in meshes_to_create_outlines_on: for object_name, object_data in bpy.context.scene.objects.items(): if object_data.type == 'MESH' and (mesh_name == object_name or f'_{mesh_name}' in object_name): self.create_geometry_nodes_modifier(f'{object_name}{BODY_PART_SUFFIX}') diff --git a/setup_wizard/replace_default_materials_setup/game_default_material_replacers.py b/setup_wizard/replace_default_materials_setup/game_default_material_replacers.py index bf739225..f4cc6c57 100644 --- a/setup_wizard/replace_default_materials_setup/game_default_material_replacers.py +++ b/setup_wizard/replace_default_materials_setup/game_default_material_replacers.py @@ -243,6 +243,9 @@ def replace_default_materials(self): if mesh_body_part_name == 'Body2_Trans': body_material = self.create_body_trans_material(mesh, self.shader_material_names.BODY2_TRANS) material_name = body_material.name + if 'Coat' in mesh_body_part_name: + body_material = self.create_body_material(mesh, self.shader_material_names.COAT) + material_name = body_material.name if 'Weapon' in mesh_body_part_name: weapon_material = self.create_weapon_materials(mesh_body_part_name) @@ -285,6 +288,8 @@ def find_body_part_name(self, material_name): Expected Format Search: Search for body part name at expected location, at the end of the material name (ex. 'Body') ''' def __expected_format_body_part_name_search(self, material_name): + if material_name.endswith('_S') or material_name.endswith('_D'): + return material_name.split('_')[-2] return material_name.split('_')[-1] ''' diff --git a/setup_wizard/texture_import_setup/texture_importer_types.py b/setup_wizard/texture_import_setup/texture_importer_types.py index b8056174..bd1c384c 100644 --- a/setup_wizard/texture_import_setup/texture_importer_types.py +++ b/setup_wizard/texture_import_setup/texture_importer_types.py @@ -755,6 +755,7 @@ def import_textures(self, directory): body3_material = bpy.data.materials.get(self.material_names.BODY3) body_trans_material = bpy.data.materials.get(self.material_names.BODY_TRANS) body2_trans_material = bpy.data.materials.get(self.material_names.BODY2_TRANS) + coat_material = bpy.data.materials.get(self.material_names.COAT) weapon_material = bpy.data.materials.get(self.material_names.WEAPON) weapon1_material = bpy.data.materials.get(self.material_names.WEAPON1) weapon01_material = bpy.data.materials.get(self.material_names.WEAPON01) @@ -866,6 +867,11 @@ def import_textures(self, directory): elif self.is_texture_identifiers_in_texture_name(['Body'], file): # Must be AFTER Body1/Body2 self.set_stocking_texture(TextureType.BODY, body_material, img) + elif self.is_texture_identifiers_in_texture_name(['Coat', 'Color'], file): + self.set_diffuse_texture(TextureType.BODY, coat_material, img) + elif self.is_texture_identifiers_in_texture_name(['Coat', 'LightMap'], file): + self.set_lightmap_texture(TextureType.BODY, coat_material, img) + elif self.is_texture_identifiers_in_texture_name(['Face', 'Color'], file): self.set_diffuse_texture(TextureType.FACE, face_material, img)