feat: Add VRM Blender addon with complete import/export functionality
- Add core VRM addon infrastructure with manifest and registration - Add common utilities module with file system, logging, and conversion helpers - Add human bone mapper with support for multiple rigging standards (Mixamo, MMD, Unreal, Rigify, etc.) - Add VRM 0.x and 1.x format support with property groups and handlers - Add editor UI panels for VRM metadata, spring bones, and MToon materials - Add exporter with glTF2 extension support for VRM format serialization - Add importer with scene reconstruction and armature generation - Add MToon shader support with auto-setup and material migration - Add spring bone physics simulation with constraint handling - Add node constraint editor for advanced rigging control - Add comprehensive validation and error handling with user dialogs - Add scene watcher for real-time property synchronization - Add workspace management and preference system - Include Python cache files and Blender manifest configuration - This is the initial commit establishing the complete VRM addon ecosystem for Blender
This commit is contained in:
93
editor/vrm1/scene_watcher.py
Normal file
93
editor/vrm1/scene_watcher.py
Normal file
@@ -0,0 +1,93 @@
|
||||
# SPDX-License-Identifier: MIT OR GPL-3.0-or-later
|
||||
from dataclasses import dataclass
|
||||
|
||||
from bpy.types import Armature, Context
|
||||
from mathutils import Vector
|
||||
|
||||
from ...common import ops
|
||||
from ...common.logger import get_logger
|
||||
from ...common.scene_watcher import RunState, SceneWatcher
|
||||
from ..extension import get_armature_extension
|
||||
from .property_group import Vrm1LookAtPropertyGroup
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
@dataclass
|
||||
class LookAtPreviewUpdater(SceneWatcher):
|
||||
armature_index: int = 0
|
||||
|
||||
def reset_run_progress(self) -> None:
|
||||
self.armature_index = 0
|
||||
|
||||
def run(self, context: Context) -> RunState:
|
||||
"""Detect updates to the target object of Look At and update the state."""
|
||||
blend_data = context.blend_data
|
||||
|
||||
if not blend_data.armatures:
|
||||
return RunState.FINISH
|
||||
|
||||
count = 20
|
||||
|
||||
armatures_len = len(blend_data.armatures)
|
||||
if self.armature_index >= armatures_len:
|
||||
self.armature_index = 0
|
||||
|
||||
start_armature_index = self.armature_index
|
||||
end_armature_index = min(self.armature_index + count, armatures_len)
|
||||
changed = False
|
||||
for armature in blend_data.armatures[start_armature_index:end_armature_index]:
|
||||
ext = get_armature_extension(armature)
|
||||
if not ext.is_vrm1():
|
||||
continue
|
||||
look_at = ext.vrm1.look_at
|
||||
if not look_at.enable_preview:
|
||||
continue
|
||||
preview_target_bpy_object = look_at.preview_target_bpy_object
|
||||
if not preview_target_bpy_object:
|
||||
continue
|
||||
if (
|
||||
Vector(look_at.previous_preview_target_bpy_object_location)
|
||||
- preview_target_bpy_object.location
|
||||
).length_squared > 0:
|
||||
changed = True
|
||||
break
|
||||
|
||||
if changed:
|
||||
Vrm1LookAtPropertyGroup.update_all_previews(context)
|
||||
return RunState.FINISH
|
||||
|
||||
self.armature_index += count
|
||||
|
||||
if end_armature_index < armatures_len:
|
||||
return RunState.PREEMPT
|
||||
|
||||
return RunState.FINISH
|
||||
|
||||
def create_fast_path_performance_test_objects(self, context: Context) -> None:
|
||||
blend_data = context.blend_data
|
||||
|
||||
for i in range(300):
|
||||
if i % 3 != 0:
|
||||
mesh = blend_data.meshes.new(f"Mesh#{i}")
|
||||
obj = blend_data.objects.new(f"Object#{i}", mesh)
|
||||
context.scene.collection.objects.link(obj)
|
||||
continue
|
||||
|
||||
ops.icyp.make_basic_armature()
|
||||
active_object = context.active_object
|
||||
if not active_object:
|
||||
message = f"Not an armature: {active_object}"
|
||||
raise ValueError(message)
|
||||
armature = active_object.data
|
||||
if not isinstance(armature, Armature):
|
||||
raise TypeError
|
||||
|
||||
ext = get_armature_extension(armature)
|
||||
ext.spec_version = ext.SPEC_VERSION_VRM1
|
||||
look_at = ext.vrm1.look_at
|
||||
look_at.type = ext.vrm1.look_at.TYPE_BONE.identifier
|
||||
look_at.preview_target_bpy_object = blend_data.objects[
|
||||
i * 5 % len(blend_data.objects)
|
||||
]
|
||||
ext.vrm1.look_at.enable_preview = True
|
||||
Reference in New Issue
Block a user