Merge pull request #8 from Yusarina/alpha4-vrmconverter

Alpha4 vrmconverter
This commit is contained in:
Yusarina
2025-08-09 15:47:39 +01:00
committed by GitHub
7 changed files with 166 additions and 162 deletions
+17 -17
View File
@@ -285,12 +285,12 @@ bone_names.update({
'head': bone_names['head'] + ['jbipchead', 'jhead', 'vrmhead', 'lefteye', 'righteye'], 'head': bone_names['head'] + ['jbipchead', 'jhead', 'vrmhead', 'lefteye', 'righteye'],
# VRM arms - both simplified patterns # VRM arms - both simplified patterns
'left_shoulder': bone_names['left_shoulder'] + ['jbipllshoulder', 'jlshoulder', 'jbiplshoulder', 'leftshoulder'], 'left_shoulder': bone_names['left_shoulder'] + ['jbipllshoulder', 'jlshoulder', 'jbiplshoulder', 'leftshoulder', 'jbipllclavicle'],
'left_arm': bone_names['left_arm'] + ['jbiplupperarm', 'jlupperarm', 'leftupperarm'], 'left_arm': bone_names['left_arm'] + ['jbiplupperarm', 'jlupperarm', 'leftupperarm'],
'left_elbow': bone_names['left_elbow'] + ['jbipllforearm', 'jlforearm', 'jbipllowerarm', 'leftlowerarm'], 'left_elbow': bone_names['left_elbow'] + ['jbipllforearm', 'jlforearm', 'jbipllowerarm', 'leftlowerarm'],
'left_wrist': bone_names['left_wrist'] + ['jbipllhand', 'jlhand', 'jbiplhand', 'lefthand'], 'left_wrist': bone_names['left_wrist'] + ['jbipllhand', 'jlhand', 'jbiplhand', 'lefthand'],
'right_shoulder': bone_names['right_shoulder'] + ['jbiprlshoulder', 'jrshoulder', 'jbiprshoulder', 'rightshoulder'], 'right_shoulder': bone_names['right_shoulder'] + ['jbiprlshoulder', 'jrshoulder', 'jbiprshoulder', 'rightshoulder', 'jbiprrclavicle'],
'right_arm': bone_names['right_arm'] + ['jbiprrupperarm', 'jrupperarm', 'jbiprupperarm', 'rightupperarm'], 'right_arm': bone_names['right_arm'] + ['jbiprrupperarm', 'jrupperarm', 'jbiprupperarm', 'rightupperarm'],
'right_elbow': bone_names['right_elbow'] + ['jbiprrforearm', 'jrforearm', 'jbiprforearm', 'jbiprlowerarm', 'rightlowerarm'], 'right_elbow': bone_names['right_elbow'] + ['jbiprrforearm', 'jrforearm', 'jbiprforearm', 'jbiprlowerarm', 'rightlowerarm'],
'right_wrist': bone_names['right_wrist'] + ['jbiprrhand', 'jrhand', 'jbiprhand', 'righthand'], 'right_wrist': bone_names['right_wrist'] + ['jbiprrhand', 'jrhand', 'jbiprhand', 'righthand'],
@@ -314,12 +314,12 @@ bone_names.update({
'jaw': ['jaw', 'mandible', 'lowerjaw', 'chin', 'あご', 'ik_あご'], 'jaw': ['jaw', 'mandible', 'lowerjaw', 'chin', 'あご', 'ik_あご'],
# Breast bones # Breast bones
'breast_1_l': bone_names['breast_1_l'] + ['jbipcbreast1l', 'jlbreast1'], 'breast_1_l': bone_names['breast_1_l'] + ['jbipcbreast1l', 'jlbreast1', 'jseclbust1'],
'breast_2_l': bone_names['breast_2_l'] + ['jbipcbreast2l', 'jlbreast2'], 'breast_2_l': bone_names['breast_2_l'] + ['jbipcbreast2l', 'jlbreast2', 'jseclbust2'],
'breast_3_l': bone_names['breast_3_l'] + ['jbipcbreast3l', 'jlbreast3'], 'breast_3_l': bone_names['breast_3_l'] + ['jbipcbreast3l', 'jlbreast3', 'jseclbust3'],
'breast_1_r': bone_names['breast_1_r'] + ['jbipcbreast1r', 'jrbreast1'], 'breast_1_r': bone_names['breast_1_r'] + ['jbipcbreast1r', 'jrbreast1', 'jsecrbust1'],
'breast_2_r': bone_names['breast_2_r'] + ['jbipcbreast2r', 'jrbreast2'], 'breast_2_r': bone_names['breast_2_r'] + ['jbipcbreast2r', 'jrbreast2', 'jsecrbust2'],
'breast_3_r': bone_names['breast_3_r'] + ['jbipcbreast3r', 'jrbreast3'], 'breast_3_r': bone_names['breast_3_r'] + ['jbipcbreast3r', 'jrbreast3', 'jsecrbust3'],
# VRM fingers - Left (including Little finger variations) # VRM fingers - Left (including Little finger variations)
'thumb_0_l': bone_names['thumb_0_l'] + ['jbipllthumb0', 'jlthumb0', 'jbipllthumbmetacarpal', 'jlthumbmetacarpal', 'leftthumbmetacarpal'], 'thumb_0_l': bone_names['thumb_0_l'] + ['jbipllthumb0', 'jlthumb0', 'jbipllthumbmetacarpal', 'jlthumbmetacarpal', 'leftthumbmetacarpal'],
@@ -452,7 +452,7 @@ standard_bones = {
'hips': 'Hips', 'hips': 'Hips',
'spine': 'Spine', 'spine': 'Spine',
'chest': 'Chest', 'chest': 'Chest',
'upper_chest': 'Chest.Up', 'upper_chest': 'UpperChest',
'neck': 'Neck', 'neck': 'Neck',
'head': 'Head', 'head': 'Head',
@@ -526,20 +526,20 @@ standard_bones = {
bone_hierarchy = [ bone_hierarchy = [
('Hips', 'Spine'), ('Hips', 'Spine'),
('Spine', 'Chest'), ('Spine', 'Chest'),
('Chest', 'Chest.Up'), ('Chest', 'UpperChest'),
('Chest.Up', 'Neck'), ('UpperChest', 'Neck'),
('Neck', 'Head'), ('Neck', 'Head'),
('Head', 'Eye_L'), ('Head', 'Eye_L'),
('Head', 'Eye_R'), ('Head', 'Eye_R'),
# Left Arm Chain # Left Arm Chain
('Chest.Up', 'Shoulder_L'), ('UpperChest', 'Shoulder_L'),
('Shoulder_L', 'UpperArm_L'), ('Shoulder_L', 'UpperArm_L'),
('UpperArm_L', 'LowerArm_L'), ('UpperArm_L', 'LowerArm_L'),
('LowerArm_L', 'Hand_L'), ('LowerArm_L', 'Hand_L'),
# Right Arm Chain # Right Arm Chain
('Chest.Up', 'Shoulder_R'), ('UpperChest', 'Shoulder_R'),
('Shoulder_R', 'UpperArm_R'), ('Shoulder_R', 'UpperArm_R'),
('UpperArm_R', 'LowerArm_R'), ('UpperArm_R', 'LowerArm_R'),
('LowerArm_R', 'Hand_R'), ('LowerArm_R', 'Hand_R'),
@@ -616,10 +616,10 @@ acceptable_bone_hierarchy = [
('Head', 'RightEye'), ('Head', 'RightEye'),
# Old standard bone hierarchy patterns # Old standard bone hierarchy patterns
('Chest.Up', 'UpperArm.L'), ('UpperChest', 'UpperArm.L'),
('UpperArm.L', 'LowerArm.L'), ('UpperArm.L', 'LowerArm.L'),
('LowerArm.L', 'Hand.L'), ('LowerArm.L', 'Hand.L'),
('Chest.Up', 'UpperArm.R'), ('UpperChest', 'UpperArm.R'),
('UpperArm.R', 'LowerArm.R'), ('UpperArm.R', 'LowerArm.R'),
('LowerArm.R', 'Hand.R'), ('LowerArm.R', 'Hand.R'),
('Hips', 'UpperLeg.L'), ('Hips', 'UpperLeg.L'),
@@ -632,11 +632,11 @@ acceptable_bone_hierarchy = [
('Foot.R', 'Toes.R'), ('Foot.R', 'Toes.R'),
# New standard bone hierarchy patterns (with shoulders) # New standard bone hierarchy patterns (with shoulders)
('Chest.Up', 'Shoulder_L'), ('UpperChest', 'Shoulder_L'),
('Shoulder_L', 'UpperArm_L'), ('Shoulder_L', 'UpperArm_L'),
('UpperArm_L', 'LowerArm_L'), ('UpperArm_L', 'LowerArm_L'),
('LowerArm_L', 'Hand_L'), ('LowerArm_L', 'Hand_L'),
('Chest.Up', 'Shoulder_R'), ('UpperChest', 'Shoulder_R'),
('Shoulder_R', 'UpperArm_R'), ('Shoulder_R', 'UpperArm_R'),
('UpperArm_R', 'LowerArm_R'), ('UpperArm_R', 'LowerArm_R'),
('LowerArm_R', 'Hand_R'), ('LowerArm_R', 'Hand_R'),
+7 -85
View File
@@ -4,6 +4,7 @@ from bpy.types import Object, Bone
from .common import get_active_armature from .common import get_active_armature
from .dictionaries import simplify_bonename, standard_bones, bone_hierarchy, reverse_bone_lookup from .dictionaries import simplify_bonename, standard_bones, bone_hierarchy, reverse_bone_lookup
from .logging_setup import logger from .logging_setup import logger
from .translations import t
def detect_vrm_armature(armature: Object) -> bool: def detect_vrm_armature(armature: Object) -> bool:
@@ -85,94 +86,15 @@ def find_vrm_bones_in_armature(armature: Object) -> Dict[str, str]:
def guess_unity_name_from_vrm(vrm_simplified: str) -> Optional[str]: def guess_unity_name_from_vrm(vrm_simplified: str) -> Optional[str]:
""" """
Attempt to guess Unity bone name from VRM simplified name Attempt to guess Unity bone name from VRM simplified name using dictionary lookup
""" """
# Map common VRM patterns to Unity equivalents if vrm_simplified in reverse_bone_lookup:
pattern_mappings = { standard_bone_key = reverse_bone_lookup[vrm_simplified]
'jbipcupperchest': 'UpperChest',
'jbipcchest': 'Chest',
'jbipcspine': 'Spine',
'jbipchips': 'Hips',
'jbipcneck': 'Neck',
'jbipchead': 'Head',
# Left arm if standard_bone_key in standard_bones:
'jbipllclavicle': 'LeftShoulder', return standard_bones[standard_bone_key]
'jbipllshoulder': 'LeftShoulder',
'jbiplshoulder': 'LeftShoulder',
'jbiplupperarm': 'LeftUpperArm',
'jbipllforearm': 'LeftLowerArm',
'jbipllowerarm': 'LeftLowerArm',
'jbipllhand': 'LeftHand',
'jbiplhand': 'LeftHand',
# Right arm (both single and double R patterns) return None
'jbiprrclavicle': 'RightShoulder',
'jbiprlshoulder': 'RightShoulder',
'jbiprshoulder': 'RightShoulder',
'jbiprupperarm': 'RightUpperArm',
'jbiprrupperarm': 'RightUpperArm',
'jbiprforearm': 'RightLowerArm',
'jbiprrforearm': 'RightLowerArm',
'jbiprlowerarm': 'RightLowerArm',
'jbiprhand': 'RightHand',
'jbiprrhand': 'RightHand',
# Left leg
'jbiplupperleg': 'LeftUpperLeg',
'jbipllowerleg': 'LeftLowerLeg',
'jbipllfoot': 'LeftFoot',
'jbiplfoot': 'LeftFoot',
'jbiplltoe': 'LeftToes',
'jbipltoebase': 'LeftToes',
# Right leg (both single and double R patterns)
'jbiprupperleg': 'RightUpperLeg',
'jbiprrupperleg': 'RightUpperLeg',
'jbiprlowerleg': 'RightLowerLeg',
'jbiprrlowerleg': 'RightLowerLeg',
'jbiprfoot': 'RightFoot',
'jbiprrfoot': 'RightFoot',
'jbiprtoe': 'RightToes',
'jbiprrtoe': 'RightToes',
'jbiprtoebase': 'RightToes',
# Eyes
'jbipcleye': 'LeftEye',
'jbipcreye': 'RightEye',
'jadjlfaceeye': 'LeftEye',
'jadjrfaceeye': 'RightEye',
# Fingers - Left
'jbiplthumb1': 'LeftThumb1',
'jbiplthumb2': 'LeftThumb2',
'jbiplthumb3': 'LeftThumb3',
'jbiplindex1': 'LeftIndex1',
'jbiplindex2': 'LeftIndex2',
'jbiplindex3': 'LeftIndex3',
'jbiplmiddle1': 'LeftMiddle1',
'jbiplmiddle2': 'LeftMiddle2',
'jbiplmiddle3': 'LeftMiddle3',
'jbiplring1': 'LeftRing1',
'jbiplring2': 'LeftRing2',
'jbiplring3': 'LeftRing3',
'jbipllittle1': 'LeftPinky1',
'jbipllittle2': 'LeftPinky2',
'jbipllittle3': 'LeftPinky3',
'jbiprlittle1': 'RightPinky1',
'jbiprlittle2': 'RightPinky2',
'jbiprlittle3': 'RightPinky3',
# Breast bones
'jseclbust1': 'Breast1_L',
'jseclbust2': 'Breast2_L',
'jseclbust3': 'Breast3_L',
'jsecrbust1': 'Breast1_R',
'jsecrbust2': 'Breast2_R',
'jsecrbust3': 'Breast3_R'
}
return pattern_mappings.get(vrm_simplified)
def is_vrm_collider_object(obj_name: str) -> bool: def is_vrm_collider_object(obj_name: str) -> bool:
+7 -7
View File
@@ -10,8 +10,8 @@ from ...core.armature_validation import validate_armature
class AvatarToolkit_OT_ConvertVRMToUnity(Operator): class AvatarToolkit_OT_ConvertVRMToUnity(Operator):
"""Convert VRM armature bone names to Unity humanoid format""" """Convert VRM armature bone names to Unity humanoid format"""
bl_idname = "avatar_toolkit.convert_vrm_to_unity" bl_idname = "avatar_toolkit.convert_vrm_to_unity"
bl_label = "Convert VRM to Unity" bl_label = t("VRM.convert_to_unity.label")
bl_description = "Convert VRM armature bone names to Unity humanoid naming convention" bl_description = t("VRM.convert_to_unity.desc")
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
@classmethod @classmethod
@@ -23,7 +23,7 @@ class AvatarToolkit_OT_ConvertVRMToUnity(Operator):
armature = get_active_armature(context) armature = get_active_armature(context)
if not armature: if not armature:
logger.warning("No active armature found for VRM conversion") logger.warning("No active armature found for VRM conversion")
self.report({'ERROR'}, "No active armature selected") self.report({'ERROR'}, t("VRM.no_armature_selected"))
return {'CANCELLED'} return {'CANCELLED'}
logger.info(f"Starting VRM to Unity conversion for armature: {armature.name}") logger.info(f"Starting VRM to Unity conversion for armature: {armature.name}")
@@ -59,10 +59,10 @@ class AvatarToolkit_OT_ConvertVRMToUnity(Operator):
if is_valid: if is_valid:
logger.info("Unity hierarchy validation passed") logger.info("Unity hierarchy validation passed")
self.report({'INFO'}, "Unity hierarchy validation passed") self.report({'INFO'}, t("VRM.validation.hierarchy_passed"))
else: else:
logger.warning("Unity hierarchy validation found issues") logger.warning("Unity hierarchy validation found issues")
self.report({'WARNING'}, "Conversion completed but hierarchy validation found issues:") self.report({'WARNING'}, t("VRM.validation.hierarchy_issues"))
for msg in validation_messages: for msg in validation_messages:
self.report({'WARNING'}, msg) self.report({'WARNING'}, msg)
@@ -70,7 +70,7 @@ class AvatarToolkit_OT_ConvertVRMToUnity(Operator):
armature_valid, armature_messages, _ = validate_armature(armature) armature_valid, armature_messages, _ = validate_armature(armature)
if armature_valid: if armature_valid:
logger.info("Full armature validation passed") logger.info("Full armature validation passed")
self.report({'INFO'}, "Armature passes standard validation") self.report({'INFO'}, t("VRM.validation.armature_passed"))
else: else:
logger.info("Full armature validation found minor issues") logger.info("Full armature validation found minor issues")
# Don't report these as errors since the conversion was successful # Don't report these as errors since the conversion was successful
@@ -83,6 +83,6 @@ class AvatarToolkit_OT_ConvertVRMToUnity(Operator):
except Exception as e: except Exception as e:
logger.error(f"Error during hierarchy validation: {str(e)}") logger.error(f"Error during hierarchy validation: {str(e)}")
self.report({'WARNING'}, f"Conversion completed but validation failed: {str(e)}") self.report({'WARNING'}, t("VRM.validation.failed", error=str(e)))
return {'FINISHED'} return {'FINISHED'}
+37 -9
View File
@@ -325,6 +325,7 @@
"Visemes.success": "Visemes created successfully", "Visemes.success": "Visemes created successfully",
"Visemes.mesh_select": "Select Mesh", "Visemes.mesh_select": "Select Mesh",
"Visemes.mesh_select_desc": "Select the mesh to create visemes on", "Visemes.mesh_select_desc": "Select the mesh to create visemes on",
"Visemes.no_meshes": "No meshes found",
"EyeTracking.label": "Eye Tracking", "EyeTracking.label": "Eye Tracking",
"EyeTracking.setup": "Eye Tracking Setup", "EyeTracking.setup": "Eye Tracking Setup",
@@ -517,6 +518,8 @@
"TextureAtlas.save_file_instructions": "Use File > Save As... or click the button below:", "TextureAtlas.save_file_instructions": "Use File > Save As... or click the button below:",
"TextureAtlas.save_file_button": "Save Blender File", "TextureAtlas.save_file_button": "Save Blender File",
"TextureAtlas.save_file_required": "Save File Required", "TextureAtlas.save_file_required": "Save File Required",
"TextureAtlas.search_materials": "Search Materials",
"TextureAtlas.search_materials_desc": "Filter materials by name",
"Settings.label": "Settings", "Settings.label": "Settings",
"Settings.language": "Language", "Settings.language": "Language",
@@ -556,6 +559,39 @@
"Language.changed.success": "Language changed successfully!", "Language.changed.success": "Language changed successfully!",
"Language.changed.restart": "Some UI elements may require restarting Blender", "Language.changed.restart": "Some UI elements may require restarting Blender",
"VRM.panel.label": "VRM to Unity",
"VRM.converter.title": "VRM Converter",
"VRM.no_armature_selected": "No armature selected",
"VRM.select_armature_to_convert": "Select an armature to convert",
"VRM.armature_name": "Armature: {name}",
"VRM.armature_detected": "VRM armature detected",
"VRM.no_vrm_bones_detected": "No VRM bones detected",
"VRM.remove_colliders": "Remove Colliders",
"VRM.remove_root_bone": "Remove Root Bone",
"VRM.convert_to_unity_format": "Convert to Unity Format",
"VRM.convert_to_unity.label": "Convert VRM to Unity",
"VRM.convert_to_unity.desc": "Convert VRM armature bone names to Unity humanoid naming convention",
"VRM.conversion_info.title": "Conversion Info:",
"VRM.conversion_info.renames_bones": "• Renames VRM bones to Unity format",
"VRM.conversion_info.removes_colliders": "• Removes collider bones (optional)",
"VRM.conversion_info.removes_root": "• Removes root bone, makes Hips root (optional)",
"VRM.conversion_info.maintains_hierarchy": "• Maintains bone hierarchy",
"VRM.conversion_info.validates_results": "• Validates conversion results",
"VRM.conversion_info.preserves_animations": "• Preserves all animations",
"VRM.detection_failed.title": "VRM Detection Failed:",
"VRM.detection_failed.not_vrm_format": "• Selected armature is not VRM format",
"VRM.detection_failed.bones_start_with": "• VRM bones start with 'J_Bip_C_'",
"VRM.detection_failed.need_five_bones": "• Need at least 5 VRM bones detected",
"VRM.detection_failed.check_bone_names": "• Check armature bone names",
"VRM.validation.hierarchy_passed": "Unity hierarchy validation passed",
"VRM.validation.hierarchy_issues": "Conversion completed but hierarchy validation found issues:",
"VRM.validation.armature_passed": "Armature passes standard validation",
"VRM.validation.failed": "Conversion completed but validation failed: {error}"
"VRM.remove_colliders": "Remove Colliders",
"VRM.remove_colliders_desc": "Remove VRM collider bones during conversion",
"VRM.remove_root": "Remove Root Bone",
"VRM.remove_root_desc": "Remove unnecessary VRM root bone and make Hips the root bone",
"Translation.label": "Translation", "Translation.label": "Translation",
"Translation.service": "Translation Service", "Translation.service": "Translation Service",
"Translation.service_desc": "Choose the translation service to use", "Translation.service_desc": "Choose the translation service to use",
@@ -613,15 +649,7 @@
"Translation.server_url": "Server URL", "Translation.server_url": "Server URL",
"Translation.server_url_desc": "LibreTranslate server URL (e.g., https://your-server.com)", "Translation.server_url_desc": "LibreTranslate server URL (e.g., https://your-server.com)",
"Translation.api_key": "API Key", "Translation.api_key": "API Key",
"Translation.api_key_desc": "API key for LibreTranslate server (optional for some servers)", "Translation.api_key_desc": "API key for LibreTranslate server (optional for some servers)"
"VRM.remove_colliders": "Remove Colliders",
"VRM.remove_colliders_desc": "Remove VRM collider bones during conversion",
"VRM.remove_root": "Remove Root Bone",
"VRM.remove_root_desc": "Remove unnecessary VRM root bone and make Hips the root bone",
"Visemes.no_meshes": "No meshes found",
"TextureAtlas.search_materials": "Search Materials",
"TextureAtlas.search_materials_desc": "Filter materials by name"
} }
} }
+37 -10
View File
@@ -308,6 +308,7 @@
"Visemes.success": "口形素が正常に作成されました", "Visemes.success": "口形素が正常に作成されました",
"Visemes.mesh_select": "メッシュを選択", "Visemes.mesh_select": "メッシュを選択",
"Visemes.mesh_select_desc": "口形素を作成するメッシュを選択", "Visemes.mesh_select_desc": "口形素を作成するメッシュを選択",
"Visemes.no_meshes": "メッシュが見つかりません",
"EyeTracking.label": "アイトラッキング", "EyeTracking.label": "アイトラッキング",
"EyeTracking.setup": "アイトラッキング設定", "EyeTracking.setup": "アイトラッキング設定",
@@ -500,6 +501,8 @@
"TextureAtlas.save_file_instructions": "ファイル > 名前を付けて保存... を使用するか、下のボタンをクリックしてください:", "TextureAtlas.save_file_instructions": "ファイル > 名前を付けて保存... を使用するか、下のボタンをクリックしてください:",
"TextureAtlas.save_file_button": "Blenderファイルを保存", "TextureAtlas.save_file_button": "Blenderファイルを保存",
"TextureAtlas.save_file_required": "ファイルの保存が必要です", "TextureAtlas.save_file_required": "ファイルの保存が必要です",
"TextureAtlas.search_materials": "マテリアルを検索",
"TextureAtlas.search_materials_desc": "名前でマテリアルをフィルタリング",
"Settings.label": "設定", "Settings.label": "設定",
"Settings.language": "言語", "Settings.language": "言語",
@@ -539,6 +542,39 @@
"Language.changed.success": "言語が正常に変更されました!", "Language.changed.success": "言語が正常に変更されました!",
"Language.changed.restart": "一部のUI要素はBlenderの再起動が必要な場合があります", "Language.changed.restart": "一部のUI要素はBlenderの再起動が必要な場合があります",
"VRM.panel.label": "VRMからUnityへ",
"VRM.converter.title": "VRMコンバーター",
"VRM.no_armature_selected": "アーマチュアが選択されていません",
"VRM.select_armature_to_convert": "変換するアーマチュアを選択してください",
"VRM.armature_name": "アーマチュア: {name}",
"VRM.armature_detected": "VRMアーマチュアが検出されました",
"VRM.no_vrm_bones_detected": "VRMボーンが検出されませんでした",
"VRM.remove_colliders": "コライダーを削除",
"VRM.remove_root_bone": "ルートボーンを削除",
"VRM.convert_to_unity_format": "Unity形式に変換",
"VRM.convert_to_unity.label": "VRMをUnityに変換",
"VRM.convert_to_unity.desc": "VRMアーマチュアのボーン名をUnityヒューマノイド命名規則に変換",
"VRM.conversion_info.title": "変換情報:",
"VRM.conversion_info.renames_bones": "• VRMボーンをUnity形式にリネーム",
"VRM.conversion_info.removes_colliders": "• コライダーボーンを削除(オプション)",
"VRM.conversion_info.removes_root": "• ルートボーンを削除し、Hipsをルートにする(オプション)",
"VRM.conversion_info.maintains_hierarchy": "• ボーン階層を維持",
"VRM.conversion_info.validates_results": "• 変換結果を検証",
"VRM.conversion_info.preserves_animations": "• すべてのアニメーションを保持",
"VRM.detection_failed.title": "VRM検出失敗:",
"VRM.detection_failed.not_vrm_format": "• 選択されたアーマチュアはVRM形式ではありません",
"VRM.detection_failed.bones_start_with": "• VRMボーンは'J_Bip_C_'で始まります",
"VRM.detection_failed.need_five_bones": "• 少なくとも5つのVRMボーンが検出される必要があります",
"VRM.detection_failed.check_bone_names": "• アーマチュアのボーン名を確認してください",
"VRM.validation.hierarchy_passed": "Unity階層検証に合格しました",
"VRM.validation.hierarchy_issues": "変換は完了しましたが、階層検証で問題が見つかりました:",
"VRM.validation.armature_passed": "アーマチュアは標準検証に合格しました",
"VRM.validation.failed": "変換は完了しましたが、検証に失敗しました: {error}",
"VRM.remove_colliders": "コライダーを削除",
"VRM.remove_colliders_desc": "変換中にVRMコライダーボーンを削除",
"VRM.remove_root": "ルートボーンを削除",
"VRM.remove_root_desc": "不要なVRMルートボーンを削除し、ヒップをルートボーンにする",
"Translation.label": "翻訳", "Translation.label": "翻訳",
"Translation.service": "翻訳サービス", "Translation.service": "翻訳サービス",
"Translation.service_desc": "使用する翻訳サービスを選択", "Translation.service_desc": "使用する翻訳サービスを選択",
@@ -596,15 +632,6 @@
"Translation.server_url": "サーバーURL", "Translation.server_url": "サーバーURL",
"Translation.server_url_desc": "LibreTranslateサーバーURL(例:https://your-server.com", "Translation.server_url_desc": "LibreTranslateサーバーURL(例:https://your-server.com",
"Translation.api_key": "APIキー", "Translation.api_key": "APIキー",
"Translation.api_key_desc": "LibreTranslateサーバー用のAPIキー(一部のサーバーでは任意)", "Translation.api_key_desc": "LibreTranslateサーバー用のAPIキー(一部のサーバーでは任意)"
"VRM.remove_colliders": "コライダーを削除",
"VRM.remove_colliders_desc": "変換中にVRMコライダーボーンを削除",
"VRM.remove_root": "ルートボーンを削除",
"VRM.remove_root_desc": "不要なVRMルートボーンを削除し、ヒップをルートボーンにする",
"Visemes.no_meshes": "メッシュが見つかりません",
"TextureAtlas.search_materials": "マテリアルを検索",
"TextureAtlas.search_materials_desc": "名前でマテリアルをフィルタリング"
} }
} }
+37 -10
View File
@@ -308,6 +308,7 @@
"Visemes.success": "비셈 생성 성공", "Visemes.success": "비셈 생성 성공",
"Visemes.mesh_select": "메시 선택", "Visemes.mesh_select": "메시 선택",
"Visemes.mesh_select_desc": "비셈을 생성할 메시 선택", "Visemes.mesh_select_desc": "비셈을 생성할 메시 선택",
"Visemes.no_meshes": "메시를 찾을 수 없음",
"EyeTracking.label": "시선 추적", "EyeTracking.label": "시선 추적",
"EyeTracking.setup": "시선 추적 설정", "EyeTracking.setup": "시선 추적 설정",
@@ -500,6 +501,8 @@
"TextureAtlas.save_file_instructions": "파일 > 다른 이름으로 저장... 을 사용하거나 아래 버튼을 클릭하세요:", "TextureAtlas.save_file_instructions": "파일 > 다른 이름으로 저장... 을 사용하거나 아래 버튼을 클릭하세요:",
"TextureAtlas.save_file_button": "Blender 파일 저장", "TextureAtlas.save_file_button": "Blender 파일 저장",
"TextureAtlas.save_file_required": "파일 저장 필요", "TextureAtlas.save_file_required": "파일 저장 필요",
"TextureAtlas.search_materials": "재질 검색",
"TextureAtlas.search_materials_desc": "이름으로 재질 필터링",
"Settings.label": "설정", "Settings.label": "설정",
"Settings.language": "언어", "Settings.language": "언어",
@@ -539,6 +542,39 @@
"Language.changed.success": "언어가 성공적으로 변경되었습니다!", "Language.changed.success": "언어가 성공적으로 변경되었습니다!",
"Language.changed.restart": "일부 UI 요소는 블렌더를 다시 시작해야 할 수 있습니다", "Language.changed.restart": "일부 UI 요소는 블렌더를 다시 시작해야 할 수 있습니다",
"VRM.panel.label": "VRM에서 Unity로",
"VRM.converter.title": "VRM 변환기",
"VRM.no_armature_selected": "선택된 아마추어 없음",
"VRM.select_armature_to_convert": "변환할 아마추어를 선택하세요",
"VRM.armature_name": "아마추어: {name}",
"VRM.armature_detected": "VRM 아마추어 감지됨",
"VRM.no_vrm_bones_detected": "VRM 본이 감지되지 않음",
"VRM.remove_colliders": "콜라이더 제거",
"VRM.remove_root_bone": "루트 본 제거",
"VRM.convert_to_unity_format": "Unity 형식으로 변환",
"VRM.convert_to_unity.label": "VRM을 Unity로 변환",
"VRM.convert_to_unity.desc": "VRM 아마추어 본 이름을 Unity 휴머노이드 명명 규칙으로 변환",
"VRM.conversion_info.title": "변환 정보:",
"VRM.conversion_info.renames_bones": "• VRM 본을 Unity 형식으로 이름 변경",
"VRM.conversion_info.removes_colliders": "• 콜라이더 본 제거 (선택사항)",
"VRM.conversion_info.removes_root": "• 루트 본 제거, Hips를 루트로 설정 (선택사항)",
"VRM.conversion_info.maintains_hierarchy": "• 본 계층 구조 유지",
"VRM.conversion_info.validates_results": "• 변환 결과 검증",
"VRM.conversion_info.preserves_animations": "• 모든 애니메이션 보존",
"VRM.detection_failed.title": "VRM 감지 실패:",
"VRM.detection_failed.not_vrm_format": "• 선택된 아마추어가 VRM 형식이 아님",
"VRM.detection_failed.bones_start_with": "• VRM 본은 'J_Bip_C_'로 시작함",
"VRM.detection_failed.need_five_bones": "• 최소 5개의 VRM 본이 감지되어야 함",
"VRM.detection_failed.check_bone_names": "• 아마추어 본 이름을 확인하세요",
"VRM.validation.hierarchy_passed": "Unity 계층 구조 검증 통과",
"VRM.validation.hierarchy_issues": "변환은 완료되었지만 계층 구조 검증에서 문제를 발견했습니다:",
"VRM.validation.armature_passed": "아마추어가 표준 검증을 통과했습니다",
"VRM.validation.failed": "변환은 완료되었지만 검증에 실패했습니다: {error}",
"VRM.remove_colliders": "콜라이더 제거",
"VRM.remove_colliders_desc": "변환 중 VRM 콜라이더 본 제거",
"VRM.remove_root": "루트 본 제거",
"VRM.remove_root_desc": "불필요한 VRM 루트 본을 제거하고 힙을 루트 본으로 설정",
"Translation.label": "번역", "Translation.label": "번역",
"Translation.service": "번역 서비스", "Translation.service": "번역 서비스",
"Translation.service_desc": "사용할 번역 서비스 선택", "Translation.service_desc": "사용할 번역 서비스 선택",
@@ -596,15 +632,6 @@
"Translation.server_url": "서버 URL", "Translation.server_url": "서버 URL",
"Translation.server_url_desc": "LibreTranslate 서버 URL (예: https://your-server.com)", "Translation.server_url_desc": "LibreTranslate 서버 URL (예: https://your-server.com)",
"Translation.api_key": "API 키", "Translation.api_key": "API 키",
"Translation.api_key_desc": "LibreTranslate 서버용 API 키 (일부 서버는 선택사항)", "Translation.api_key_desc": "LibreTranslate 서버용 API 키 (일부 서버는 선택사항)"
"VRM.remove_colliders": "콜라이더 제거",
"VRM.remove_colliders_desc": "변환 중 VRM 콜라이더 본 제거",
"VRM.remove_root": "루트 본 제거",
"VRM.remove_root_desc": "불필요한 VRM 루트 본을 제거하고 힙을 루트 본으로 설정",
"Visemes.no_meshes": "메시를 찾을 수 없음",
"TextureAtlas.search_materials": "재질 검색",
"TextureAtlas.search_materials_desc": "이름으로 재질 필터링"
} }
} }
+24 -24
View File
@@ -9,7 +9,7 @@ from ..functions.tools.vrm_unity_conversion import AvatarToolkit_OT_ConvertVRMTo
class AvatarToolKit_PT_VRMUnityPanel(Panel): class AvatarToolKit_PT_VRMUnityPanel(Panel):
"""Panel for VRM to Unity conversion tools""" """Panel for VRM to Unity conversion tools"""
bl_label = "VRM to Unity" bl_label = t("VRM.panel.label")
bl_idname = "OBJECT_PT_avatar_toolkit_vrm_unity" bl_idname = "OBJECT_PT_avatar_toolkit_vrm_unity"
bl_space_type = 'VIEW_3D' bl_space_type = 'VIEW_3D'
bl_region_type = 'UI' bl_region_type = 'UI'
@@ -25,63 +25,63 @@ class AvatarToolKit_PT_VRMUnityPanel(Panel):
# VRM Conversion Tools # VRM Conversion Tools
vrm_box: UILayout = layout.box() vrm_box: UILayout = layout.box()
col: UILayout = vrm_box.column(align=True) col: UILayout = vrm_box.column(align=True)
col.label(text="VRM Converter", icon='ARMATURE_DATA') col.label(text=t("VRM.converter.title"), icon='ARMATURE_DATA')
col.separator(factor=0.5) col.separator(factor=0.5)
# Check if we have an active armature # Check if we have an active armature
armature = get_active_armature(context) armature = get_active_armature(context)
if not armature: if not armature:
col.label(text="No armature selected", icon='ERROR') col.label(text=t("VRM.no_armature_selected"), icon='ERROR')
col.label(text="Select an armature to convert") col.label(text=t("VRM.select_armature_to_convert"))
return return
# Check if the armature appears to be VRM # Check if the armature appears to be VRM
is_vrm = detect_vrm_armature(armature) is_vrm = detect_vrm_armature(armature)
if is_vrm: if is_vrm:
col.label(text=f"Armature: {armature.name}", icon='CHECKMARK') col.label(text=t("VRM.armature_name", name=armature.name), icon='CHECKMARK')
col.label(text="VRM armature detected", icon='INFO') col.label(text=t("VRM.armature_detected"), icon='INFO')
col.separator(factor=0.3) col.separator(factor=0.3)
toolkit = context.scene.avatar_toolkit toolkit = context.scene.avatar_toolkit
col.prop(toolkit, 'vrm_remove_colliders', text="Remove Colliders") col.prop(toolkit, 'vrm_remove_colliders', text=t("VRM.remove_colliders"))
col.prop(toolkit, 'vrm_remove_root', text="Remove Root Bone") col.prop(toolkit, 'vrm_remove_root', text=t("VRM.remove_root_bone"))
col.separator(factor=0.2) col.separator(factor=0.2)
col.operator( col.operator(
AvatarToolkit_OT_ConvertVRMToUnity.bl_idname, AvatarToolkit_OT_ConvertVRMToUnity.bl_idname,
text="Convert to Unity Format", text=t("VRM.convert_to_unity_format"),
icon='EXPORT' icon='EXPORT'
) )
info_box = vrm_box.box() info_box = vrm_box.box()
info_col = info_box.column(align=True) info_col = info_box.column(align=True)
info_col.label(text="Conversion Info:", icon='INFO') info_col.label(text=t("VRM.conversion_info.title"), icon='INFO')
info_col.label(text="• Renames VRM bones to Unity format") info_col.label(text=t("VRM.conversion_info.renames_bones"))
info_col.label(text="• Removes collider bones (optional)") info_col.label(text=t("VRM.conversion_info.removes_colliders"))
info_col.label(text="• Removes root bone, makes Hips root (optional)") info_col.label(text=t("VRM.conversion_info.removes_root"))
info_col.label(text="• Maintains bone hierarchy") info_col.label(text=t("VRM.conversion_info.maintains_hierarchy"))
info_col.label(text="• Validates conversion results") info_col.label(text=t("VRM.conversion_info.validates_results"))
info_col.label(text="• Preserves all animations") info_col.label(text=t("VRM.conversion_info.preserves_animations"))
else: else:
col.label(text=f"Armature: {armature.name}", icon='ERROR') col.label(text=t("VRM.armature_name", name=armature.name), icon='ERROR')
col.label(text="No VRM bones detected", icon='CANCEL') col.label(text=t("VRM.no_vrm_bones_detected"), icon='CANCEL')
col.separator(factor=0.3) col.separator(factor=0.3)
row = col.row() row = col.row()
row.enabled = False row.enabled = False
row.operator( row.operator(
AvatarToolkit_OT_ConvertVRMToUnity.bl_idname, AvatarToolkit_OT_ConvertVRMToUnity.bl_idname,
text="Convert to Unity Format", text=t("VRM.convert_to_unity_format"),
icon='CANCEL' icon='CANCEL'
) )
help_box = vrm_box.box() help_box = vrm_box.box()
help_col = help_box.column(align=True) help_col = help_box.column(align=True)
help_col.label(text="VRM Detection Failed:", icon='QUESTION') help_col.label(text=t("VRM.detection_failed.title"), icon='QUESTION')
help_col.label(text="• Selected armature is not VRM format") help_col.label(text=t("VRM.detection_failed.not_vrm_format"))
help_col.label(text="• VRM bones start with 'J_Bip_C_'") help_col.label(text=t("VRM.detection_failed.bones_start_with"))
help_col.label(text="• Need at least 5 VRM bones detected") help_col.label(text=t("VRM.detection_failed.need_five_bones"))
help_col.label(text="• Check armature bone names") help_col.label(text=t("VRM.detection_failed.check_bone_names"))