@volter/blender-engine 0.1.148 → 0.1.150
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -5
- package/README.md +4 -11
- package/browser/addons/vrm/LICENSE_(OPTION1)_MIT.txt +22 -0
- package/browser/addons/vrm/LICENSE_(OPTION2)_GPL-3_0.txt +674 -0
- package/browser/addons/vrm/LICENSE_MAIN.txt +1 -0
- package/browser/addons/vrm/README.txt +3 -0
- package/browser/addons/vrm/__init__.py +41 -0
- package/browser/addons/vrm/blender_manifest.toml +16 -0
- package/browser/addons/vrm/common/__init__.py +1 -0
- package/browser/addons/vrm/common/animation.py +58 -0
- package/browser/addons/vrm/common/blender_manifest.py +82 -0
- package/browser/addons/vrm/common/char.py +16 -0
- package/browser/addons/vrm/common/convert.py +287 -0
- package/browser/addons/vrm/common/convert_any.py +48 -0
- package/browser/addons/vrm/common/debug.py +40 -0
- package/browser/addons/vrm/common/deep.py +162 -0
- package/browser/addons/vrm/common/error_dialog.py +274 -0
- package/browser/addons/vrm/common/fs.py +71 -0
- package/browser/addons/vrm/common/gl.py +20 -0
- package/browser/addons/vrm/common/gltf.py +1149 -0
- package/browser/addons/vrm/common/human_bone_mapper/__init__.py +1 -0
- package/browser/addons/vrm/common/human_bone_mapper/biped_mapping.py +84 -0
- package/browser/addons/vrm/common/human_bone_mapper/cats_blender_plugin_fix_model_mapping.py +63 -0
- package/browser/addons/vrm/common/human_bone_mapper/human_bone_mapper.py +203 -0
- package/browser/addons/vrm/common/human_bone_mapper/microsoft_rocketbox_mapping.py +69 -0
- package/browser/addons/vrm/common/human_bone_mapper/mixamo_mapping.py +62 -0
- package/browser/addons/vrm/common/human_bone_mapper/mmd_mapping.py +115 -0
- package/browser/addons/vrm/common/human_bone_mapper/mpfb_mapping.py +120 -0
- package/browser/addons/vrm/common/human_bone_mapper/ready_player_me_mapping.py +65 -0
- package/browser/addons/vrm/common/human_bone_mapper/reallusion_mapping.py +94 -0
- package/browser/addons/vrm/common/human_bone_mapper/rigify_meta_rig_mapping.py +65 -0
- package/browser/addons/vrm/common/human_bone_mapper/structure_based_mapping.py +891 -0
- package/browser/addons/vrm/common/human_bone_mapper/unreal_mapping.py +62 -0
- package/browser/addons/vrm/common/human_bone_mapper/vrm_addon_mapping.py +112 -0
- package/browser/addons/vrm/common/human_bone_mapper/vroid_mapping.py +89 -0
- package/browser/addons/vrm/common/legacy_gltf.py +16 -0
- package/browser/addons/vrm/common/logger.py +84 -0
- package/browser/addons/vrm/common/mtoon0.blend +0 -0
- package/browser/addons/vrm/common/mtoon1.blend +0 -0
- package/browser/addons/vrm/common/mtoon1_outline.blend +0 -0
- package/browser/addons/vrm/common/mtoon_auto_setup.blend +0 -0
- package/browser/addons/vrm/common/mtoon_unversioned.py +62 -0
- package/browser/addons/vrm/common/ops/__init__.py +10 -0
- package/browser/addons/vrm/common/ops/export_scene.py +67 -0
- package/browser/addons/vrm/common/ops/icyp.py +53 -0
- package/browser/addons/vrm/common/ops/import_scene.py +57 -0
- package/browser/addons/vrm/common/ops/vrm.py +2380 -0
- package/browser/addons/vrm/common/ops/wm.py +167 -0
- package/browser/addons/vrm/common/preferences.py +362 -0
- package/browser/addons/vrm/common/progress.py +87 -0
- package/browser/addons/vrm/common/rotation.py +89 -0
- package/browser/addons/vrm/common/safe_removal.py +46 -0
- package/browser/addons/vrm/common/scene_watcher.py +230 -0
- package/browser/addons/vrm/common/shader.py +2243 -0
- package/browser/addons/vrm/common/shape_key_mapper/__init__.py +1 -0
- package/browser/addons/vrm/common/shape_key_mapper/arkit_mapping.py +168 -0
- package/browser/addons/vrm/common/shape_key_mapper/mmd_mapping.py +62 -0
- package/browser/addons/vrm/common/shape_key_mapper/ready_player_me_mapping.py +52 -0
- package/browser/addons/vrm/common/shape_key_mapper/vrchat_mapping.py +17 -0
- package/browser/addons/vrm/common/third_party_user_extension.py +214 -0
- package/browser/addons/vrm/common/transparent_z_write.blend +0 -0
- package/browser/addons/vrm/common/version.py +161 -0
- package/browser/addons/vrm/common/vrm0/__init__.py +1 -0
- package/browser/addons/vrm/common/vrm0/human_bone.py +662 -0
- package/browser/addons/vrm/common/vrm0/material_property.py +346 -0
- package/browser/addons/vrm/common/vrm1/__init__.py +1 -0
- package/browser/addons/vrm/common/vrm1/expression_preset.py +207 -0
- package/browser/addons/vrm/common/vrm1/human_bone.py +822 -0
- package/browser/addons/vrm/common/workspace.py +227 -0
- package/browser/addons/vrm/common/writable_context.py +77 -0
- package/browser/addons/vrm/documentation/en-us/animation/index.md +63 -0
- package/browser/addons/vrm/documentation/en-us/create-humanoid-vrm-from-scratch/index.md +131 -0
- package/browser/addons/vrm/documentation/en-us/create-simple-vrm-from-scratch/index.md +30 -0
- package/browser/addons/vrm/documentation/en-us/development/index.md +136 -0
- package/browser/addons/vrm/documentation/en-us/index.md +41 -0
- package/browser/addons/vrm/documentation/en-us/installation/index.md +152 -0
- package/browser/addons/vrm/documentation/en-us/material-mtoon/index.md +122 -0
- package/browser/addons/vrm/documentation/en-us/material-pbr/index.md +94 -0
- package/browser/addons/vrm/documentation/en-us/scripting-api/index.md +391 -0
- package/browser/addons/vrm/documentation/en-us/ui/export_scene.vrm/index.md +57 -0
- package/browser/addons/vrm/documentation/en-us/ui/export_scene.vrma/index.md +17 -0
- package/browser/addons/vrm/documentation/en-us/ui/import_scene.vrm/index.md +61 -0
- package/browser/addons/vrm/documentation/en-us/ui/import_scene.vrma/index.md +13 -0
- package/browser/addons/vrm/documentation/ja-jp/animation/index.md +57 -0
- package/browser/addons/vrm/documentation/ja-jp/create-humanoid-vrm-from-scratch/index.md +129 -0
- package/browser/addons/vrm/documentation/ja-jp/create-simple-vrm-from-scratch/index.md +29 -0
- package/browser/addons/vrm/documentation/ja-jp/development/index.md +137 -0
- package/browser/addons/vrm/documentation/ja-jp/index.md +37 -0
- package/browser/addons/vrm/documentation/ja-jp/installation/index.md +150 -0
- package/browser/addons/vrm/documentation/ja-jp/material-mtoon/index.md +113 -0
- package/browser/addons/vrm/documentation/ja-jp/material-pbr/index.md +90 -0
- package/browser/addons/vrm/documentation/ja-jp/scripting-api/index.md +389 -0
- package/browser/addons/vrm/documentation/ja-jp/ui/export_scene.vrm/index.md +55 -0
- package/browser/addons/vrm/documentation/ja-jp/ui/export_scene.vrma/index.md +19 -0
- package/browser/addons/vrm/documentation/ja-jp/ui/import_scene.vrm/index.md +56 -0
- package/browser/addons/vrm/documentation/ja-jp/ui/import_scene.vrma/index.md +14 -0
- package/browser/addons/vrm/editor/__init__.py +1 -0
- package/browser/addons/vrm/editor/extension.py +425 -0
- package/browser/addons/vrm/editor/extension_accessor.py +75 -0
- package/browser/addons/vrm/editor/handler.py +84 -0
- package/browser/addons/vrm/editor/khr_character/__init__.py +1 -0
- package/browser/addons/vrm/editor/khr_character/panel.py +69 -0
- package/browser/addons/vrm/editor/khr_character/property_group.py +27 -0
- package/browser/addons/vrm/editor/khr_xmp_json_ld/__init__.py +1 -0
- package/browser/addons/vrm/editor/khr_xmp_json_ld/ops.py +464 -0
- package/browser/addons/vrm/editor/khr_xmp_json_ld/panel.py +136 -0
- package/browser/addons/vrm/editor/khr_xmp_json_ld/property_group.py +83 -0
- package/browser/addons/vrm/editor/khr_xmp_json_ld/ui_list.py +198 -0
- package/browser/addons/vrm/editor/make_armature.py +709 -0
- package/browser/addons/vrm/editor/menu.py +147 -0
- package/browser/addons/vrm/editor/migration.py +297 -0
- package/browser/addons/vrm/editor/mtoon1/__init__.py +1 -0
- package/browser/addons/vrm/editor/mtoon1/handler.py +20 -0
- package/browser/addons/vrm/editor/mtoon1/migration.py +536 -0
- package/browser/addons/vrm/editor/mtoon1/ops.py +304 -0
- package/browser/addons/vrm/editor/mtoon1/panel.py +442 -0
- package/browser/addons/vrm/editor/mtoon1/property_group.py +4977 -0
- package/browser/addons/vrm/editor/mtoon1/scene_watcher.py +381 -0
- package/browser/addons/vrm/editor/node_constraint1/__init__.py +1 -0
- package/browser/addons/vrm/editor/node_constraint1/panel.py +317 -0
- package/browser/addons/vrm/editor/node_constraint1/property_group.py +25 -0
- package/browser/addons/vrm/editor/ops.py +471 -0
- package/browser/addons/vrm/editor/panel.py +315 -0
- package/browser/addons/vrm/editor/property_group.py +888 -0
- package/browser/addons/vrm/editor/search.py +682 -0
- package/browser/addons/vrm/editor/spring_bone1/__init__.py +1 -0
- package/browser/addons/vrm/editor/spring_bone1/handler.py +994 -0
- package/browser/addons/vrm/editor/spring_bone1/menu.py +246 -0
- package/browser/addons/vrm/editor/spring_bone1/migration.py +86 -0
- package/browser/addons/vrm/editor/spring_bone1/ops.py +1679 -0
- package/browser/addons/vrm/editor/spring_bone1/panel.py +605 -0
- package/browser/addons/vrm/editor/spring_bone1/property_group.py +1457 -0
- package/browser/addons/vrm/editor/spring_bone1/ui_list.py +408 -0
- package/browser/addons/vrm/editor/subscription.py +123 -0
- package/browser/addons/vrm/editor/t_pose.py +713 -0
- package/browser/addons/vrm/editor/validation.py +1271 -0
- package/browser/addons/vrm/editor/vrm0/__init__.py +1 -0
- package/browser/addons/vrm/editor/vrm0/gizmo_group.py +63 -0
- package/browser/addons/vrm/editor/vrm0/handler.py +23 -0
- package/browser/addons/vrm/editor/vrm0/menu.py +145 -0
- package/browser/addons/vrm/editor/vrm0/migration.py +761 -0
- package/browser/addons/vrm/editor/vrm0/ops.py +2145 -0
- package/browser/addons/vrm/editor/vrm0/panel.py +1333 -0
- package/browser/addons/vrm/editor/vrm0/property_group.py +1818 -0
- package/browser/addons/vrm/editor/vrm0/ui_list.py +688 -0
- package/browser/addons/vrm/editor/vrm1/__init__.py +1 -0
- package/browser/addons/vrm/editor/vrm1/handler.py +28 -0
- package/browser/addons/vrm/editor/vrm1/menu.py +76 -0
- package/browser/addons/vrm/editor/vrm1/migration.py +321 -0
- package/browser/addons/vrm/editor/vrm1/ops.py +2679 -0
- package/browser/addons/vrm/editor/vrm1/panel.py +1243 -0
- package/browser/addons/vrm/editor/vrm1/property_group.py +2087 -0
- package/browser/addons/vrm/editor/vrm1/scene_watcher.py +90 -0
- package/browser/addons/vrm/editor/vrm1/ui_list.py +533 -0
- package/browser/addons/vrm/exporter/__init__.py +1 -0
- package/browser/addons/vrm/exporter/abstract_base_vrm_exporter.py +628 -0
- package/browser/addons/vrm/exporter/export_scene.py +930 -0
- package/browser/addons/vrm/exporter/gltf2_export_user_extension.py +45 -0
- package/browser/addons/vrm/exporter/khr_character_exporter.py +34 -0
- package/browser/addons/vrm/exporter/vrm0_exporter.py +4020 -0
- package/browser/addons/vrm/exporter/vrm1_exporter.py +3682 -0
- package/browser/addons/vrm/exporter/vrm_animation_exporter.py +1035 -0
- package/browser/addons/vrm/external/__init__.py +1 -0
- package/browser/addons/vrm/external/auto_rig_pro_support.py +3 -0
- package/browser/addons/vrm/external/io_scene_gltf2_support.py +418 -0
- package/browser/addons/vrm/external/rigify_support.py +1 -0
- package/browser/addons/vrm/importer/__init__.py +1 -0
- package/browser/addons/vrm/importer/abstract_base_vrm_importer.py +1548 -0
- package/browser/addons/vrm/importer/file_handler.py +34 -0
- package/browser/addons/vrm/importer/gltf2_import_user_extension.py +268 -0
- package/browser/addons/vrm/importer/import_scene.py +646 -0
- package/browser/addons/vrm/importer/license_validation.py +198 -0
- package/browser/addons/vrm/importer/vrm0_importer.py +1723 -0
- package/browser/addons/vrm/importer/vrm1_importer.py +2014 -0
- package/browser/addons/vrm/importer/vrm_animation_importer.py +763 -0
- package/browser/addons/vrm/importer/vrm_diff.py +316 -0
- package/browser/addons/vrm/locale/__init__.py +1 -0
- package/browser/addons/vrm/locale/ja_jp.py +826 -0
- package/browser/addons/vrm/locale/ruff.toml +8 -0
- package/browser/addons/vrm/locale/translation_dictionary.py +10 -0
- package/browser/addons/vrm/locale/zh_hans.py +928 -0
- package/browser/addons/vrm/registration.py +670 -0
- package/browser/addons/vrm.json +18 -0
- package/browser/blender-emscripten-engine.mts +66 -129
- package/browser/blender-engine.mts +20 -186
- package/browser/blender-wali-engine.mts +37 -81
- package/browser/describe-thrown.mts +3 -6
- package/browser/document-chunks.mts +4 -16
- package/browser/gltf_export.py +3161 -0
- package/browser/heap-growth.mts +23 -0
- package/browser/index.ts +3 -0
- package/browser/protocol.ts +130 -43
- package/browser/pull-job.mts +2 -10
- package/browser/rna.ts +190 -73
- package/browser/runtime.ts +271 -106
- package/browser/session-addons.mts +33 -0
- package/browser/session-frame.mts +5 -24
- package/browser/session.py +1389 -1446
- package/browser/three/attach-presenter.ts +11 -39
- package/browser/three/blender-base64.ts +1 -36
- package/browser/three/blender-corner-normals.ts +1 -23
- package/browser/three/blender-display-shaders.json +1 -1
- package/browser/three/blender-display-shaders.lut +0 -0
- package/browser/three/blender-display-transform.ts +2 -1
- package/browser/three/blender-frame-columns.ts +5 -13
- package/browser/three/blender-graph-material.ts +18 -3
- package/browser/three/blender-node-graph.ts +10 -34
- package/browser/three/blender-physical-material.ts +2 -31
- package/browser/three/blender-runtime-armature.ts +7 -60
- package/browser/three/blender-runtime-frame.ts +9 -23
- package/browser/three/blender-runtime-geometry.ts +22 -26
- package/browser/three/blender-runtime-lighting.ts +48 -178
- package/browser/three/blender-runtime-shadows.ts +187 -1
- package/browser/three/blender-runtime-skeleton.ts +53 -1
- package/browser/three/blender-runtime-view.ts +492 -306
- package/browser/three/blender-runtime-weights.ts +9 -72
- package/browser/three/blender-sky.ts +13 -33
- package/browser/three/blender-triangulate.ts +7 -35
- package/browser/three/blender-viewport-sampling.ts +235 -0
- package/browser/three/blender-workbench-material.ts +25 -29
- package/browser/three/blender-workbench-outline.ts +199 -0
- package/browser/three/blender-world-volume.ts +62 -10
- package/browser/three/presenter.ts +10 -26
- package/browser/three/release.ts +5 -21
- package/browser/three/sky-precompute-worker.ts +1 -18
- package/browser/three/sky-worker.ts +5 -23
- package/browser/three/world-field-sampler.ts +12 -26
- package/browser/volter_three.py +9 -105
- package/browser/worker.ts +195 -180
- package/package.json +5 -2
- package/wasm/BUNDLE.json +17 -17
- package/wasm/DEPENDENCY-LICENSES.txt +14 -0
- package/wasm/blender_browser.data.br +0 -0
- package/wasm/blender_browser.js +1 -1
- package/wasm/blender_browser.wasm.br +0 -0
- package/browser/frame-transfer.mts +0 -19
- package/browser/three/agx-base-srgb.lut +0 -0
- package/browser/three/agx-look-medium-high-contrast.lut +0 -0
- package/browser/three/agx-look-punchy.lut +0 -0
- package/browser/three/blender-agx.ts +0 -235
- package/browser/three/blender-display-lut.ts +0 -145
- package/browser/three/blender-filmic.ts +0 -49
- package/browser/three/blender-standard.ts +0 -68
- package/browser/three/blender-world-visibility.ts +0 -278
- package/browser/three/filmic-srgb.lut +0 -0
|
@@ -0,0 +1,1679 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT OR GPL-3.0-or-later
|
|
2
|
+
import uuid
|
|
3
|
+
from collections import deque
|
|
4
|
+
from sys import float_info
|
|
5
|
+
from typing import TYPE_CHECKING, ClassVar, Optional
|
|
6
|
+
|
|
7
|
+
from bpy.props import BoolProperty, FloatProperty, IntProperty, StringProperty
|
|
8
|
+
from bpy.types import Armature, Bone, ChildOfConstraint, Context, Object, Operator
|
|
9
|
+
from mathutils import Vector
|
|
10
|
+
|
|
11
|
+
from ...common import safe_removal
|
|
12
|
+
from ...common.logger import get_logger
|
|
13
|
+
from ..extension_accessor import get_armature_extension
|
|
14
|
+
from .handler import reset_state, update_pose_bone_rotations
|
|
15
|
+
from .property_group import (
|
|
16
|
+
SpringBone1ColliderGroupReferencePropertyGroup,
|
|
17
|
+
SpringBone1ColliderReferencePropertyGroup,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
logger = get_logger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class VRM_OT_add_spring_bone1_collider(Operator):
|
|
24
|
+
bl_idname = "vrm.add_spring_bone1_collider"
|
|
25
|
+
bl_label = "Add Collider"
|
|
26
|
+
bl_description = "Add VRM 1.0 Collider"
|
|
27
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
28
|
+
|
|
29
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
30
|
+
options={"HIDDEN"},
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
def execute(self, context: Context) -> set[str]:
|
|
34
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
35
|
+
if armature is None or armature.type != "ARMATURE":
|
|
36
|
+
return {"CANCELLED"}
|
|
37
|
+
armature_data = armature.data
|
|
38
|
+
if not isinstance(armature_data, Armature):
|
|
39
|
+
return {"CANCELLED"}
|
|
40
|
+
spring_bone1 = get_armature_extension(armature_data).spring_bone1
|
|
41
|
+
spring_bone1.add_collider(context, armature)
|
|
42
|
+
return {"FINISHED"}
|
|
43
|
+
|
|
44
|
+
if TYPE_CHECKING:
|
|
45
|
+
# This code is auto generated.
|
|
46
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
47
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class VRM_OT_remove_spring_bone1_collider(Operator):
|
|
51
|
+
bl_idname = "vrm.remove_spring_bone1_collider"
|
|
52
|
+
bl_label = "Remove Collider"
|
|
53
|
+
bl_description = "Remove VRM 0.x Collider"
|
|
54
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
55
|
+
|
|
56
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
57
|
+
options={"HIDDEN"},
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
collider_index: IntProperty( # type: ignore[valid-type]
|
|
61
|
+
options={"HIDDEN"},
|
|
62
|
+
min=0,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
def execute(self, context: Context) -> set[str]:
|
|
66
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
67
|
+
if armature is None or armature.type != "ARMATURE":
|
|
68
|
+
return {"CANCELLED"}
|
|
69
|
+
armature_data = armature.data
|
|
70
|
+
if not isinstance(armature_data, Armature):
|
|
71
|
+
return {"CANCELLED"}
|
|
72
|
+
spring_bone = get_armature_extension(armature_data).spring_bone1
|
|
73
|
+
if len(spring_bone.colliders) <= self.collider_index:
|
|
74
|
+
return {"CANCELLED"}
|
|
75
|
+
|
|
76
|
+
collider = spring_bone.colliders[self.collider_index]
|
|
77
|
+
bpy_object = collider.bpy_object
|
|
78
|
+
if bpy_object:
|
|
79
|
+
collider.bpy_object = None
|
|
80
|
+
for unnecessary_object in (*bpy_object.children, bpy_object):
|
|
81
|
+
if not safe_removal.remove_object(context, unnecessary_object):
|
|
82
|
+
logger.warning(
|
|
83
|
+
'Failed to remove "%s" with %d users'
|
|
84
|
+
" while removing spring bone collider object",
|
|
85
|
+
unnecessary_object.name,
|
|
86
|
+
unnecessary_object.users,
|
|
87
|
+
)
|
|
88
|
+
bpy_object = None
|
|
89
|
+
|
|
90
|
+
collider_uuid = spring_bone.colliders[self.collider_index].uuid
|
|
91
|
+
for collider_group in spring_bone.collider_groups:
|
|
92
|
+
for index in reversed(range(len(collider_group.colliders))):
|
|
93
|
+
if not (0 <= index < len(collider_group.colliders)):
|
|
94
|
+
continue
|
|
95
|
+
collider_reference = collider_group.colliders[index]
|
|
96
|
+
if collider_reference.collider_uuid == collider_uuid:
|
|
97
|
+
collider_group.colliders.remove(index)
|
|
98
|
+
collider_group.active_collider_index = min(
|
|
99
|
+
collider_group.active_collider_index,
|
|
100
|
+
max(0, len(collider_group.colliders) - 1),
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
spring_bone.colliders.remove(self.collider_index)
|
|
104
|
+
|
|
105
|
+
spring_bone.active_collider_index = min(
|
|
106
|
+
spring_bone.active_collider_index,
|
|
107
|
+
max(0, len(spring_bone.colliders) - 1),
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
return {"FINISHED"}
|
|
111
|
+
|
|
112
|
+
if TYPE_CHECKING:
|
|
113
|
+
# This code is auto generated.
|
|
114
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
115
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
116
|
+
collider_index: int # type: ignore[no-redef]
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class VRM_OT_move_up_spring_bone1_collider_group(Operator):
|
|
120
|
+
bl_idname = "vrm.move_up_spring_bone1_collider_group"
|
|
121
|
+
bl_label = "Move Up Collider Group"
|
|
122
|
+
bl_description = "Move Up VRM 1.0 Collider Group"
|
|
123
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
124
|
+
|
|
125
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
126
|
+
options={"HIDDEN"},
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
collider_group_index: IntProperty( # type: ignore[valid-type]
|
|
130
|
+
options={"HIDDEN"},
|
|
131
|
+
min=0,
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
def execute(self, context: Context) -> set[str]:
|
|
135
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
136
|
+
if armature is None or armature.type != "ARMATURE":
|
|
137
|
+
return {"CANCELLED"}
|
|
138
|
+
armature_data = armature.data
|
|
139
|
+
if not isinstance(armature_data, Armature):
|
|
140
|
+
return {"CANCELLED"}
|
|
141
|
+
spring_bone = get_armature_extension(armature_data).spring_bone1
|
|
142
|
+
if len(spring_bone.collider_groups) <= self.collider_group_index:
|
|
143
|
+
return {"CANCELLED"}
|
|
144
|
+
new_index = (self.collider_group_index - 1) % len(spring_bone.collider_groups)
|
|
145
|
+
spring_bone.collider_groups.move(self.collider_group_index, new_index)
|
|
146
|
+
spring_bone.active_collider_group_index = new_index
|
|
147
|
+
return {"FINISHED"}
|
|
148
|
+
|
|
149
|
+
if TYPE_CHECKING:
|
|
150
|
+
# This code is auto generated.
|
|
151
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
152
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
153
|
+
collider_group_index: int # type: ignore[no-redef]
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class VRM_OT_move_down_spring_bone1_collider_group(Operator):
|
|
157
|
+
bl_idname = "vrm.move_down_spring_bone1_collider_group"
|
|
158
|
+
bl_label = "Move Down Collider Group"
|
|
159
|
+
bl_description = "Move Down VRM 1.0 Collider Group"
|
|
160
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
161
|
+
|
|
162
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
163
|
+
options={"HIDDEN"},
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
collider_group_index: IntProperty( # type: ignore[valid-type]
|
|
167
|
+
options={"HIDDEN"},
|
|
168
|
+
min=0,
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
def execute(self, context: Context) -> set[str]:
|
|
172
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
173
|
+
if armature is None or armature.type != "ARMATURE":
|
|
174
|
+
return {"CANCELLED"}
|
|
175
|
+
armature_data = armature.data
|
|
176
|
+
if not isinstance(armature_data, Armature):
|
|
177
|
+
return {"CANCELLED"}
|
|
178
|
+
spring_bone = get_armature_extension(armature_data).spring_bone1
|
|
179
|
+
if len(spring_bone.collider_groups) <= self.collider_group_index:
|
|
180
|
+
return {"CANCELLED"}
|
|
181
|
+
new_index = (self.collider_group_index + 1) % len(spring_bone.collider_groups)
|
|
182
|
+
spring_bone.collider_groups.move(self.collider_group_index, new_index)
|
|
183
|
+
spring_bone.active_collider_group_index = new_index
|
|
184
|
+
return {"FINISHED"}
|
|
185
|
+
|
|
186
|
+
if TYPE_CHECKING:
|
|
187
|
+
# This code is auto generated.
|
|
188
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
189
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
190
|
+
collider_group_index: int # type: ignore[no-redef]
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
class VRM_OT_add_spring_bone1_spring(Operator):
|
|
194
|
+
bl_idname = "vrm.add_spring_bone1_spring"
|
|
195
|
+
bl_label = "Add Spring"
|
|
196
|
+
bl_description = "Add VRM 1.0 Spring"
|
|
197
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
198
|
+
|
|
199
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
200
|
+
options={"HIDDEN"},
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
def execute(self, context: Context) -> set[str]:
|
|
204
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
205
|
+
if armature is None or armature.type != "ARMATURE":
|
|
206
|
+
return {"CANCELLED"}
|
|
207
|
+
armature_data = armature.data
|
|
208
|
+
if not isinstance(armature_data, Armature):
|
|
209
|
+
return {"CANCELLED"}
|
|
210
|
+
spring_bone1 = get_armature_extension(armature_data).spring_bone1
|
|
211
|
+
spring_bone1.add_spring()
|
|
212
|
+
return {"FINISHED"}
|
|
213
|
+
|
|
214
|
+
if TYPE_CHECKING:
|
|
215
|
+
# This code is auto generated.
|
|
216
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
217
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
class VRM_OT_remove_spring_bone1_spring(Operator):
|
|
221
|
+
bl_idname = "vrm.remove_spring_bone1_spring"
|
|
222
|
+
bl_label = "Remove Spring"
|
|
223
|
+
bl_description = "Remove VRM 1.0 Spring"
|
|
224
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
225
|
+
|
|
226
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
227
|
+
options={"HIDDEN"},
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
spring_index: IntProperty( # type: ignore[valid-type]
|
|
231
|
+
options={"HIDDEN"},
|
|
232
|
+
min=0,
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
def execute(self, context: Context) -> set[str]:
|
|
236
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
237
|
+
if armature is None or armature.type != "ARMATURE":
|
|
238
|
+
return {"CANCELLED"}
|
|
239
|
+
armature_data = armature.data
|
|
240
|
+
if not isinstance(armature_data, Armature):
|
|
241
|
+
return {"CANCELLED"}
|
|
242
|
+
spring_bone1 = get_armature_extension(armature_data).spring_bone1
|
|
243
|
+
if len(spring_bone1.springs) <= self.spring_index:
|
|
244
|
+
return {"CANCELLED"}
|
|
245
|
+
spring_bone1.springs.remove(self.spring_index)
|
|
246
|
+
spring_bone1.active_spring_index = min(
|
|
247
|
+
spring_bone1.active_spring_index, max(0, len(spring_bone1.springs) - 1)
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
return {"FINISHED"}
|
|
251
|
+
|
|
252
|
+
if TYPE_CHECKING:
|
|
253
|
+
# This code is auto generated.
|
|
254
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
255
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
256
|
+
spring_index: int # type: ignore[no-redef]
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
class VRM_OT_move_up_spring_bone1_spring(Operator):
|
|
260
|
+
bl_idname = "vrm.move_up_spring_bone1_spring"
|
|
261
|
+
bl_label = "Move Up Spring"
|
|
262
|
+
bl_description = "Move Up VRM 1.0 Spring"
|
|
263
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
264
|
+
|
|
265
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
266
|
+
options={"HIDDEN"},
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
spring_index: IntProperty( # type: ignore[valid-type]
|
|
270
|
+
options={"HIDDEN"},
|
|
271
|
+
min=0,
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
def execute(self, context: Context) -> set[str]:
|
|
275
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
276
|
+
if armature is None or armature.type != "ARMATURE":
|
|
277
|
+
return {"CANCELLED"}
|
|
278
|
+
armature_data = armature.data
|
|
279
|
+
if not isinstance(armature_data, Armature):
|
|
280
|
+
return {"CANCELLED"}
|
|
281
|
+
spring_bone1 = get_armature_extension(armature_data).spring_bone1
|
|
282
|
+
springs = spring_bone1.springs
|
|
283
|
+
if len(springs) <= self.spring_index:
|
|
284
|
+
return {"CANCELLED"}
|
|
285
|
+
new_spring_index = (self.spring_index - 1) % len(springs)
|
|
286
|
+
springs.move(self.spring_index, new_spring_index)
|
|
287
|
+
spring_bone1.active_spring_index = new_spring_index
|
|
288
|
+
return {"FINISHED"}
|
|
289
|
+
|
|
290
|
+
if TYPE_CHECKING:
|
|
291
|
+
# This code is auto generated.
|
|
292
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
293
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
294
|
+
spring_index: int # type: ignore[no-redef]
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
class VRM_OT_move_down_spring_bone1_spring(Operator):
|
|
298
|
+
bl_idname = "vrm.move_down_spring_bone1_spring"
|
|
299
|
+
bl_label = "Move Down Spring"
|
|
300
|
+
bl_description = "Move Down VRM 1.0 Spring"
|
|
301
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
302
|
+
|
|
303
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
304
|
+
options={"HIDDEN"},
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
spring_index: IntProperty( # type: ignore[valid-type]
|
|
308
|
+
options={"HIDDEN"},
|
|
309
|
+
min=0,
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
def execute(self, context: Context) -> set[str]:
|
|
313
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
314
|
+
if armature is None or armature.type != "ARMATURE":
|
|
315
|
+
return {"CANCELLED"}
|
|
316
|
+
armature_data = armature.data
|
|
317
|
+
if not isinstance(armature_data, Armature):
|
|
318
|
+
return {"CANCELLED"}
|
|
319
|
+
spring_bone1 = get_armature_extension(armature_data).spring_bone1
|
|
320
|
+
springs = spring_bone1.springs
|
|
321
|
+
if len(springs) <= self.spring_index:
|
|
322
|
+
return {"CANCELLED"}
|
|
323
|
+
new_spring_index = (self.spring_index + 1) % len(springs)
|
|
324
|
+
springs.move(self.spring_index, new_spring_index)
|
|
325
|
+
spring_bone1.active_spring_index = new_spring_index
|
|
326
|
+
return {"FINISHED"}
|
|
327
|
+
|
|
328
|
+
if TYPE_CHECKING:
|
|
329
|
+
# This code is auto generated.
|
|
330
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
331
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
332
|
+
spring_index: int # type: ignore[no-redef]
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
class VRM_OT_add_spring_bone1_collider_group(Operator):
|
|
336
|
+
bl_idname = "vrm.add_spring_bone1_collider_group"
|
|
337
|
+
bl_label = "Add Collider Group"
|
|
338
|
+
bl_description = "Add VRM 1.0 Spring Bone Collider Group"
|
|
339
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
340
|
+
|
|
341
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
342
|
+
options={"HIDDEN"},
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
def execute(self, context: Context) -> set[str]:
|
|
346
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
347
|
+
if armature is None or armature.type != "ARMATURE":
|
|
348
|
+
return {"CANCELLED"}
|
|
349
|
+
armature_data = armature.data
|
|
350
|
+
if not isinstance(armature_data, Armature):
|
|
351
|
+
return {"CANCELLED"}
|
|
352
|
+
spring_bone = get_armature_extension(armature_data).spring_bone1
|
|
353
|
+
spring_bone.add_collider_group()
|
|
354
|
+
return {"FINISHED"}
|
|
355
|
+
|
|
356
|
+
if TYPE_CHECKING:
|
|
357
|
+
# This code is auto generated.
|
|
358
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
359
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
class VRM_OT_remove_spring_bone1_collider_group(Operator):
|
|
363
|
+
bl_idname = "vrm.remove_spring_bone1_collider_group"
|
|
364
|
+
bl_label = "Remove Collider Group"
|
|
365
|
+
bl_description = "Remove VRM 1.0 Spring Bone Collider Group"
|
|
366
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
367
|
+
|
|
368
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
369
|
+
options={"HIDDEN"},
|
|
370
|
+
)
|
|
371
|
+
|
|
372
|
+
collider_group_index: IntProperty( # type: ignore[valid-type]
|
|
373
|
+
options={"HIDDEN"},
|
|
374
|
+
min=0,
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
def execute(self, context: Context) -> set[str]:
|
|
378
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
379
|
+
if armature is None or armature.type != "ARMATURE":
|
|
380
|
+
return {"CANCELLED"}
|
|
381
|
+
armature_data = armature.data
|
|
382
|
+
if not isinstance(armature_data, Armature):
|
|
383
|
+
return {"CANCELLED"}
|
|
384
|
+
spring_bone = get_armature_extension(armature_data).spring_bone1
|
|
385
|
+
collider_groups = spring_bone.collider_groups
|
|
386
|
+
if len(collider_groups) <= self.collider_group_index:
|
|
387
|
+
return {"CANCELLED"}
|
|
388
|
+
|
|
389
|
+
collider_group_uuid = collider_groups[self.collider_group_index].uuid
|
|
390
|
+
for spring in spring_bone.springs:
|
|
391
|
+
for index in reversed(range(len(spring.collider_groups))):
|
|
392
|
+
if not (0 <= index < len(spring.collider_groups)):
|
|
393
|
+
continue
|
|
394
|
+
collider_group_reference = spring.collider_groups[index]
|
|
395
|
+
if collider_group_reference.collider_group_uuid == collider_group_uuid:
|
|
396
|
+
spring.collider_groups.remove(index)
|
|
397
|
+
spring.active_collider_group_index = min(
|
|
398
|
+
spring.active_collider_group_index,
|
|
399
|
+
max(0, len(spring.collider_groups) - 1),
|
|
400
|
+
)
|
|
401
|
+
|
|
402
|
+
collider_groups.remove(self.collider_group_index)
|
|
403
|
+
|
|
404
|
+
spring_bone.active_collider_group_index = min(
|
|
405
|
+
spring_bone.active_collider_group_index,
|
|
406
|
+
max(0, len(spring_bone.collider_groups) - 1),
|
|
407
|
+
)
|
|
408
|
+
|
|
409
|
+
return {"FINISHED"}
|
|
410
|
+
|
|
411
|
+
if TYPE_CHECKING:
|
|
412
|
+
# This code is auto generated.
|
|
413
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
414
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
415
|
+
collider_group_index: int # type: ignore[no-redef]
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
class VRM_OT_move_up_spring_bone1_collider(Operator):
|
|
419
|
+
bl_idname = "vrm.move_up_spring_bone1_collider"
|
|
420
|
+
bl_label = "Move Up Collider"
|
|
421
|
+
bl_description = "Move Up VRM 1.0 Collider"
|
|
422
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
423
|
+
|
|
424
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
425
|
+
options={"HIDDEN"},
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
collider_index: IntProperty( # type: ignore[valid-type]
|
|
429
|
+
options={"HIDDEN"},
|
|
430
|
+
min=0,
|
|
431
|
+
)
|
|
432
|
+
|
|
433
|
+
def execute(self, context: Context) -> set[str]:
|
|
434
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
435
|
+
if armature is None or armature.type != "ARMATURE":
|
|
436
|
+
return {"CANCELLED"}
|
|
437
|
+
armature_data = armature.data
|
|
438
|
+
if not isinstance(armature_data, Armature):
|
|
439
|
+
return {"CANCELLED"}
|
|
440
|
+
spring_bone1 = get_armature_extension(armature_data).spring_bone1
|
|
441
|
+
colliders = spring_bone1.colliders
|
|
442
|
+
if len(colliders) <= self.collider_index:
|
|
443
|
+
return {"CANCELLED"}
|
|
444
|
+
new_collider_index = (self.collider_index - 1) % len(colliders)
|
|
445
|
+
colliders.move(self.collider_index, new_collider_index)
|
|
446
|
+
spring_bone1.active_collider_index = new_collider_index
|
|
447
|
+
return {"FINISHED"}
|
|
448
|
+
|
|
449
|
+
if TYPE_CHECKING:
|
|
450
|
+
# This code is auto generated.
|
|
451
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
452
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
453
|
+
collider_index: int # type: ignore[no-redef]
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
class VRM_OT_move_down_spring_bone1_collider(Operator):
|
|
457
|
+
bl_idname = "vrm.move_down_spring_bone1_collider"
|
|
458
|
+
bl_label = "Move Down Collider"
|
|
459
|
+
bl_description = "Move Down VRM 1.0 Collider"
|
|
460
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
461
|
+
|
|
462
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
463
|
+
options={"HIDDEN"},
|
|
464
|
+
)
|
|
465
|
+
|
|
466
|
+
collider_index: IntProperty( # type: ignore[valid-type]
|
|
467
|
+
options={"HIDDEN"},
|
|
468
|
+
min=0,
|
|
469
|
+
)
|
|
470
|
+
|
|
471
|
+
def execute(self, context: Context) -> set[str]:
|
|
472
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
473
|
+
if armature is None or armature.type != "ARMATURE":
|
|
474
|
+
return {"CANCELLED"}
|
|
475
|
+
armature_data = armature.data
|
|
476
|
+
if not isinstance(armature_data, Armature):
|
|
477
|
+
return {"CANCELLED"}
|
|
478
|
+
spring_bone1 = get_armature_extension(armature_data).spring_bone1
|
|
479
|
+
colliders = spring_bone1.colliders
|
|
480
|
+
if len(colliders) <= self.collider_index:
|
|
481
|
+
return {"CANCELLED"}
|
|
482
|
+
new_collider_index = (self.collider_index + 1) % len(colliders)
|
|
483
|
+
colliders.move(self.collider_index, new_collider_index)
|
|
484
|
+
spring_bone1.active_collider_index = new_collider_index
|
|
485
|
+
return {"FINISHED"}
|
|
486
|
+
|
|
487
|
+
if TYPE_CHECKING:
|
|
488
|
+
# This code is auto generated.
|
|
489
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
490
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
491
|
+
collider_index: int # type: ignore[no-redef]
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
class VRM_OT_add_spring_bone1_collider_group_collider(Operator):
|
|
495
|
+
bl_idname = "vrm.add_spring_bone1_collider_group_collider"
|
|
496
|
+
bl_label = "Add Collider"
|
|
497
|
+
bl_description = "Add VRM 1.0 Spring Bone Collider Group Collider"
|
|
498
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
499
|
+
|
|
500
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
501
|
+
options={"HIDDEN"},
|
|
502
|
+
)
|
|
503
|
+
|
|
504
|
+
collider_group_index: IntProperty( # type: ignore[valid-type]
|
|
505
|
+
options={"HIDDEN"},
|
|
506
|
+
min=0,
|
|
507
|
+
)
|
|
508
|
+
|
|
509
|
+
def execute(self, context: Context) -> set[str]:
|
|
510
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
511
|
+
if armature is None or armature.type != "ARMATURE":
|
|
512
|
+
return {"CANCELLED"}
|
|
513
|
+
armature_data = armature.data
|
|
514
|
+
if not isinstance(armature_data, Armature):
|
|
515
|
+
return {"CANCELLED"}
|
|
516
|
+
collider_groups = get_armature_extension(
|
|
517
|
+
armature_data
|
|
518
|
+
).spring_bone1.collider_groups
|
|
519
|
+
if len(collider_groups) <= self.collider_group_index:
|
|
520
|
+
return {"CANCELLED"}
|
|
521
|
+
collider_group = collider_groups[self.collider_group_index]
|
|
522
|
+
collider_group.add_collider()
|
|
523
|
+
return {"FINISHED"}
|
|
524
|
+
|
|
525
|
+
if TYPE_CHECKING:
|
|
526
|
+
# This code is auto generated.
|
|
527
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
528
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
529
|
+
collider_group_index: int # type: ignore[no-redef]
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
class VRM_OT_assign_spring_bone1_collider_group_collider(Operator):
|
|
533
|
+
bl_idname = "vrm.assign_spring_bone1_collider_group_collider"
|
|
534
|
+
bl_label = "Assign Collider"
|
|
535
|
+
bl_description = "Assign VRM 1.0 Spring Bone Collider Group Collider"
|
|
536
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
537
|
+
|
|
538
|
+
armature_data_name: StringProperty( # type: ignore[valid-type]
|
|
539
|
+
options={"HIDDEN"},
|
|
540
|
+
)
|
|
541
|
+
collider_reference_path: StringProperty( # type: ignore[valid-type]
|
|
542
|
+
options={"HIDDEN"},
|
|
543
|
+
)
|
|
544
|
+
collider_uuid: StringProperty( # type: ignore[valid-type]
|
|
545
|
+
options={"HIDDEN"},
|
|
546
|
+
)
|
|
547
|
+
|
|
548
|
+
def execute(self, context: Context) -> set[str]:
|
|
549
|
+
armature_data = context.blend_data.armatures.get(self.armature_data_name)
|
|
550
|
+
if not isinstance(armature_data, Armature):
|
|
551
|
+
return {"CANCELLED"}
|
|
552
|
+
|
|
553
|
+
collider_reference = armature_data.path_resolve(
|
|
554
|
+
self.collider_reference_path,
|
|
555
|
+
False,
|
|
556
|
+
)
|
|
557
|
+
if not isinstance(
|
|
558
|
+
collider_reference, SpringBone1ColliderReferencePropertyGroup
|
|
559
|
+
):
|
|
560
|
+
return {"CANCELLED"}
|
|
561
|
+
|
|
562
|
+
if not self.collider_uuid:
|
|
563
|
+
collider_reference.collider_uuid = ""
|
|
564
|
+
return {"FINISHED"}
|
|
565
|
+
|
|
566
|
+
spring_bone1 = get_armature_extension(armature_data).spring_bone1
|
|
567
|
+
for collider in spring_bone1.colliders:
|
|
568
|
+
if collider.uuid != self.collider_uuid:
|
|
569
|
+
continue
|
|
570
|
+
collider_reference.collider_uuid = collider.uuid
|
|
571
|
+
return {"FINISHED"}
|
|
572
|
+
|
|
573
|
+
return {"CANCELLED"}
|
|
574
|
+
|
|
575
|
+
if TYPE_CHECKING:
|
|
576
|
+
# This code is auto generated.
|
|
577
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
578
|
+
armature_data_name: str # type: ignore[no-redef]
|
|
579
|
+
collider_reference_path: str # type: ignore[no-redef]
|
|
580
|
+
collider_uuid: str # type: ignore[no-redef]
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
class VRM_OT_unassign_spring_bone1_collider_group_collider(Operator):
|
|
584
|
+
bl_idname = "vrm.unassign_spring_bone1_collider_group_collider"
|
|
585
|
+
bl_label = "Unassign Collider"
|
|
586
|
+
bl_description = "Unassign VRM 1.0 Spring Bone Collider Group Collider"
|
|
587
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
588
|
+
|
|
589
|
+
armature_data_name: StringProperty( # type: ignore[valid-type]
|
|
590
|
+
options={"HIDDEN"},
|
|
591
|
+
)
|
|
592
|
+
collider_reference_path: StringProperty( # type: ignore[valid-type]
|
|
593
|
+
options={"HIDDEN"},
|
|
594
|
+
)
|
|
595
|
+
|
|
596
|
+
def execute(self, context: Context) -> set[str]:
|
|
597
|
+
armature_data = context.blend_data.armatures.get(self.armature_data_name)
|
|
598
|
+
if not isinstance(armature_data, Armature):
|
|
599
|
+
return {"CANCELLED"}
|
|
600
|
+
|
|
601
|
+
collider_reference = armature_data.path_resolve(
|
|
602
|
+
self.collider_reference_path,
|
|
603
|
+
False,
|
|
604
|
+
)
|
|
605
|
+
if not isinstance(
|
|
606
|
+
collider_reference, SpringBone1ColliderReferencePropertyGroup
|
|
607
|
+
):
|
|
608
|
+
return {"CANCELLED"}
|
|
609
|
+
|
|
610
|
+
collider_reference.collider_uuid = ""
|
|
611
|
+
return {"FINISHED"}
|
|
612
|
+
|
|
613
|
+
if TYPE_CHECKING:
|
|
614
|
+
# This code is auto generated.
|
|
615
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
616
|
+
armature_data_name: str # type: ignore[no-redef]
|
|
617
|
+
collider_reference_path: str # type: ignore[no-redef]
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
class VRM_OT_remove_spring_bone1_collider_group_collider(Operator):
|
|
621
|
+
bl_idname = "vrm.remove_spring_bone1_collider_group_collider"
|
|
622
|
+
bl_label = "Remove Collider"
|
|
623
|
+
bl_description = "Remove VRM 1.0 Spring Bone Collider Group Collider"
|
|
624
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
625
|
+
|
|
626
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
627
|
+
options={"HIDDEN"},
|
|
628
|
+
)
|
|
629
|
+
|
|
630
|
+
collider_group_index: IntProperty( # type: ignore[valid-type]
|
|
631
|
+
options={"HIDDEN"},
|
|
632
|
+
min=0,
|
|
633
|
+
)
|
|
634
|
+
collider_index: IntProperty( # type: ignore[valid-type]
|
|
635
|
+
options={"HIDDEN"},
|
|
636
|
+
min=0,
|
|
637
|
+
)
|
|
638
|
+
|
|
639
|
+
def execute(self, context: Context) -> set[str]:
|
|
640
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
641
|
+
if armature is None or armature.type != "ARMATURE":
|
|
642
|
+
return {"CANCELLED"}
|
|
643
|
+
armature_data = armature.data
|
|
644
|
+
if not isinstance(armature_data, Armature):
|
|
645
|
+
return {"CANCELLED"}
|
|
646
|
+
collider_groups = get_armature_extension(
|
|
647
|
+
armature_data
|
|
648
|
+
).spring_bone1.collider_groups
|
|
649
|
+
if len(collider_groups) <= self.collider_group_index:
|
|
650
|
+
return {"CANCELLED"}
|
|
651
|
+
collider_group = collider_groups[self.collider_group_index]
|
|
652
|
+
if len(collider_group.colliders) <= self.collider_index:
|
|
653
|
+
return {"CANCELLED"}
|
|
654
|
+
collider_group.colliders.remove(self.collider_index)
|
|
655
|
+
collider_group.active_collider_index = min(
|
|
656
|
+
collider_group.active_collider_index,
|
|
657
|
+
max(0, len(collider_group.colliders) - 1),
|
|
658
|
+
)
|
|
659
|
+
return {"FINISHED"}
|
|
660
|
+
|
|
661
|
+
if TYPE_CHECKING:
|
|
662
|
+
# This code is auto generated.
|
|
663
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
664
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
665
|
+
collider_group_index: int # type: ignore[no-redef]
|
|
666
|
+
collider_index: int # type: ignore[no-redef]
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
class VRM_OT_move_up_spring_bone1_collider_group_collider(Operator):
|
|
670
|
+
bl_idname = "vrm.move_up_spring_bone1_collider_group_collider"
|
|
671
|
+
bl_label = "Move Up Collider"
|
|
672
|
+
bl_description = "Move Up VRM 1.0 Collider Group Collider"
|
|
673
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
674
|
+
|
|
675
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
676
|
+
options={"HIDDEN"},
|
|
677
|
+
)
|
|
678
|
+
|
|
679
|
+
collider_group_index: IntProperty( # type: ignore[valid-type]
|
|
680
|
+
options={"HIDDEN"},
|
|
681
|
+
min=0,
|
|
682
|
+
)
|
|
683
|
+
collider_index: IntProperty( # type: ignore[valid-type]
|
|
684
|
+
options={"HIDDEN"},
|
|
685
|
+
min=0,
|
|
686
|
+
)
|
|
687
|
+
|
|
688
|
+
def execute(self, context: Context) -> set[str]:
|
|
689
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
690
|
+
if armature is None or armature.type != "ARMATURE":
|
|
691
|
+
return {"CANCELLED"}
|
|
692
|
+
armature_data = armature.data
|
|
693
|
+
if not isinstance(armature_data, Armature):
|
|
694
|
+
return {"CANCELLED"}
|
|
695
|
+
spring_bone1 = get_armature_extension(armature_data).spring_bone1
|
|
696
|
+
if len(spring_bone1.collider_groups) <= self.collider_group_index:
|
|
697
|
+
return {"CANCELLED"}
|
|
698
|
+
collider_group = spring_bone1.collider_groups[self.collider_group_index]
|
|
699
|
+
if len(collider_group.colliders) <= self.collider_index:
|
|
700
|
+
return {"CANCELLED"}
|
|
701
|
+
new_collider_index = (self.collider_index - 1) % len(collider_group.colliders)
|
|
702
|
+
collider_group.colliders.move(self.collider_index, new_collider_index)
|
|
703
|
+
collider_group.active_collider_index = new_collider_index
|
|
704
|
+
return {"FINISHED"}
|
|
705
|
+
|
|
706
|
+
if TYPE_CHECKING:
|
|
707
|
+
# This code is auto generated.
|
|
708
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
709
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
710
|
+
collider_group_index: int # type: ignore[no-redef]
|
|
711
|
+
collider_index: int # type: ignore[no-redef]
|
|
712
|
+
|
|
713
|
+
|
|
714
|
+
class VRM_OT_move_down_spring_bone1_collider_group_collider(Operator):
|
|
715
|
+
bl_idname = "vrm.move_down_spring_bone1_collider_group_collider"
|
|
716
|
+
bl_label = "Move Down Collider"
|
|
717
|
+
bl_description = "Move Down VRM 1.0 Collider Group Collider"
|
|
718
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
719
|
+
|
|
720
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
721
|
+
options={"HIDDEN"},
|
|
722
|
+
)
|
|
723
|
+
|
|
724
|
+
collider_group_index: IntProperty( # type: ignore[valid-type]
|
|
725
|
+
options={"HIDDEN"},
|
|
726
|
+
min=0,
|
|
727
|
+
)
|
|
728
|
+
collider_index: IntProperty( # type: ignore[valid-type]
|
|
729
|
+
options={"HIDDEN"},
|
|
730
|
+
min=0,
|
|
731
|
+
)
|
|
732
|
+
|
|
733
|
+
def execute(self, context: Context) -> set[str]:
|
|
734
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
735
|
+
if armature is None or armature.type != "ARMATURE":
|
|
736
|
+
return {"CANCELLED"}
|
|
737
|
+
armature_data = armature.data
|
|
738
|
+
if not isinstance(armature_data, Armature):
|
|
739
|
+
return {"CANCELLED"}
|
|
740
|
+
spring_bone1 = get_armature_extension(armature_data).spring_bone1
|
|
741
|
+
if len(spring_bone1.collider_groups) <= self.collider_group_index:
|
|
742
|
+
return {"CANCELLED"}
|
|
743
|
+
collider_group = spring_bone1.collider_groups[self.collider_group_index]
|
|
744
|
+
if len(collider_group.colliders) <= self.collider_index:
|
|
745
|
+
return {"CANCELLED"}
|
|
746
|
+
new_collider_index = (self.collider_index + 1) % len(collider_group.colliders)
|
|
747
|
+
collider_group.colliders.move(self.collider_index, new_collider_index)
|
|
748
|
+
collider_group.active_collider_index = new_collider_index
|
|
749
|
+
return {"FINISHED"}
|
|
750
|
+
|
|
751
|
+
if TYPE_CHECKING:
|
|
752
|
+
# This code is auto generated.
|
|
753
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
754
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
755
|
+
collider_group_index: int # type: ignore[no-redef]
|
|
756
|
+
collider_index: int # type: ignore[no-redef]
|
|
757
|
+
|
|
758
|
+
|
|
759
|
+
class VRM_OT_add_spring_bone1_spring_collider_group(Operator):
|
|
760
|
+
bl_idname = "vrm.add_spring_bone1_spring_collider_group"
|
|
761
|
+
bl_label = "Add Collider Group"
|
|
762
|
+
bl_description = "Add VRM 1.0 Spring Bone Spring Collider Group"
|
|
763
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
764
|
+
|
|
765
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
766
|
+
options={"HIDDEN"},
|
|
767
|
+
)
|
|
768
|
+
|
|
769
|
+
spring_index: IntProperty( # type: ignore[valid-type]
|
|
770
|
+
options={"HIDDEN"},
|
|
771
|
+
min=0,
|
|
772
|
+
)
|
|
773
|
+
|
|
774
|
+
def execute(self, context: Context) -> set[str]:
|
|
775
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
776
|
+
if armature is None or armature.type != "ARMATURE":
|
|
777
|
+
return {"CANCELLED"}
|
|
778
|
+
armature_data = armature.data
|
|
779
|
+
if not isinstance(armature_data, Armature):
|
|
780
|
+
return {"CANCELLED"}
|
|
781
|
+
springs = get_armature_extension(armature_data).spring_bone1.springs
|
|
782
|
+
if len(springs) <= self.spring_index:
|
|
783
|
+
return {"CANCELLED"}
|
|
784
|
+
spring = springs[self.spring_index]
|
|
785
|
+
spring.add_collider_group()
|
|
786
|
+
return {"FINISHED"}
|
|
787
|
+
|
|
788
|
+
if TYPE_CHECKING:
|
|
789
|
+
# This code is auto generated.
|
|
790
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
791
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
792
|
+
spring_index: int # type: ignore[no-redef]
|
|
793
|
+
|
|
794
|
+
|
|
795
|
+
class VRM_OT_assign_spring_bone1_spring_collider_group(Operator):
|
|
796
|
+
bl_idname = "vrm.assign_spring_bone1_spring_collider_group"
|
|
797
|
+
bl_label = "Assign Collider Group"
|
|
798
|
+
bl_description = "Assign VRM 1.0 Spring Bone Spring Collider Group"
|
|
799
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
800
|
+
|
|
801
|
+
armature_data_name: StringProperty( # type: ignore[valid-type]
|
|
802
|
+
options={"HIDDEN"},
|
|
803
|
+
)
|
|
804
|
+
collider_group_reference_path: StringProperty( # type: ignore[valid-type]
|
|
805
|
+
options={"HIDDEN"},
|
|
806
|
+
)
|
|
807
|
+
collider_group_uuid: StringProperty( # type: ignore[valid-type]
|
|
808
|
+
options={"HIDDEN"},
|
|
809
|
+
)
|
|
810
|
+
|
|
811
|
+
def execute(self, context: Context) -> set[str]:
|
|
812
|
+
armature_data = context.blend_data.armatures.get(self.armature_data_name)
|
|
813
|
+
if not isinstance(armature_data, Armature):
|
|
814
|
+
return {"CANCELLED"}
|
|
815
|
+
|
|
816
|
+
collider_group_reference = armature_data.path_resolve(
|
|
817
|
+
self.collider_group_reference_path,
|
|
818
|
+
False,
|
|
819
|
+
)
|
|
820
|
+
if not isinstance(
|
|
821
|
+
collider_group_reference,
|
|
822
|
+
SpringBone1ColliderGroupReferencePropertyGroup,
|
|
823
|
+
):
|
|
824
|
+
return {"CANCELLED"}
|
|
825
|
+
|
|
826
|
+
if not self.collider_group_uuid:
|
|
827
|
+
collider_group_reference.collider_group_uuid = ""
|
|
828
|
+
return {"FINISHED"}
|
|
829
|
+
|
|
830
|
+
spring_bone1 = get_armature_extension(armature_data).spring_bone1
|
|
831
|
+
for collider_group in spring_bone1.collider_groups:
|
|
832
|
+
if collider_group.uuid != self.collider_group_uuid:
|
|
833
|
+
continue
|
|
834
|
+
collider_group_reference.collider_group_uuid = collider_group.uuid
|
|
835
|
+
return {"FINISHED"}
|
|
836
|
+
|
|
837
|
+
return {"CANCELLED"}
|
|
838
|
+
|
|
839
|
+
if TYPE_CHECKING:
|
|
840
|
+
# This code is auto generated.
|
|
841
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
842
|
+
armature_data_name: str # type: ignore[no-redef]
|
|
843
|
+
collider_group_reference_path: str # type: ignore[no-redef]
|
|
844
|
+
collider_group_uuid: str # type: ignore[no-redef]
|
|
845
|
+
|
|
846
|
+
|
|
847
|
+
class VRM_OT_unassign_spring_bone1_spring_collider_group(Operator):
|
|
848
|
+
bl_idname = "vrm.unassign_spring_bone1_spring_collider_group"
|
|
849
|
+
bl_label = "Unassign Collider Group"
|
|
850
|
+
bl_description = "Unassign VRM 1.0 Spring Bone Spring Collider Group"
|
|
851
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
852
|
+
|
|
853
|
+
armature_data_name: StringProperty( # type: ignore[valid-type]
|
|
854
|
+
options={"HIDDEN"},
|
|
855
|
+
)
|
|
856
|
+
collider_group_reference_path: StringProperty( # type: ignore[valid-type]
|
|
857
|
+
options={"HIDDEN"},
|
|
858
|
+
)
|
|
859
|
+
|
|
860
|
+
def execute(self, context: Context) -> set[str]:
|
|
861
|
+
armature_data = context.blend_data.armatures.get(self.armature_data_name)
|
|
862
|
+
if not isinstance(armature_data, Armature):
|
|
863
|
+
return {"CANCELLED"}
|
|
864
|
+
|
|
865
|
+
collider_group_reference = armature_data.path_resolve(
|
|
866
|
+
self.collider_group_reference_path,
|
|
867
|
+
False,
|
|
868
|
+
)
|
|
869
|
+
if not isinstance(
|
|
870
|
+
collider_group_reference,
|
|
871
|
+
SpringBone1ColliderGroupReferencePropertyGroup,
|
|
872
|
+
):
|
|
873
|
+
return {"CANCELLED"}
|
|
874
|
+
|
|
875
|
+
collider_group_reference.collider_group_uuid = ""
|
|
876
|
+
return {"FINISHED"}
|
|
877
|
+
|
|
878
|
+
if TYPE_CHECKING:
|
|
879
|
+
# This code is auto generated.
|
|
880
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
881
|
+
armature_data_name: str # type: ignore[no-redef]
|
|
882
|
+
collider_group_reference_path: str # type: ignore[no-redef]
|
|
883
|
+
|
|
884
|
+
|
|
885
|
+
class VRM_OT_remove_spring_bone1_spring_collider_group(Operator):
|
|
886
|
+
bl_idname = "vrm.remove_spring_bone1_spring_collider_group"
|
|
887
|
+
bl_label = "Remove Collider Group"
|
|
888
|
+
bl_description = "Remove VRM 1.0 Spring Bone Spring Collider Group"
|
|
889
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
890
|
+
|
|
891
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
892
|
+
options={"HIDDEN"},
|
|
893
|
+
)
|
|
894
|
+
|
|
895
|
+
spring_index: IntProperty( # type: ignore[valid-type]
|
|
896
|
+
options={"HIDDEN"},
|
|
897
|
+
min=0,
|
|
898
|
+
)
|
|
899
|
+
collider_group_index: IntProperty( # type: ignore[valid-type]
|
|
900
|
+
options={"HIDDEN"},
|
|
901
|
+
min=0,
|
|
902
|
+
)
|
|
903
|
+
|
|
904
|
+
def execute(self, context: Context) -> set[str]:
|
|
905
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
906
|
+
if armature is None or armature.type != "ARMATURE":
|
|
907
|
+
return {"CANCELLED"}
|
|
908
|
+
armature_data = armature.data
|
|
909
|
+
if not isinstance(armature_data, Armature):
|
|
910
|
+
return {"CANCELLED"}
|
|
911
|
+
springs = get_armature_extension(armature_data).spring_bone1.springs
|
|
912
|
+
if len(springs) <= self.spring_index:
|
|
913
|
+
return {"CANCELLED"}
|
|
914
|
+
spring = springs[self.spring_index]
|
|
915
|
+
if len(spring.collider_groups) <= self.collider_group_index:
|
|
916
|
+
return {"CANCELLED"}
|
|
917
|
+
spring.collider_groups.remove(self.collider_group_index)
|
|
918
|
+
spring.active_collider_group_index = min(
|
|
919
|
+
spring.active_collider_group_index, max(0, len(spring.collider_groups) - 1)
|
|
920
|
+
)
|
|
921
|
+
return {"FINISHED"}
|
|
922
|
+
|
|
923
|
+
if TYPE_CHECKING:
|
|
924
|
+
# This code is auto generated.
|
|
925
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
926
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
927
|
+
spring_index: int # type: ignore[no-redef]
|
|
928
|
+
collider_group_index: int # type: ignore[no-redef]
|
|
929
|
+
|
|
930
|
+
|
|
931
|
+
class VRM_OT_move_up_spring_bone1_spring_collider_group(Operator):
|
|
932
|
+
bl_idname = "vrm.move_up_spring_bone1_spring_collider_group"
|
|
933
|
+
bl_label = "Move Up Collider Group"
|
|
934
|
+
bl_description = "Move Up VRM 1.0 Spring Collider Group"
|
|
935
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
936
|
+
|
|
937
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
938
|
+
options={"HIDDEN"},
|
|
939
|
+
)
|
|
940
|
+
|
|
941
|
+
spring_index: IntProperty( # type: ignore[valid-type]
|
|
942
|
+
options={"HIDDEN"},
|
|
943
|
+
min=0,
|
|
944
|
+
)
|
|
945
|
+
collider_group_index: IntProperty( # type: ignore[valid-type]
|
|
946
|
+
options={"HIDDEN"},
|
|
947
|
+
min=0,
|
|
948
|
+
)
|
|
949
|
+
|
|
950
|
+
def execute(self, context: Context) -> set[str]:
|
|
951
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
952
|
+
if armature is None or armature.type != "ARMATURE":
|
|
953
|
+
return {"CANCELLED"}
|
|
954
|
+
armature_data = armature.data
|
|
955
|
+
if not isinstance(armature_data, Armature):
|
|
956
|
+
return {"CANCELLED"}
|
|
957
|
+
spring_bone1 = get_armature_extension(armature_data).spring_bone1
|
|
958
|
+
springs = spring_bone1.springs
|
|
959
|
+
if len(springs) <= self.spring_index:
|
|
960
|
+
return {"CANCELLED"}
|
|
961
|
+
spring = springs[self.spring_index]
|
|
962
|
+
if len(spring.collider_groups) <= self.collider_group_index:
|
|
963
|
+
return {"CANCELLED"}
|
|
964
|
+
new_collider_group_index = (self.collider_group_index - 1) % len(
|
|
965
|
+
spring.collider_groups
|
|
966
|
+
)
|
|
967
|
+
spring.collider_groups.move(self.collider_group_index, new_collider_group_index)
|
|
968
|
+
spring.active_collider_group_index = new_collider_group_index
|
|
969
|
+
return {"FINISHED"}
|
|
970
|
+
|
|
971
|
+
if TYPE_CHECKING:
|
|
972
|
+
# This code is auto generated.
|
|
973
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
974
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
975
|
+
spring_index: int # type: ignore[no-redef]
|
|
976
|
+
collider_group_index: int # type: ignore[no-redef]
|
|
977
|
+
|
|
978
|
+
|
|
979
|
+
class VRM_OT_move_down_spring_bone1_spring_collider_group(Operator):
|
|
980
|
+
bl_idname = "vrm.move_down_spring_bone1_spring_collider_group"
|
|
981
|
+
bl_label = "Move Down Collider Group"
|
|
982
|
+
bl_description = "Move Down VRM 1.0 Spring Collider Group"
|
|
983
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
984
|
+
|
|
985
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
986
|
+
options={"HIDDEN"},
|
|
987
|
+
)
|
|
988
|
+
|
|
989
|
+
spring_index: IntProperty( # type: ignore[valid-type]
|
|
990
|
+
options={"HIDDEN"},
|
|
991
|
+
min=0,
|
|
992
|
+
)
|
|
993
|
+
collider_group_index: IntProperty( # type: ignore[valid-type]
|
|
994
|
+
options={"HIDDEN"},
|
|
995
|
+
min=0,
|
|
996
|
+
)
|
|
997
|
+
|
|
998
|
+
def execute(self, context: Context) -> set[str]:
|
|
999
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
1000
|
+
if armature is None or armature.type != "ARMATURE":
|
|
1001
|
+
return {"CANCELLED"}
|
|
1002
|
+
armature_data = armature.data
|
|
1003
|
+
if not isinstance(armature_data, Armature):
|
|
1004
|
+
return {"CANCELLED"}
|
|
1005
|
+
spring_bone1 = get_armature_extension(armature_data).spring_bone1
|
|
1006
|
+
springs = spring_bone1.springs
|
|
1007
|
+
if len(springs) <= self.spring_index:
|
|
1008
|
+
return {"CANCELLED"}
|
|
1009
|
+
spring = springs[self.spring_index]
|
|
1010
|
+
if len(spring.collider_groups) <= self.collider_group_index:
|
|
1011
|
+
return {"CANCELLED"}
|
|
1012
|
+
new_collider_group_index = (self.collider_group_index + 1) % len(
|
|
1013
|
+
spring.collider_groups
|
|
1014
|
+
)
|
|
1015
|
+
spring.collider_groups.move(self.collider_group_index, new_collider_group_index)
|
|
1016
|
+
spring.active_collider_group_index = new_collider_group_index
|
|
1017
|
+
return {"FINISHED"}
|
|
1018
|
+
|
|
1019
|
+
if TYPE_CHECKING:
|
|
1020
|
+
# This code is auto generated.
|
|
1021
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
1022
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
1023
|
+
spring_index: int # type: ignore[no-redef]
|
|
1024
|
+
collider_group_index: int # type: ignore[no-redef]
|
|
1025
|
+
|
|
1026
|
+
|
|
1027
|
+
class VRM_OT_add_spring_bone1_joint(Operator):
|
|
1028
|
+
bl_idname = "vrm.add_spring_bone1_spring_joint"
|
|
1029
|
+
bl_label = "Add Joint"
|
|
1030
|
+
bl_description = "Add VRM 1.0 Spring Bone Spring Joint"
|
|
1031
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
1032
|
+
|
|
1033
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
1034
|
+
options={"HIDDEN"},
|
|
1035
|
+
)
|
|
1036
|
+
|
|
1037
|
+
spring_index: IntProperty( # type: ignore[valid-type]
|
|
1038
|
+
options={"HIDDEN"},
|
|
1039
|
+
min=0,
|
|
1040
|
+
)
|
|
1041
|
+
guess_properties: BoolProperty( # type: ignore[valid-type]
|
|
1042
|
+
options={"HIDDEN"},
|
|
1043
|
+
)
|
|
1044
|
+
|
|
1045
|
+
def execute(self, context: Context) -> set[str]:
|
|
1046
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
1047
|
+
if armature is None or armature.type != "ARMATURE":
|
|
1048
|
+
return {"CANCELLED"}
|
|
1049
|
+
armature_data = armature.data
|
|
1050
|
+
if not isinstance(armature_data, Armature):
|
|
1051
|
+
return {"CANCELLED"}
|
|
1052
|
+
springs = get_armature_extension(armature_data).spring_bone1.springs
|
|
1053
|
+
if len(springs) <= self.spring_index:
|
|
1054
|
+
return {"CANCELLED"}
|
|
1055
|
+
spring = springs[self.spring_index]
|
|
1056
|
+
spring.add_joint()
|
|
1057
|
+
if not self.guess_properties:
|
|
1058
|
+
return {"FINISHED"}
|
|
1059
|
+
|
|
1060
|
+
if len(spring.joints) < 2:
|
|
1061
|
+
return {"FINISHED"}
|
|
1062
|
+
parent_joint, joint = spring.joints[-2:]
|
|
1063
|
+
parent_bone = armature_data.bones.get(parent_joint.node.bone_name)
|
|
1064
|
+
if parent_bone and parent_bone.children:
|
|
1065
|
+
joint.node.bone_name = parent_bone.children[0].name
|
|
1066
|
+
joint.hit_radius = parent_joint.hit_radius
|
|
1067
|
+
joint.stiffness = parent_joint.stiffness
|
|
1068
|
+
joint.gravity_power = parent_joint.gravity_power
|
|
1069
|
+
joint.gravity_dir = list(parent_joint.gravity_dir)
|
|
1070
|
+
joint.drag_force = parent_joint.drag_force
|
|
1071
|
+
return {"FINISHED"}
|
|
1072
|
+
|
|
1073
|
+
if TYPE_CHECKING:
|
|
1074
|
+
# This code is auto generated.
|
|
1075
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
1076
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
1077
|
+
spring_index: int # type: ignore[no-redef]
|
|
1078
|
+
guess_properties: bool # type: ignore[no-redef]
|
|
1079
|
+
|
|
1080
|
+
|
|
1081
|
+
class VRM_OT_remove_spring_bone1_joint(Operator):
|
|
1082
|
+
bl_idname = "vrm.remove_spring_bone1_spring_joint"
|
|
1083
|
+
bl_label = "Remove Joint"
|
|
1084
|
+
bl_description = "Remove VRM 1.0 Spring Bone Spring Joint"
|
|
1085
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
1086
|
+
|
|
1087
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
1088
|
+
options={"HIDDEN"},
|
|
1089
|
+
)
|
|
1090
|
+
|
|
1091
|
+
spring_index: IntProperty( # type: ignore[valid-type]
|
|
1092
|
+
options={"HIDDEN"},
|
|
1093
|
+
min=0,
|
|
1094
|
+
)
|
|
1095
|
+
joint_index: IntProperty( # type: ignore[valid-type]
|
|
1096
|
+
options={"HIDDEN"},
|
|
1097
|
+
min=0,
|
|
1098
|
+
)
|
|
1099
|
+
|
|
1100
|
+
def execute(self, context: Context) -> set[str]:
|
|
1101
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
1102
|
+
if armature is None or armature.type != "ARMATURE":
|
|
1103
|
+
return {"CANCELLED"}
|
|
1104
|
+
armature_data = armature.data
|
|
1105
|
+
if not isinstance(armature_data, Armature):
|
|
1106
|
+
return {"CANCELLED"}
|
|
1107
|
+
springs = get_armature_extension(armature_data).spring_bone1.springs
|
|
1108
|
+
if len(springs) <= self.spring_index:
|
|
1109
|
+
return {"CANCELLED"}
|
|
1110
|
+
spring = springs[self.spring_index]
|
|
1111
|
+
if len(spring.joints) <= self.joint_index:
|
|
1112
|
+
return {"CANCELLED"}
|
|
1113
|
+
spring.joints.remove(self.joint_index)
|
|
1114
|
+
spring.active_joint_index = min(
|
|
1115
|
+
spring.active_joint_index, max(0, len(spring.joints) - 1)
|
|
1116
|
+
)
|
|
1117
|
+
return {"FINISHED"}
|
|
1118
|
+
|
|
1119
|
+
if TYPE_CHECKING:
|
|
1120
|
+
# This code is auto generated.
|
|
1121
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
1122
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
1123
|
+
spring_index: int # type: ignore[no-redef]
|
|
1124
|
+
joint_index: int # type: ignore[no-redef]
|
|
1125
|
+
|
|
1126
|
+
|
|
1127
|
+
class VRM_OT_move_up_spring_bone1_joint(Operator):
|
|
1128
|
+
bl_idname = "vrm.move_up_spring_bone1_joint"
|
|
1129
|
+
bl_label = "Move Up Joint"
|
|
1130
|
+
bl_description = "Move Up VRM 1.0 Joint"
|
|
1131
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
1132
|
+
|
|
1133
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
1134
|
+
options={"HIDDEN"},
|
|
1135
|
+
)
|
|
1136
|
+
|
|
1137
|
+
spring_index: IntProperty( # type: ignore[valid-type]
|
|
1138
|
+
options={"HIDDEN"},
|
|
1139
|
+
min=0,
|
|
1140
|
+
)
|
|
1141
|
+
joint_index: IntProperty( # type: ignore[valid-type]
|
|
1142
|
+
options={"HIDDEN"},
|
|
1143
|
+
min=0,
|
|
1144
|
+
)
|
|
1145
|
+
|
|
1146
|
+
def execute(self, context: Context) -> set[str]:
|
|
1147
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
1148
|
+
if armature is None or armature.type != "ARMATURE":
|
|
1149
|
+
return {"CANCELLED"}
|
|
1150
|
+
armature_data = armature.data
|
|
1151
|
+
if not isinstance(armature_data, Armature):
|
|
1152
|
+
return {"CANCELLED"}
|
|
1153
|
+
spring_bone1 = get_armature_extension(armature_data).spring_bone1
|
|
1154
|
+
springs = spring_bone1.springs
|
|
1155
|
+
if len(springs) <= self.spring_index:
|
|
1156
|
+
return {"CANCELLED"}
|
|
1157
|
+
spring = springs[self.spring_index]
|
|
1158
|
+
if len(spring.joints) <= self.joint_index:
|
|
1159
|
+
return {"CANCELLED"}
|
|
1160
|
+
new_joint_index = (self.joint_index - 1) % len(spring.joints)
|
|
1161
|
+
spring.joints.move(self.joint_index, new_joint_index)
|
|
1162
|
+
spring.active_joint_index = new_joint_index
|
|
1163
|
+
return {"FINISHED"}
|
|
1164
|
+
|
|
1165
|
+
if TYPE_CHECKING:
|
|
1166
|
+
# This code is auto generated.
|
|
1167
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
1168
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
1169
|
+
spring_index: int # type: ignore[no-redef]
|
|
1170
|
+
joint_index: int # type: ignore[no-redef]
|
|
1171
|
+
|
|
1172
|
+
|
|
1173
|
+
class VRM_OT_move_down_spring_bone1_joint(Operator):
|
|
1174
|
+
bl_idname = "vrm.move_down_spring_bone1_joint"
|
|
1175
|
+
bl_label = "Move Down Joint"
|
|
1176
|
+
bl_description = "Move Down VRM 1.0 Joint"
|
|
1177
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
1178
|
+
|
|
1179
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
1180
|
+
options={"HIDDEN"},
|
|
1181
|
+
)
|
|
1182
|
+
|
|
1183
|
+
spring_index: IntProperty( # type: ignore[valid-type]
|
|
1184
|
+
options={"HIDDEN"},
|
|
1185
|
+
min=0,
|
|
1186
|
+
)
|
|
1187
|
+
joint_index: IntProperty( # type: ignore[valid-type]
|
|
1188
|
+
options={"HIDDEN"},
|
|
1189
|
+
min=0,
|
|
1190
|
+
)
|
|
1191
|
+
|
|
1192
|
+
def execute(self, context: Context) -> set[str]:
|
|
1193
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
1194
|
+
if armature is None or armature.type != "ARMATURE":
|
|
1195
|
+
return {"CANCELLED"}
|
|
1196
|
+
armature_data = armature.data
|
|
1197
|
+
if not isinstance(armature_data, Armature):
|
|
1198
|
+
return {"CANCELLED"}
|
|
1199
|
+
spring_bone1 = get_armature_extension(armature_data).spring_bone1
|
|
1200
|
+
springs = spring_bone1.springs
|
|
1201
|
+
if len(springs) <= self.spring_index:
|
|
1202
|
+
return {"CANCELLED"}
|
|
1203
|
+
spring = springs[self.spring_index]
|
|
1204
|
+
if len(spring.joints) <= self.joint_index:
|
|
1205
|
+
return {"CANCELLED"}
|
|
1206
|
+
new_joint_index = (self.joint_index + 1) % len(spring.joints)
|
|
1207
|
+
spring.joints.move(self.joint_index, new_joint_index)
|
|
1208
|
+
spring.active_joint_index = new_joint_index
|
|
1209
|
+
return {"FINISHED"}
|
|
1210
|
+
|
|
1211
|
+
if TYPE_CHECKING:
|
|
1212
|
+
# This code is auto generated.
|
|
1213
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
1214
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
1215
|
+
spring_index: int # type: ignore[no-redef]
|
|
1216
|
+
joint_index: int # type: ignore[no-redef]
|
|
1217
|
+
|
|
1218
|
+
|
|
1219
|
+
class VRM_OT_reset_spring_bone1_animation_state(Operator):
|
|
1220
|
+
bl_idname = "vrm.reset_spring_bone1_animation_state"
|
|
1221
|
+
bl_label = "Reset SpringBone Animation State"
|
|
1222
|
+
bl_description = "Reset SpringBone Animation State"
|
|
1223
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
1224
|
+
|
|
1225
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
1226
|
+
options={"HIDDEN"},
|
|
1227
|
+
)
|
|
1228
|
+
|
|
1229
|
+
def execute(self, context: Context) -> set[str]:
|
|
1230
|
+
armature = context.blend_data.objects.get(self.armature_object_name)
|
|
1231
|
+
if armature is None or armature.type != "ARMATURE":
|
|
1232
|
+
return {"CANCELLED"}
|
|
1233
|
+
armature_data = armature.data
|
|
1234
|
+
if not isinstance(armature_data, Armature):
|
|
1235
|
+
return {"CANCELLED"}
|
|
1236
|
+
for spring in get_armature_extension(armature_data).spring_bone1.springs:
|
|
1237
|
+
for joint in spring.joints:
|
|
1238
|
+
joint.animation_state.initialized_as_tail = False
|
|
1239
|
+
reset_state(context)
|
|
1240
|
+
return {"FINISHED"}
|
|
1241
|
+
|
|
1242
|
+
if TYPE_CHECKING:
|
|
1243
|
+
# This code is auto generated.
|
|
1244
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
1245
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
1246
|
+
|
|
1247
|
+
|
|
1248
|
+
class VRM_OT_update_spring_bone1_animation(Operator):
|
|
1249
|
+
bl_idname = "vrm.update_spring_bone1_animation"
|
|
1250
|
+
bl_label = "Update SpringBone Animation"
|
|
1251
|
+
bl_description = "Update SpringBone Animation"
|
|
1252
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
1253
|
+
|
|
1254
|
+
delta_time: FloatProperty( # type: ignore[valid-type]
|
|
1255
|
+
options={"HIDDEN"},
|
|
1256
|
+
)
|
|
1257
|
+
|
|
1258
|
+
def execute(self, context: Context) -> set[str]:
|
|
1259
|
+
delta_time = self.delta_time
|
|
1260
|
+
if abs(delta_time) < float_info.epsilon:
|
|
1261
|
+
delta_time = context.scene.render.fps_base / float(context.scene.render.fps)
|
|
1262
|
+
update_pose_bone_rotations(context, delta_time)
|
|
1263
|
+
return {"FINISHED"}
|
|
1264
|
+
|
|
1265
|
+
if TYPE_CHECKING:
|
|
1266
|
+
# This code is auto generated.
|
|
1267
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
1268
|
+
delta_time: float # type: ignore[no-redef]
|
|
1269
|
+
|
|
1270
|
+
|
|
1271
|
+
def _assign_spring_bone1_from_vrm0(
|
|
1272
|
+
context: Context,
|
|
1273
|
+
armature_object_name: str,
|
|
1274
|
+
) -> set[str]:
|
|
1275
|
+
armature = context.blend_data.objects.get(armature_object_name)
|
|
1276
|
+
if armature is None or armature.type != "ARMATURE":
|
|
1277
|
+
return {"CANCELLED"}
|
|
1278
|
+
armature_data = armature.data
|
|
1279
|
+
if not isinstance(armature_data, Armature):
|
|
1280
|
+
return {"CANCELLED"}
|
|
1281
|
+
|
|
1282
|
+
ext = get_armature_extension(armature_data)
|
|
1283
|
+
vrm0_secondary_animation = ext.vrm0.secondary_animation
|
|
1284
|
+
spring_bone1 = ext.spring_bone1
|
|
1285
|
+
|
|
1286
|
+
if (
|
|
1287
|
+
not vrm0_secondary_animation.collider_groups
|
|
1288
|
+
and not vrm0_secondary_animation.bone_groups
|
|
1289
|
+
):
|
|
1290
|
+
return {"FINISHED"}
|
|
1291
|
+
|
|
1292
|
+
if spring_bone1.colliders or spring_bone1.springs:
|
|
1293
|
+
return {"FINISHED"}
|
|
1294
|
+
|
|
1295
|
+
vrm0_collider_group_uuid_to_collider_group_uuid: dict[str, str] = {}
|
|
1296
|
+
for vrm0_collider_group in vrm0_secondary_animation.collider_groups:
|
|
1297
|
+
if not vrm0_collider_group.uuid:
|
|
1298
|
+
continue
|
|
1299
|
+
collider_group = spring_bone1.add_collider_group()
|
|
1300
|
+
vrm0_collider_group_uuid_to_collider_group_uuid[vrm0_collider_group.uuid] = (
|
|
1301
|
+
collider_group.uuid
|
|
1302
|
+
)
|
|
1303
|
+
collider_group_name = vrm0_collider_group.node.bone_name
|
|
1304
|
+
if collider_group_name:
|
|
1305
|
+
collider_group_name += "-"
|
|
1306
|
+
collider_group_name += vrm0_collider_group.uuid
|
|
1307
|
+
collider_group.vrm_name = collider_group_name
|
|
1308
|
+
for vrm0_collider in vrm0_collider_group.colliders:
|
|
1309
|
+
vrm0_collider_bpy_object = vrm0_collider.bpy_object
|
|
1310
|
+
if not vrm0_collider_bpy_object:
|
|
1311
|
+
continue
|
|
1312
|
+
|
|
1313
|
+
collider = spring_bone1.add_collider(context, armature)
|
|
1314
|
+
collider.node.bone_name = vrm0_collider_group.node.bone_name
|
|
1315
|
+
collider.shape_type = collider.SHAPE_TYPE_SPHERE.identifier
|
|
1316
|
+
collider_bpy_object = collider.bpy_object
|
|
1317
|
+
if collider_bpy_object:
|
|
1318
|
+
collider_bpy_object.name = vrm0_collider_bpy_object.name + ".1"
|
|
1319
|
+
collider_bpy_object.matrix_world = vrm0_collider_bpy_object.matrix_world
|
|
1320
|
+
vrm0_scale = vrm0_collider_bpy_object.scale
|
|
1321
|
+
vrm0_mean_abs_scale = (
|
|
1322
|
+
abs(vrm0_scale[0]) + abs(vrm0_scale[1]) + abs(vrm0_scale[2])
|
|
1323
|
+
) / 3.0
|
|
1324
|
+
effective_radius = (
|
|
1325
|
+
vrm0_collider_bpy_object.empty_display_size * vrm0_mean_abs_scale
|
|
1326
|
+
)
|
|
1327
|
+
collider.shape.sphere.radius = effective_radius
|
|
1328
|
+
|
|
1329
|
+
collider_group_collider = collider_group.add_collider()
|
|
1330
|
+
collider_group_collider.collider_uuid = collider.uuid
|
|
1331
|
+
|
|
1332
|
+
assigned_bone_names: set[str] = set()
|
|
1333
|
+
for vrm0_bone_group in vrm0_secondary_animation.bone_groups:
|
|
1334
|
+
root_bones: list[Bone] = []
|
|
1335
|
+
for vrm0_bone_group_bone in vrm0_bone_group.bones:
|
|
1336
|
+
bone_name = vrm0_bone_group_bone.bone_name
|
|
1337
|
+
if not bone_name:
|
|
1338
|
+
continue
|
|
1339
|
+
bone = armature_data.bones.get(bone_name)
|
|
1340
|
+
if not bone:
|
|
1341
|
+
continue
|
|
1342
|
+
if bone.name in assigned_bone_names:
|
|
1343
|
+
continue
|
|
1344
|
+
traversing_bone = bone
|
|
1345
|
+
while traversing_bone:
|
|
1346
|
+
if traversing_bone in root_bones:
|
|
1347
|
+
break
|
|
1348
|
+
traversing_bone = traversing_bone.parent
|
|
1349
|
+
if traversing_bone:
|
|
1350
|
+
continue
|
|
1351
|
+
|
|
1352
|
+
children = list(bone.children)
|
|
1353
|
+
while children:
|
|
1354
|
+
child_bone = children.pop()
|
|
1355
|
+
if child_bone in root_bones:
|
|
1356
|
+
root_bones.remove(child_bone)
|
|
1357
|
+
children.extend(child_bone.children)
|
|
1358
|
+
|
|
1359
|
+
root_bones.append(bone)
|
|
1360
|
+
|
|
1361
|
+
bone_chains: list[list[str]] = []
|
|
1362
|
+
|
|
1363
|
+
start_bones = deque[Bone](root_bones)
|
|
1364
|
+
while start_bones:
|
|
1365
|
+
start_bone = start_bones.popleft()
|
|
1366
|
+
bone_chain = [start_bone.name]
|
|
1367
|
+
child_bones = deque[Bone](start_bone.children)
|
|
1368
|
+
while child_bones:
|
|
1369
|
+
first_child_bone = child_bones.popleft()
|
|
1370
|
+
bone_chain.append(first_child_bone.name)
|
|
1371
|
+
start_bones.extend(child_bones)
|
|
1372
|
+
child_bones = deque[Bone](first_child_bone.children)
|
|
1373
|
+
bone_chains.append(bone_chain)
|
|
1374
|
+
|
|
1375
|
+
assigned_bone_names.update(
|
|
1376
|
+
bone_name for bone_chain in bone_chains for bone_name in bone_chain
|
|
1377
|
+
)
|
|
1378
|
+
|
|
1379
|
+
for bone_chain in bone_chains:
|
|
1380
|
+
spring = spring_bone1.add_spring()
|
|
1381
|
+
spring_vrm_name = vrm0_bone_group.comment
|
|
1382
|
+
if not spring_vrm_name:
|
|
1383
|
+
spring_vrm_name = "Spring"
|
|
1384
|
+
spring_vrm_name += "-" + uuid.uuid4().hex
|
|
1385
|
+
spring.vrm_name = spring_vrm_name
|
|
1386
|
+
spring.center.bone_name = vrm0_bone_group.center.bone_name
|
|
1387
|
+
|
|
1388
|
+
for bone_name in bone_chain:
|
|
1389
|
+
joint = spring.add_joint()
|
|
1390
|
+
joint.node.bone_name = bone_name
|
|
1391
|
+
joint.stiffness = vrm0_bone_group.stiffiness
|
|
1392
|
+
joint.gravity_power = vrm0_bone_group.gravity_power
|
|
1393
|
+
joint.gravity_dir = list(vrm0_bone_group.gravity_dir)
|
|
1394
|
+
joint.drag_force = vrm0_bone_group.drag_force
|
|
1395
|
+
joint.hit_radius = vrm0_bone_group.hit_radius
|
|
1396
|
+
|
|
1397
|
+
for vrm0_bone_group_collider_group in vrm0_bone_group.collider_groups:
|
|
1398
|
+
vrm0_collider_group_uuid = (
|
|
1399
|
+
vrm0_bone_group_collider_group.collider_group_uuid
|
|
1400
|
+
)
|
|
1401
|
+
if not vrm0_collider_group_uuid:
|
|
1402
|
+
continue
|
|
1403
|
+
collider_group_uuid = (
|
|
1404
|
+
vrm0_collider_group_uuid_to_collider_group_uuid.get(
|
|
1405
|
+
vrm0_collider_group_uuid
|
|
1406
|
+
)
|
|
1407
|
+
)
|
|
1408
|
+
if not collider_group_uuid:
|
|
1409
|
+
continue
|
|
1410
|
+
spring_collider_group = spring.add_collider_group()
|
|
1411
|
+
spring_collider_group.collider_group_uuid = collider_group_uuid
|
|
1412
|
+
return {"FINISHED"}
|
|
1413
|
+
|
|
1414
|
+
|
|
1415
|
+
class VRM_OT_assign_spring_bone1_from_vrm0(Operator):
|
|
1416
|
+
bl_idname = "vrm.assign_spring_bone1_from_vrm0"
|
|
1417
|
+
bl_label = "Assign VRM 0.0 Spring Bones"
|
|
1418
|
+
bl_description = "Copy VRM 0.0 Spring Bone data to VRM 1.0 Spring Bone"
|
|
1419
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
1420
|
+
|
|
1421
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
1422
|
+
options={"HIDDEN"},
|
|
1423
|
+
)
|
|
1424
|
+
|
|
1425
|
+
def execute(self, context: Context) -> set[str]:
|
|
1426
|
+
return _assign_spring_bone1_from_vrm0(context, self.armature_object_name)
|
|
1427
|
+
|
|
1428
|
+
if TYPE_CHECKING:
|
|
1429
|
+
# This code is auto generated.
|
|
1430
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
1431
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
1432
|
+
|
|
1433
|
+
|
|
1434
|
+
def _assign_spring_bone1_from_mmd(
|
|
1435
|
+
context: Context,
|
|
1436
|
+
armature_object_name: str,
|
|
1437
|
+
) -> set[str]:
|
|
1438
|
+
armature = context.blend_data.objects.get(armature_object_name)
|
|
1439
|
+
if armature is None or armature.type != "ARMATURE":
|
|
1440
|
+
return {"CANCELLED"}
|
|
1441
|
+
|
|
1442
|
+
armature_data = armature.data
|
|
1443
|
+
if not isinstance(armature_data, Armature):
|
|
1444
|
+
return {"CANCELLED"}
|
|
1445
|
+
|
|
1446
|
+
ext = get_armature_extension(armature_data)
|
|
1447
|
+
spring_bone1 = ext.spring_bone1
|
|
1448
|
+
if spring_bone1.colliders or spring_bone1.springs:
|
|
1449
|
+
return {"FINISHED"}
|
|
1450
|
+
|
|
1451
|
+
# Collect MMD rigid bodies associated with this armature.
|
|
1452
|
+
# mmd_rigid.type: '0' = kinematic (collider), '1' or '2' = dynamic (springy bone).
|
|
1453
|
+
# https://github.com/MMD-Blender/blender_mmd_tools/blob/v4.5.9/mmd_tools/core/rigid_body.py
|
|
1454
|
+
# https://github.com/MMD-Blender/blender_mmd_tools/blob/v4.5.9/mmd_tools/properties/rigid_body.py
|
|
1455
|
+
static_rigid_bodies: list[tuple[str, Object]] = []
|
|
1456
|
+
dynamic_rigid_bone_names: list[str] = []
|
|
1457
|
+
|
|
1458
|
+
for obj in context.blend_data.objects:
|
|
1459
|
+
mmd_type: object = getattr(obj, "mmd_type", None)
|
|
1460
|
+
if mmd_type != "RIGID_BODY":
|
|
1461
|
+
continue
|
|
1462
|
+
|
|
1463
|
+
mmd_rigid: object = getattr(obj, "mmd_rigid", None)
|
|
1464
|
+
if mmd_rigid is None:
|
|
1465
|
+
continue
|
|
1466
|
+
|
|
1467
|
+
# The bone linkage is stored in a 'mmd_tools_rigid_parent' CHILD_OF constraint.
|
|
1468
|
+
rigid_parent_constraint = obj.constraints.get("mmd_tools_rigid_parent")
|
|
1469
|
+
if not isinstance(rigid_parent_constraint, ChildOfConstraint):
|
|
1470
|
+
continue
|
|
1471
|
+
|
|
1472
|
+
if rigid_parent_constraint.target != armature:
|
|
1473
|
+
continue
|
|
1474
|
+
|
|
1475
|
+
bone_name = rigid_parent_constraint.subtarget
|
|
1476
|
+
if not bone_name:
|
|
1477
|
+
continue
|
|
1478
|
+
|
|
1479
|
+
if bone_name not in armature_data.bones:
|
|
1480
|
+
continue
|
|
1481
|
+
|
|
1482
|
+
rigid_type: object = getattr(mmd_rigid, "type", None)
|
|
1483
|
+
if rigid_type == "0":
|
|
1484
|
+
# MODE_STATIC
|
|
1485
|
+
static_rigid_bodies.append((bone_name, obj))
|
|
1486
|
+
elif rigid_type in {"1", "2"} and bone_name not in dynamic_rigid_bone_names:
|
|
1487
|
+
# MODE_DYNAMIC, MODE_DYNAMIC_BONE
|
|
1488
|
+
dynamic_rigid_bone_names.append(bone_name)
|
|
1489
|
+
|
|
1490
|
+
if not dynamic_rigid_bone_names:
|
|
1491
|
+
return {"FINISHED"}
|
|
1492
|
+
|
|
1493
|
+
# Preserve every kinematic body, including multiple bodies on one bone.
|
|
1494
|
+
static_rigid_bone_to_collider_group_uuid: dict[str, str] = {}
|
|
1495
|
+
for bone_name, mmd_obj in static_rigid_bodies:
|
|
1496
|
+
collider = spring_bone1.add_collider(context, armature)
|
|
1497
|
+
collider.node.bone_name = bone_name
|
|
1498
|
+
|
|
1499
|
+
mmd_rigid = getattr(mmd_obj, "mmd_rigid", None)
|
|
1500
|
+
shape: object = getattr(mmd_rigid, "shape", None)
|
|
1501
|
+
# MMD capsule geometry is centered on local Z. Read local bounds so
|
|
1502
|
+
# object scale is applied exactly once by the body-to-bone transform.
|
|
1503
|
+
bounds = mmd_obj.bound_box
|
|
1504
|
+
dimensions = Vector(
|
|
1505
|
+
tuple(
|
|
1506
|
+
max(v[i] for v in bounds) - min(v[i] for v in bounds) for i in range(3)
|
|
1507
|
+
)
|
|
1508
|
+
)
|
|
1509
|
+
bone_world = armature.matrix_world @ armature.pose.bones[bone_name].matrix
|
|
1510
|
+
body_to_bone = bone_world.inverted_safe() @ mmd_obj.matrix_world
|
|
1511
|
+
# Approximate nonuniform scale with the largest body-to-bone scale.
|
|
1512
|
+
radius_scale = max(abs(value) for value in body_to_bone.to_scale())
|
|
1513
|
+
|
|
1514
|
+
if shape == "CAPSULE":
|
|
1515
|
+
collider.shape_type = collider.SHAPE_TYPE_CAPSULE.identifier
|
|
1516
|
+
radius = max(dimensions.x, dimensions.y) / 2
|
|
1517
|
+
half_height = max(dimensions.z - radius * 2, 0.0) / 2
|
|
1518
|
+
collider.shape.capsule.offset = body_to_bone @ Vector((0, 0, -half_height))
|
|
1519
|
+
collider.shape.capsule.tail = body_to_bone @ Vector((0, 0, half_height))
|
|
1520
|
+
collider.shape.capsule.radius = max(radius * radius_scale, 0.0001)
|
|
1521
|
+
else:
|
|
1522
|
+
collider.shape_type = collider.SHAPE_TYPE_SPHERE.identifier
|
|
1523
|
+
collider.shape.sphere.offset = body_to_bone.translation
|
|
1524
|
+
collider.shape.sphere.radius = max(
|
|
1525
|
+
max(dimensions) * radius_scale / 2, 0.0001
|
|
1526
|
+
)
|
|
1527
|
+
|
|
1528
|
+
# Do not overwrite matrix_world with the source body's center: the
|
|
1529
|
+
# capsule object is its first endpoint, and its child is the second.
|
|
1530
|
+
group_uuid = static_rigid_bone_to_collider_group_uuid.get(bone_name)
|
|
1531
|
+
collider_group = next(
|
|
1532
|
+
(
|
|
1533
|
+
group
|
|
1534
|
+
for group in spring_bone1.collider_groups
|
|
1535
|
+
if group.uuid == group_uuid
|
|
1536
|
+
),
|
|
1537
|
+
None,
|
|
1538
|
+
)
|
|
1539
|
+
if collider_group is None:
|
|
1540
|
+
collider_group = spring_bone1.add_collider_group()
|
|
1541
|
+
collider_group.vrm_name = bone_name + "-mmd-colliders"
|
|
1542
|
+
static_rigid_bone_to_collider_group_uuid[bone_name] = collider_group.uuid
|
|
1543
|
+
collider_group_collider = collider_group.add_collider()
|
|
1544
|
+
collider_group_collider.collider_uuid = collider.uuid
|
|
1545
|
+
|
|
1546
|
+
# Build bone chains from physics bones.
|
|
1547
|
+
# Root physics bones are those whose direct bone parent is NOT a physics bone.
|
|
1548
|
+
root_physics_bones: list[Bone] = []
|
|
1549
|
+
for bone_name in dynamic_rigid_bone_names:
|
|
1550
|
+
bone = armature_data.bones.get(bone_name)
|
|
1551
|
+
if not bone:
|
|
1552
|
+
continue
|
|
1553
|
+
parent = bone.parent
|
|
1554
|
+
if parent is None or parent.name not in dynamic_rigid_bone_names:
|
|
1555
|
+
root_physics_bones.append(bone)
|
|
1556
|
+
|
|
1557
|
+
assigned_bone_names: set[str] = set()
|
|
1558
|
+
bone_chains: list[list[str]] = []
|
|
1559
|
+
|
|
1560
|
+
start_bones = deque[Bone](root_physics_bones)
|
|
1561
|
+
while start_bones:
|
|
1562
|
+
start_bone = start_bones.popleft()
|
|
1563
|
+
if start_bone.name in assigned_bone_names:
|
|
1564
|
+
continue
|
|
1565
|
+
bone_chain = [start_bone.name]
|
|
1566
|
+
child_bones = deque[Bone](
|
|
1567
|
+
child
|
|
1568
|
+
for child in start_bone.children
|
|
1569
|
+
if child.name in dynamic_rigid_bone_names
|
|
1570
|
+
)
|
|
1571
|
+
while child_bones:
|
|
1572
|
+
first_child_bone = child_bones.popleft()
|
|
1573
|
+
bone_chain.append(first_child_bone.name)
|
|
1574
|
+
start_bones.extend(child_bones)
|
|
1575
|
+
child_bones = deque[Bone](
|
|
1576
|
+
child
|
|
1577
|
+
for child in first_child_bone.children
|
|
1578
|
+
if child.name in dynamic_rigid_bone_names
|
|
1579
|
+
)
|
|
1580
|
+
bone_chains.append(bone_chain)
|
|
1581
|
+
assigned_bone_names.update(bone_chain)
|
|
1582
|
+
|
|
1583
|
+
for bone_chain in bone_chains:
|
|
1584
|
+
if not bone_chain:
|
|
1585
|
+
continue
|
|
1586
|
+
first_bone_name = bone_chain[0]
|
|
1587
|
+
|
|
1588
|
+
spring = spring_bone1.add_spring()
|
|
1589
|
+
|
|
1590
|
+
spring_vrm_name = ""
|
|
1591
|
+
root_pose_bone = armature.pose.bones.get(first_bone_name)
|
|
1592
|
+
if root_pose_bone is not None:
|
|
1593
|
+
mmd_bone: object = getattr(root_pose_bone, "mmd_bone", None)
|
|
1594
|
+
if mmd_bone is not None:
|
|
1595
|
+
name_j = getattr(mmd_bone, "name_j", None)
|
|
1596
|
+
if isinstance(name_j, str) and name_j:
|
|
1597
|
+
spring_vrm_name = name_j
|
|
1598
|
+
if not spring_vrm_name:
|
|
1599
|
+
spring_vrm_name = first_bone_name
|
|
1600
|
+
spring.vrm_name = spring_vrm_name + "-" + uuid.uuid4().hex
|
|
1601
|
+
|
|
1602
|
+
for bone_name in bone_chain:
|
|
1603
|
+
joint = spring.add_joint()
|
|
1604
|
+
joint.node.bone_name = bone_name
|
|
1605
|
+
|
|
1606
|
+
# Associate collider groups whose bone is an ancestor of the root physics bone.
|
|
1607
|
+
root_bone = armature_data.bones.get(first_bone_name)
|
|
1608
|
+
if root_bone:
|
|
1609
|
+
traversing: Optional[Bone] = root_bone.parent
|
|
1610
|
+
while traversing:
|
|
1611
|
+
collider_group_uuid = static_rigid_bone_to_collider_group_uuid.get(
|
|
1612
|
+
traversing.name
|
|
1613
|
+
)
|
|
1614
|
+
if collider_group_uuid:
|
|
1615
|
+
spring_collider_group = spring.add_collider_group()
|
|
1616
|
+
spring_collider_group.collider_group_uuid = collider_group_uuid
|
|
1617
|
+
traversing = traversing.parent
|
|
1618
|
+
|
|
1619
|
+
return {"FINISHED"}
|
|
1620
|
+
|
|
1621
|
+
|
|
1622
|
+
class VRM_OT_assign_spring_bone1_from_mmd(Operator):
|
|
1623
|
+
bl_idname = "vrm.assign_spring_bone1_from_mmd"
|
|
1624
|
+
bl_label = "Assign MMD Spring Bones"
|
|
1625
|
+
bl_description = "Copy MMD spring bone data to VRM 1.0 Spring Bone"
|
|
1626
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
1627
|
+
|
|
1628
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
1629
|
+
options={"HIDDEN"},
|
|
1630
|
+
)
|
|
1631
|
+
|
|
1632
|
+
def execute(self, context: Context) -> set[str]:
|
|
1633
|
+
return _assign_spring_bone1_from_mmd(context, self.armature_object_name)
|
|
1634
|
+
|
|
1635
|
+
if TYPE_CHECKING:
|
|
1636
|
+
# This code is auto generated.
|
|
1637
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
1638
|
+
armature_object_name: str # type: ignore[no-redef]
|
|
1639
|
+
|
|
1640
|
+
|
|
1641
|
+
def assign_spring_bone1_automatically(
|
|
1642
|
+
context: Context, armature_object_name: str
|
|
1643
|
+
) -> set[str]:
|
|
1644
|
+
armature = context.blend_data.objects.get(armature_object_name)
|
|
1645
|
+
if armature is None or armature.type != "ARMATURE":
|
|
1646
|
+
return {"CANCELLED"}
|
|
1647
|
+
armature_data = armature.data
|
|
1648
|
+
if not isinstance(armature_data, Armature):
|
|
1649
|
+
return {"CANCELLED"}
|
|
1650
|
+
|
|
1651
|
+
ext = get_armature_extension(armature_data)
|
|
1652
|
+
spring_bone1 = ext.spring_bone1
|
|
1653
|
+
|
|
1654
|
+
if spring_bone1.colliders or spring_bone1.springs:
|
|
1655
|
+
return {"FINISHED"}
|
|
1656
|
+
|
|
1657
|
+
_assign_spring_bone1_from_vrm0(context, armature_object_name)
|
|
1658
|
+
_assign_spring_bone1_from_mmd(context, armature_object_name)
|
|
1659
|
+
|
|
1660
|
+
return {"FINISHED"}
|
|
1661
|
+
|
|
1662
|
+
|
|
1663
|
+
class VRM_OT_assign_spring_bone1_automatically(Operator):
|
|
1664
|
+
bl_idname = "vrm.assign_spring_bone1_automatically"
|
|
1665
|
+
bl_label = "Assign Auto-Detected Spring Bones"
|
|
1666
|
+
bl_description = "Assign Spring Bones automatically"
|
|
1667
|
+
bl_options: ClassVar = {"REGISTER", "UNDO"}
|
|
1668
|
+
|
|
1669
|
+
armature_object_name: StringProperty( # type: ignore[valid-type]
|
|
1670
|
+
options={"HIDDEN"},
|
|
1671
|
+
)
|
|
1672
|
+
|
|
1673
|
+
def execute(self, context: Context) -> set[str]:
|
|
1674
|
+
return assign_spring_bone1_automatically(context, self.armature_object_name)
|
|
1675
|
+
|
|
1676
|
+
if TYPE_CHECKING:
|
|
1677
|
+
# This code is auto generated.
|
|
1678
|
+
# To regenerate, run the `uv run tools/property_typing.py` command.
|
|
1679
|
+
armature_object_name: str # type: ignore[no-redef]
|