diff --git a/editor-blender/core/actions/state/load/floor.py b/editor-blender/core/actions/state/load/floor.py index 50aa68bc..9866d6d6 100644 --- a/editor-blender/core/actions/state/load/floor.py +++ b/editor-blender/core/actions/state/load/floor.py @@ -1,21 +1,29 @@ -import bpy from typing import cast +import bpy + from ....config import config from ....utils.convert import rgb_to_float + def setup_floor() -> None: if not bpy.context: return - - data_objects: dict[str, bpy.types.Object] = cast(dict[str, bpy.types.Object], bpy.data.objects) + + data_objects: dict[str, bpy.types.Object] = cast( + dict[str, bpy.types.Object], bpy.data.objects + ) # Create floor stage_scale: float = cast(float, getattr(config, "stage_scale", 1.0)) stage_width: float = cast(float, getattr(config, "stage_width", 1.0)) * stage_scale - stage_length: float = cast(float, getattr(config, "stage_length", 1.0)) * stage_scale + stage_length: float = ( + cast(float, getattr(config, "stage_length", 1.0)) * stage_scale + ) stage_stroke: float = 0.02 - stage_color: tuple[float, float, float, float] = (*rgb_to_float((38, 123, 216)), 1.0) + stage_color: tuple[float, float, float, float] = cast( + tuple[float, float, float, float], (*rgb_to_float((38, 123, 216)), 1.0) + ) edge_locations: list[tuple[float, float, float]] = [ (0, stage_width / 2, 0), @@ -39,11 +47,11 @@ def setup_floor() -> None: edge_obj: bpy.types.Object | None = bpy.context.object if edge_obj is None: return - + edge_obj.name = name edge_obj.location = edge_locations[i] edge_obj.scale = edge_scales[i] - edge_obj.color = stage_color + edge_obj.color = stage_color edge_obj.hide_select = True for obj in cast(list[bpy.types.Object], bpy.context.view_layer.objects.selected): @@ -52,20 +60,20 @@ def setup_floor() -> None: # Floor Material setup material_wooden = bpy.data.materials.new(name="Wooden") material_wooden.use_nodes = True - + node_tree = material_wooden.node_tree if node_tree is None: return material_output = node_tree.nodes.get("Material Output") pri_bsdf = node_tree.nodes.get("Principled BSDF") - + if not material_output or not pri_bsdf: return - + material_output.location = (400, 500) pri_bsdf.location = (100, 500) - + # Create nodes brick_texture = node_tree.nodes.new("ShaderNodeTexBrick") map1 = node_tree.nodes.new("ShaderNodeMapping") @@ -76,7 +84,7 @@ def setup_floor() -> None: coord2 = node_tree.nodes.new("ShaderNodeTexCoord") mix = node_tree.nodes.new("ShaderNodeMixRGB") ramp = node_tree.nodes.new("ShaderNodeValToRGB") - + # Set node locations (For manual adjustment) brick_texture.location = (-600, 300) map1.location = (-800, 300) @@ -87,7 +95,7 @@ def setup_floor() -> None: coord2.location = (-1000, 750) mix.location = (-400, 500) ramp.location = (-200, 500) - + # Connect nodes node_tree.links.new(coord1.outputs[3], map1.inputs[0]) node_tree.links.new(coord2.outputs[3], map2.inputs[0]) @@ -98,45 +106,48 @@ def setup_floor() -> None: node_tree.links.new(mix.outputs[0], ramp.inputs[0]) node_tree.links.new(ramp.outputs[0], pri_bsdf.inputs[0]) node_tree.links.new(bump.outputs[0], pri_bsdf.inputs[5]) - + # Modify node values - brick_texture.inputs[1].default_value = (0.226, 0.226, 0.226, 1) - brick_texture.inputs[2].default_value = (0.413, 0.413, 0.413, 1) - brick_texture.inputs[4].default_value = 7.00 - brick_texture.inputs[5].default_value = 0.005 - brick_texture.inputs[6].default_value = 1.00 - brick_texture.inputs[7].default_value = 0.02 - brick_texture.inputs[8].default_value = 4.00 - brick_texture.inputs[9].default_value = 0.60 - - noise.inputs[2].default_value = 6.00 - noise.inputs[3].default_value = 16.00 - noise.inputs[4].default_value = 0.80 - noise.inputs[8].default_value = 4.00 - - map2.inputs[3].default_value[1] = 10.00 - mix.inputs[0].default_value = 1.00 - mix.blend_type = 'MULTIPLY' - - ramp.color_ramp.elements.new(0.200) - ramp.color_ramp.elements.new(0.500) - ramp.color_ramp.elements[3].position = 0.450 - ramp.color_ramp.elements[2].position = 0.250 - ramp.color_ramp.elements[1].position = 0.100 - ramp.color_ramp.elements[3].color = (1.00, 0.89, 0.81, 1.00) - ramp.color_ramp.elements[2].color = (0.90, 0.65, 0.47, 1.00) - ramp.color_ramp.elements[1].color = (0.42, 0.27, 0.18, 1.00) - - pri_bsdf.inputs[2].default_value = 0.240 - + setattr(brick_texture.inputs[1], "default_value", (0.226, 0.226, 0.226, 1)) + setattr(brick_texture.inputs[2], "default_value", (0.413, 0.413, 0.413, 1)) + setattr(brick_texture.inputs[4], "default_value", 7.00) + setattr(brick_texture.inputs[5], "default_value", 0.005) + setattr(brick_texture.inputs[6], "default_value", 1.00) + setattr(brick_texture.inputs[7], "default_value", 0.02) + setattr(brick_texture.inputs[8], "default_value", 4.00) + setattr(brick_texture.inputs[9], "default_value", 0.60) + + setattr(noise.inputs[2], "default_value", 6.00) + setattr(noise.inputs[3], "default_value", 16.00) + setattr(noise.inputs[4], "default_value", 0.80) + setattr(noise.inputs[8], "default_value", 4.00) + + vec = list(getattr(map2.inputs[3], "default_value")) + vec[1] = 10.00 + setattr(map2.inputs[3], "default_value", vec) + + setattr(mix.inputs[0], "default_value", 1.00) + setattr(mix, "blend_type", "MULTIPLY") + + ramp.color_ramp.elements.new(0.200) # type: ignore + ramp.color_ramp.elements.new(0.500) # type: ignore + setattr(ramp.color_ramp.elements[3], "position", 0.450) # type: ignore + setattr(ramp.color_ramp.elements[2], "position", 0.250) # type: ignore + setattr(ramp.color_ramp.elements[1], "position", 0.100) # type: ignore + setattr(ramp.color_ramp.elements[3], "color", (1.00, 0.89, 0.81, 1.00)) # type: ignore + setattr(ramp.color_ramp.elements[2], "color", (0.90, 0.65, 0.47, 1.00)) # type: ignore + setattr(ramp.color_ramp.elements[1], "color", (0.42, 0.27, 0.18, 1.00)) # type: ignore + + setattr(pri_bsdf.inputs[2], "default_value", 0.240) + flr = "wooden_floor" - + # Remove existing floor if flr in bpy.data.objects: obj = bpy.data.objects.get(flr) if obj: bpy.data.objects.remove(obj, do_unlink=True) - + # Add new floor bpy.ops.mesh.primitive_cube_add(scale=(stage_width / 2, stage_length / 2, 0.01)) obj = bpy.context.object diff --git a/editor-blender/core/actions/state/load/objects.py b/editor-blender/core/actions/state/load/objects.py index a73ad9df..8ccceb13 100644 --- a/editor-blender/core/actions/state/load/objects.py +++ b/editor-blender/core/actions/state/load/objects.py @@ -108,34 +108,33 @@ async def import_model_to_asset( # avoid part name conflict obj.name = f"{model_name}.{obj.name}" - + # Add material to each object material = bpy.data.materials.new(name=f"{obj.name}_Material") material.use_nodes = True # Ensure the object has valid data - if obj.data is not None and hasattr(obj.data, 'materials'): - + if obj.data is not None and hasattr(obj.data, "materials"): # Create new nodes and some setup - bsdf_node = material.node_tree.nodes.new(type='ShaderNodeBsdfPrincipled') - object_node = material.node_tree.nodes.new(type="ShaderNodeObjectInfo") + bsdf_node = material.node_tree.nodes.new(type="ShaderNodeBsdfPrincipled") # type: ignore + object_node = material.node_tree.nodes.new(type="ShaderNodeObjectInfo") # type: ignore - material.node_tree.links.new(object_node.outputs[1], bsdf_node.inputs[0]) - material.node_tree.links.new(object_node.outputs[1], bsdf_node.inputs[26]) - bsdf_node.inputs[27].default_value = 5.0 + material.node_tree.links.new(object_node.outputs[1], bsdf_node.inputs[0]) # type: ignore + material.node_tree.links.new(object_node.outputs[1], bsdf_node.inputs[26]) # type: ignore + setattr(bsdf_node.inputs[27], "default_value", 5.0) # Material Output node if it doesn't exist - material_output_node = material.node_tree.nodes.get("Material Output") + material_output_node = material.node_tree.nodes.get("Material Output") # type: ignore if not material_output_node: - material_output_node = material.node_tree.nodes.new(type='ShaderNodeOutputMaterial') + material_output_node = material.node_tree.nodes.new(type="ShaderNodeOutputMaterial") # type: ignore - material.node_tree.links.new(bsdf_node.outputs[0], material_output_node.inputs['Surface']) + material.node_tree.links.new(bsdf_node.outputs[0], material_output_node.inputs["Surface"]) # type: ignore # Assign material to the object - if obj.data.materials: - obj.data.materials[0] = material + if obj.data.materials: # type: ignore + obj.data.materials[0] = material # type: ignore else: - obj.data.materials.append(material) + obj.data.materials.append(material) # type: ignore # Clean meshes sphere_mesh = find_first_mesh("Sphere") @@ -412,5 +411,3 @@ async def setup_objects(): ] setup_dancer_part_objects_map() - - diff --git a/editor-blender/operators/camera/__init__.py b/editor-blender/operators/camera/__init__.py index fb59c0d8..e92f2215 100644 --- a/editor-blender/operators/camera/__init__.py +++ b/editor-blender/operators/camera/__init__.py @@ -1,95 +1,122 @@ import bpy import mathutils +from ...properties.ui.types import CameraStatusType + + def toggle_camera_view(context): + if not bpy.context: + return scene = context.scene - area = next(area for area in context.screen.areas if area.type == 'VIEW_3D') + area = next(area for area in context.screen.areas if area.type == "VIEW_3D") # Control On/Off based on whether the user is in Camera View - if area.spaces[0].region_3d.view_perspective != 'CAMERA': - area.spaces[0].region_3d.view_perspective = 'CAMERA' + if area.spaces[0].region_3d.view_perspective != "CAMERA": + area.spaces[0].region_3d.view_perspective = "CAMERA" # Ensure 'lightdance_camera' Camera - camera = bpy.data.objects.get('lightdance_camera') + camera = bpy.data.objects.get("lightdance_camera") if not camera: bpy.ops.object.camera_add() camera = bpy.context.object - camera.name = 'lightdance_camera' - + camera.name = "lightdance_camera" # type: ignore + scene.camera = camera # Default location and rotaion. - camera.location = mathutils.Vector((10, 0, 2.7)) - target = mathutils.Vector((0, 0, 1.5)) + if not camera: + return + camera.location = mathutils.Vector((10, 0, 2.7)) + target = mathutils.Vector((0, 0, 1.5)) direction = camera.location - target - camera.rotation_euler = direction.to_track_quat('Z', 'Y').to_euler() + camera.rotation_euler = direction.to_track_quat("Z", "Y").to_euler() # Remember the previous location and rotaion. - scene['pre_camera_location'] = area.spaces[0].region_3d.view_location.copy() - scene['pre_camera_rotation'] = area.spaces[0].region_3d.view_rotation.copy() + scene["pre_camera_location"] = area.spaces[0].region_3d.view_location.copy() + scene["pre_camera_rotation"] = area.spaces[0].region_3d.view_rotation.copy() # Switch rendering modes and set rendering-related settings - bpy.context.space_data.shading.type = 'RENDERED' - bpy.context.space_data.overlay.show_overlays = False - bpy.context.scene.render.engine = 'BLENDER_EEVEE_NEXT' + if not bpy.context: + return + bpy.context.space_data.shading.type = "RENDERED" # type: ignore + bpy.context.space_data.overlay.show_overlays = False # type: ignore + bpy.context.scene.render.engine = "BLENDER_EEVEE_NEXT" bpy.context.scene.eevee.use_raytracing = True - bpy.context.scene.eevee.ray_tracing_options.resolution_scale = '1' + bpy.context.scene.eevee.ray_tracing_options.resolution_scale = "1" bpy.context.scene.eevee.ray_tracing_options.trace_max_roughness = 0.95 - bpy.context.space_data.lock_camera = True + bpy.context.space_data.lock_camera = True # type: ignore else: # Return to the original location/rotation. - if 'pre_camera_location' in scene and 'pre_camera_rotation' in scene: - area.spaces[0].region_3d.view_location = scene['pre_camera_location'] - area.spaces[0].region_3d.view_rotation = scene['pre_camera_rotation'] - - area.spaces[0].region_3d.view_perspective = 'PERSP' - bpy.context.space_data.shading.type = 'SOLID' - bpy.context.space_data.overlay.show_overlays = True + if "pre_camera_location" in scene and "pre_camera_rotation" in scene: + area.spaces[0].region_3d.view_location = scene["pre_camera_location"] + area.spaces[0].region_3d.view_rotation = scene["pre_camera_rotation"] + + area.spaces[0].region_3d.view_perspective = "PERSP" + bpy.context.space_data.shading.type = "SOLID" # type: ignore + bpy.context.space_data.overlay.show_overlays = True # type: ignore + class SetCameraY(bpy.types.Operator): bl_idname = "view3d.set_camera_y" bl_label = "Set Camera Y" - target_y: bpy.props.FloatProperty() + target_y: bpy.props.FloatProperty() # type: ignore def execute(self, context): - scene = context.scene - camera = bpy.data.objects.get('lightdance_camera') - + camera = bpy.data.objects.get("lightdance_camera") + if not bpy.context: + return + ld_camera_status: CameraStatusType = getattr( + bpy.context.window_manager, "ld_ui_camera" + ) + if camera: camera.location.y = self.target_y - scene.camera_y = self.target_y # Update the value on slider - - return {'FINISHED'} + ld_camera_status.camera_y = self.target_y # Update the value on slider + + return {"FINISHED"} + class SetCameraX(bpy.types.Operator): bl_idname = "view3d.set_camera_x" bl_label = "Set Camera X" - target_x: bpy.props.FloatProperty() + target_x: bpy.props.FloatProperty() # type: ignore def execute(self, context): - scene = context.scene - camera = bpy.data.objects.get('lightdance_camera') - + camera = bpy.data.objects.get("lightdance_camera") + if not bpy.context: + return + ld_camera_status: CameraStatusType = getattr( + bpy.context.window_manager, "ld_ui_camera" + ) + if camera: camera.location.x = self.target_x - scene.camera_x = self.target_x # Updtate the value on slider - - return {'FINISHED'} + ld_camera_status.camera_x = self.target_x # Updtate the value on slider + + return {"FINISHED"} + class SetCameraFocal(bpy.types.Operator): bl_idname = "view3d.set_camera_focal" bl_label = "Set Camera Focal Length" - target_focal_length: bpy.props.FloatProperty() + target_focal_length: bpy.props.FloatProperty() # type: ignore def execute(self, context): - scene = context.scene - camera = bpy.data.objects.get('lightdance_camera') - + if not bpy.context: + return + camera = bpy.data.objects.get("lightdance_camera") + + ld_camera_status: CameraStatusType = getattr( + bpy.context.window_manager, "ld_ui_camera" + ) + if camera: - camera.data.lens = self.target_focal_length - scene.camera_focal_length = self.target_focal_length # Update the value on slider - - return {'FINISHED'} + camera.data.lens = self.target_focal_length # type: ignore + ld_camera_status.camera_focal_length = ( + self.target_focal_length + ) # Update the value on slider + + return {"FINISHED"} class ToggleCameraOperator(bpy.types.Operator): @@ -97,11 +124,17 @@ class ToggleCameraOperator(bpy.types.Operator): bl_label = "Toggle Camera View" def execute(self, context): - scene = context.scene - scene["camera_on"] = not scene.get("camera_on", False) + if not bpy.context: + return + ld_camera_status: CameraStatusType = getattr( + bpy.context.window_manager, "ld_ui_camera" + ) + setattr( + ld_camera_status, "camera_on", not getattr(ld_camera_status, "camera_on") + ) toggle_camera_view(context) - return {'FINISHED'} + return {"FINISHED"} class AutoFitFullscreenOperator(bpy.types.Operator): @@ -110,62 +143,18 @@ class AutoFitFullscreenOperator(bpy.types.Operator): def execute(self, context): bpy.ops.view3d.view_center_camera() - return {'FINISHED'} - -def update_camera(self, context): - camera = bpy.data.objects.get('lightdance_camera') - if camera: - # update camera position - camera.location.y = context.scene.camera_y - camera.location.x = max(4.5, min(context.scene.camera_x, 17.5)) - - # adjust z postion according to x - if 4.5 <= camera.location.x <= 5.5: - camera.location.z = 0.3 + (camera.location.x - 4.5) * 1.5 #the first row is relatively low. - else: - camera.location.z = 1.8 + (camera.location.x - 5.5) * 0.2 - - camera.data.lens = context.scene.camera_focal_length - - # Let camera face the center of the stage - target = mathutils.Vector((0, 0, 1.5)) - direction = camera.location - target - camera.rotation_euler = direction.to_track_quat('Z', 'Y').to_euler() - - bpy.context.view_layer.update() - -def update_world_light(self, context): - world = bpy.context.scene.world - if world and world.node_tree: - node = world.node_tree.nodes.get("Background") - if node: - node.inputs[1].default_value = context.scene.world_light_intensity + return {"FINISHED"} def register(): - bpy.types.Scene.camera_on = bpy.props.BoolProperty(default=False) - bpy.types.Scene.camera_y = bpy.props.FloatProperty(name="Camera Y", min=-10, max=10, default=0, update=update_camera) - bpy.types.Scene.camera_x = bpy.props.FloatProperty(name="Camera X", min=4.5, max=17.5, default=4.5, update=update_camera) - bpy.types.Scene.camera_focal_length = bpy.props.FloatProperty(name="Focal Length", min=35, max=80, default=50, update=update_camera) - bpy.types.Scene.world_light_intensity = bpy.props.FloatProperty( - name="World Light", min=0, max=1, default=1, update=update_world_light -) - - bpy.utils.register_class(ToggleCameraOperator) bpy.utils.register_class(SetCameraX) bpy.utils.register_class(SetCameraY) bpy.utils.register_class(SetCameraFocal) bpy.utils.register_class(AutoFitFullscreenOperator) -def unregister(): - del bpy.types.Scene.camera_on - del bpy.types.Scene.camera_x - del bpy.types.Scene.camera_y - del bpy.types.Scene.camera_focal_length - del bpy.types.Scene.world_light_intensity - +def unregister(): bpy.utils.unregister_class(ToggleCameraOperator) bpy.utils.unregister_class(SetCameraX) bpy.utils.unregister_class(SetCameraY) diff --git a/editor-blender/panels/camera/__init__.py b/editor-blender/panels/camera/__init__.py index 51c91170..cad28b07 100644 --- a/editor-blender/panels/camera/__init__.py +++ b/editor-blender/panels/camera/__init__.py @@ -1,48 +1,75 @@ import bpy -from ...core.states import state +from ...properties.ui.types import CameraStatusType + class CameraPanel(bpy.types.Panel): bl_label = "Camera View Panel" - bl_idname = "PT_CameraView" - bl_space_type = 'VIEW_3D' - bl_region_type = 'UI' - bl_category = 'CameraView' + bl_idname = "VIEW_PT_CameraView" + bl_space_type = "VIEW_3D" + bl_region_type = "UI" + bl_category = "CameraView" def draw(self, context): + if not bpy.context: + return layout = self.layout - scene = context.scene + ld_camera_status: CameraStatusType = getattr( + bpy.context.window_manager, "ld_ui_camera" + ) row = layout.row() - row.operator("view3d.toggle_camera_operator", text="Turn On" if not scene.get("camera_on", False) else "Turn Off") + row.operator( + "view3d.toggle_camera_operator", + text="Turn On" + if not getattr(ld_camera_status, "camera_on", False) + else "Turn Off", + ) # Show other buttons/slider when it's on - if scene.get("camera_on", False): + if getattr(ld_camera_status, "camera_on", False): layout.label(text="Adjust Camera Position:") - layout.prop(scene, "camera_y", slider=True) + layout.prop(ld_camera_status, "camera_y", slider=True) + row = layout.row() + + op = row.operator("view3d.set_camera_y", text="Left") + setattr(op, "target_y", -10) + + op = row.operator("view3d.set_camera_y", text="Middle") + setattr(op, "target_y", 0) + + op = row.operator("view3d.set_camera_y", text="Right") + setattr(op, "target_y", 10) + + layout.prop(ld_camera_status, "camera_x", slider=True) + row = layout.row() + + op = row.operator("view3d.set_camera_x", text="Front") + setattr(op, "target_x", 4.5) + + op = row.operator("view3d.set_camera_x", text="Middle") + setattr(op, "target_x", 10) + + op = row.operator("view3d.set_camera_x", text="Back") + setattr(op, "target_x", 17.5) + + layout.prop(ld_camera_status, "camera_focal_length", slider=True) row = layout.row() - row.operator("view3d.set_camera_y", text="Left").target_y = -10 - row.operator("view3d.set_camera_y", text="Middle").target_y = 0 - row.operator("view3d.set_camera_y", text="Right").target_y = 10 - - layout.prop(scene, "camera_x", slider=True) - row = layout.row() - row.operator("view3d.set_camera_x", text="Front").target_x = 4.5 - row.operator("view3d.set_camera_x", text="Middle").target_x = 10 - row.operator("view3d.set_camera_x", text="Back").target_x = 17.5 - - layout.prop(scene, "camera_focal_length", slider=True) - row = layout.row() - row.operator("view3d.set_camera_focal", text="35mm").target_focal_length = 35 - row.operator("view3d.set_camera_focal", text="50mm").target_focal_length = 50 - row.operator("view3d.set_camera_focal", text="80mm").target_focal_length = 80 + + op = row.operator("view3d.set_camera_focal", text="35mm") + setattr(op, "target_focal_length", 35) + + op = row.operator("view3d.set_camera_focal", text="50mm") + setattr(op, "target_focal_length", 50) + + op = row.operator("view3d.set_camera_focal", text="80mm") + setattr(op, "target_focal_length", 80) row = layout.row() row.operator("view3d.auto_fit_fullscreen", text="Auto Fit to Fullscreen") - - layout.prop(scene, "world_light_intensity", slider=True) + layout.prop(ld_camera_status, "world_light_intensity", slider=True) def register(): diff --git a/editor-blender/properties/ui/__init__.py b/editor-blender/properties/ui/__init__.py index 769dfaee..6c4eed69 100644 --- a/editor-blender/properties/ui/__init__.py +++ b/editor-blender/properties/ui/__init__.py @@ -1,4 +1,5 @@ from . import ( + camera, color_palette, command_center, control_editor, @@ -10,6 +11,7 @@ def register(): + camera.register() login.register() pos_editor.register() color_palette.register() @@ -20,6 +22,7 @@ def register(): def unregister(): + camera.unregister() login.unregister() pos_editor.unregister() color_palette.unregister() diff --git a/editor-blender/properties/ui/camera.py b/editor-blender/properties/ui/camera.py new file mode 100644 index 00000000..c199cb06 --- /dev/null +++ b/editor-blender/properties/ui/camera.py @@ -0,0 +1,65 @@ +import bpy +import mathutils + + +def update_camera(self, context): + camera = bpy.data.objects.get("lightdance_camera") + if camera: + # update camera position + camera.location.y = getattr(self, "camera_y") + camera.location.x = max(4.5, min(getattr(self, "camera_x"), 17.5)) + + # adjust z postion according to x + if 4.5 <= camera.location.x <= 5.5: + camera.location.z = ( + 0.3 + (camera.location.x - 4.5) * 1.5 + ) # the first row is relatively low. + else: + camera.location.z = 1.8 + (camera.location.x - 5.5) * 0.2 + + camera.data.lens = getattr(self, "camera_focal_length") # type: ignore + + # Let camera face the center of the stage + target = mathutils.Vector((0, 0, 1.5)) + direction = camera.location - target + camera.rotation_euler = direction.to_track_quat("Z", "Y").to_euler() + if not bpy.context: + return + bpy.context.view_layer.update() + + +def update_world_light(self, context): + if not bpy.context: + return + world = bpy.context.scene.world + if world and world.node_tree: + node = world.node_tree.nodes.get("Background") + if node: + setattr( + node.inputs[1], "default_value", getattr(self, "world_light_intensity") + ) + + +class CameraStatus(bpy.types.PropertyGroup): + edit_index: bpy.props.IntProperty() # type: ignore + camera_on: bpy.props.BoolProperty(default=False) # type: ignore + camera_y: bpy.props.FloatProperty(name="Camera Y", min=-10, max=10, default=0, update=update_camera) # type: ignore + camera_x: bpy.props.FloatProperty(name="Camera X", min=4.5, max=17.5, default=4.5, update=update_camera) # type: ignore + camera_focal_length: bpy.props.FloatProperty(name="Focal Length", min=35, max=80, default=50, update=update_camera) # type: ignore + world_light_intensity: bpy.props.FloatProperty( # type: ignore + name="World Light", min=0, max=1, default=1, update=update_world_light + ) # type: ignore + + +def register(): + bpy.utils.register_class(CameraStatus) + setattr( + bpy.types.WindowManager, + "ld_ui_camera", + bpy.props.PointerProperty(type=CameraStatus), + ) + + +def unregister(): + bpy.utils.unregister_class(CameraStatus) + delattr(bpy.types.WindowManager, "ld_ui_camera") diff --git a/editor-blender/properties/ui/types.py b/editor-blender/properties/ui/types.py index 0b61b1f7..332d3a2e 100644 --- a/editor-blender/properties/ui/types.py +++ b/editor-blender/properties/ui/types.py @@ -78,3 +78,11 @@ class TimeShiftStatusType: start: int end: int displacement: int + + +class CameraStatusType: + camera_on: bool + camera_y: float + camera_x: float + camera_focal_length: float + world_light_intensity: float