Skip to content

Commit

Permalink
Merge pull request #3 from AIGODLIKE/feat-click-and-drag-event
Browse files Browse the repository at this point in the history
Feat: use ray cast check mouse over model
  • Loading branch information
xmx-emm authored Jun 12, 2024
2 parents 067d1ec + 177a5f1 commit 4a5efe3
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 2 deletions.
9 changes: 7 additions & 2 deletions ops.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from math import degrees, radians

import bpy
from bpy.types import Operator

from .utils.ray_cast import RayCast


def get_node(node_tree=None, match_type=None) -> [bpy.types.Node, ...]:
Expand Down Expand Up @@ -32,7 +33,7 @@ def check_modal_exit(event):
return event.type == "RIGHTMOUSE" and event.value == "RELEASE"


class HdrRotationOperator(Operator):
class HdrRotationOperator(RayCast):
bl_idname = 'hdr.rotation'
bl_label = 'HDR Rotation'
bl_options = {'UNDO'}
Expand Down Expand Up @@ -68,6 +69,9 @@ def invoke(self, context, event):
self.start_x = event.mouse_region_x

if context.area and context.area.type == "VIEW_3D":
if self.get_mouse_location_ray_cast(context, event):
# mouse over model
return {'FINISHED', 'PASS_THROUGH'}
if self.use_scene_world:
if len(self.nodes) == 0:
self.report({'WARNING'}, "World Environment Not Mapping Node,Please add a Mapping node")
Expand All @@ -87,6 +91,7 @@ def invoke(self, context, event):
return {'FINISHED', 'PASS_THROUGH'}

def modal(self, context, event):
# print(event.value, event.type, event.value_prev, event.type_prev)
if check_modal_exit(event):
modal_exit()
return {'FINISHED'}
Expand Down
57 changes: 57 additions & 0 deletions utils/ray_cast.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import bpy
import gpu
import numpy as np
from bpy.types import Operator
from gpu.types import Buffer


class RayCast(Operator):

@staticmethod
def get_gpu_buffer(xy, wh=(1, 1), centered=False) -> Buffer:
""" 用于获取当前视图的GPU BUFFER
:params xy: 获取的左下角坐标,带X 和Y信息
:type xy: list or set
:params wh: 获取的宽度和高度信息
:type wh: list or set
:params centered: 是否按中心获取BUFFER
:type centered: bool
:return bpy.gpu.Buffer: 返回活动的GPU BUFFER
"""

if isinstance(wh, (int, float)):
wh = (wh, wh)
elif len(wh) < 2:
wh = (wh[0], wh[0])

x, y, w, h = int(xy[0]), int(xy[1]), int(wh[0]), int(wh[1])
if centered:
x -= w // 2
y -= h // 2

depth_buffer = gpu.state.active_framebuffer_get().read_depth(x, y, w, h)
return depth_buffer

@classmethod
def gpu_depth_ray_cast(cls, x, y, data) -> None:
size = 10 # ray cast pixels

buffer = cls.get_gpu_buffer([x, y], wh=[size, size], centered=True)
numpy_buffer = np.asarray(buffer, dtype=np.float32).ravel()
min_depth = np.min(numpy_buffer)
data['is_in_model'] = (min_depth != (0 or 1))

def get_mouse_location_ray_cast(self, context, event) -> bool:
x, y = (event.mouse_region_x, event.mouse_region_y)
view3d = context.space_data
show_xray = view3d.shading.show_xray
view3d.shading.show_xray = False
data = {}
sp = bpy.types.SpaceView3D
han = sp.draw_handler_add(self.gpu_depth_ray_cast,
(x, y, data), 'WINDOW',
'POST_PIXEL')
bpy.ops.wm.redraw_timer(type='DRAW', iterations=1)
sp.draw_handler_remove(han, 'WINDOW')
view3d.shading.show_xray = show_xray
return data['is_in_model']

0 comments on commit 4a5efe3

Please sign in to comment.