feat: draw users

This commit is contained in:
Swann Martinez 2019-08-14 14:25:20 +02:00
parent 26fde5da43
commit d15c099d05
No known key found for this signature in database
GPG Key ID: 414CCAFD8DA720E1
7 changed files with 96 additions and 91 deletions

View File

@ -2,10 +2,13 @@ import bpy
import mathutils import mathutils
from .. import utils from .. import utils
from ..presence import User from .. import presence
from ..libs.replication.data import ReplicatedDatablock from ..libs.replication.data import ReplicatedDatablock
from ..libs.replication.constants import UP
from ..libs.debug import draw_point from ..libs.debug import draw_point
class BlUser(ReplicatedDatablock): class BlUser(ReplicatedDatablock):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__( *args, **kwargs) super().__init__( *args, **kwargs)
@ -15,13 +18,26 @@ class BlUser(ReplicatedDatablock):
if self.buffer: if self.buffer:
self.load(self.buffer, self.pointer) self.load(self.buffer, self.pointer)
def construct(self, name): def construct(self, name):
return User() return presence.User()
def load(self, data, target): def load(self, data, target):
target.name = data['name'] target.name = data['name']
target.location = data['location'] target.location = data['location']
utils.dump_anything.load(target, data) utils.dump_anything.load(target, data)
def apply(self):
if self.pointer is None:
self.pointer = self.construct(self.buffer)
if self.pointer:
self.load(data=self.buffer, target=self.pointer)
self.state = UP
#TODO: refactor in order to redraw in cleaner ways
if presence.renderer:
presence.renderer.draw_client_camera(self.buffer['name'], self.buffer['location'],self.buffer['color'])
def dump(self,pointer=None): def dump(self,pointer=None):
data = utils.dump_anything.dump(pointer) data = utils.dump_anything.dump(pointer)
data['location'] = pointer.location data['location'] = pointer.location
@ -32,11 +48,10 @@ class BlUser(ReplicatedDatablock):
def diff(self): def diff(self):
for i,coord in enumerate(self.pointer.location): for i,coord in enumerate(self.pointer.location):
if coord != self.buffer['location'][i]: if coord != self.buffer['location'][i]:
print("user location update")
return True return True
return False return False
bl_id = "users" bl_id = "users"
bl_class = User bl_class = presence.User
bl_rep_class = BlUser bl_rep_class = BlUser

View File

@ -1,7 +1,7 @@
import bpy import bpy
from .libs.replication.constants import * from .libs.replication.constants import *
from .libs import debug from .libs import debug
from . import operators from . import operators, utils
from .bl_types.bl_user import BlUser from .bl_types.bl_user import BlUser
class Delayable(): class Delayable():
@ -87,14 +87,43 @@ class ClientUpdate(Draw):
if client: if client:
client.pointer.update_location() client.pointer.update_location()
class DrawClients(Draw): class DrawClients(Draw):
def __init__(self):
super().__init__()
self._camera_lines = []
def execute(self): def execute(self):
if operators.client: if operators.client:
users = operators.client.list(filter=BlUser) users = operators.client.list(filter=BlUser)
try:
[debug.draw_point(location=operators.client.get(u).buffer['location']) for u in users if operators.client.get(u)] self.clear_camera()
except:
pass
for u in users:
cli = operators.client.get(u)
if cli:
loc = cli.buffer['location']
self.draw_camera(loc)
def clear_camera(self):
for line in self._camera_lines:
line.clear()
self._camera_lines.clear()
def draw_camera(self, loc):
self._camera_lines.append(debug.draw_line(a=loc[0],b=loc[2]))
self._camera_lines.append(debug.draw_line(a=loc[1],b=loc[2]))
self._camera_lines.append(debug.draw_line(a=loc[3],b=loc[1]))
self._camera_lines.append(debug.draw_line(a=loc[3],b=loc[0]))
self._camera_lines.append(debug.draw_line(a=loc[0],b=loc[6]))
self._camera_lines.append(debug.draw_line(a=loc[1],b=loc[6]))
self._camera_lines.append(debug.draw_line(a=loc[2],b=loc[6]))
self._camera_lines.append(debug.draw_line(a=loc[3],b=loc[6]))
self._camera_lines.append(debug.draw_line(a=loc[4],b=loc[5]))

View File

@ -30,7 +30,7 @@ class Drawable():
:type duration: float :type duration: float
""" """
def __init__(self, coords=DEFAULT_COORDS, indices=DEFAULT_INDICES, location=(0.0, 0.0, 0.0), mode='POINTS', color=(1, 0, 0, 1), duration=1): def __init__(self, coords=DEFAULT_COORDS, indices=DEFAULT_INDICES, location=(0.0, 0.0, 0.0), mode='POINTS', color=(1, 0, 0, 1), duration=0):
self._duration = duration self._duration = duration
self._color = color self._color = color
self._coord = [tuple(numpy.add(c,location)) for c in coords] self._coord = [tuple(numpy.add(c,location)) for c in coords]
@ -42,8 +42,9 @@ class Drawable():
self._handler = bpy.types.SpaceView3D.draw_handler_add( self._handler = bpy.types.SpaceView3D.draw_handler_add(
self.draw, (), 'WINDOW', 'POST_VIEW') self.draw, (), 'WINDOW', 'POST_VIEW')
# Bind the callback # Bind the callback
self._timer = bpy.app.timers.register( if duration:
self.clear, first_interval=duration) self._timer = bpy.app.timers.register(
self.clear, first_interval=duration)
def draw(self): def draw(self):
self.shader.bind() self.shader.bind()

View File

@ -23,8 +23,7 @@ logger = logging.getLogger(__name__)
client = None client = None
delayables = [] delayables = []
context = None ui_context = None
def add_datablock(datablock): def add_datablock(datablock):
global client global client
@ -96,7 +95,7 @@ class SessionStartOperator(bpy.types.Operator):
if _type.bl_id == 'users':#For testing if _type.bl_id == 'users':#For testing
bpy_factory.register_type(_type.bl_class, _type.bl_rep_class, timer=0.1,automatic=True) bpy_factory.register_type(_type.bl_class, _type.bl_rep_class, timer=0.1,automatic=True)
# delayables.append(delayable.ApplyTimer(timout=0.16,target_type=_type.bl_rep_class)) delayables.append(delayable.ApplyTimer(timout=0.1,target_type=_type.bl_rep_class))
else: else:
bpy_factory.register_type(_type.bl_class, _type.bl_rep_class) bpy_factory.register_type(_type.bl_class, _type.bl_rep_class)
@ -120,19 +119,21 @@ class SessionStartOperator(bpy.types.Operator):
usr = presence.User( usr = presence.User(
username=settings.username, username=settings.username,
color=list(settings.client_color), color=(settings.client_color.r,
settings.client_color.g,
settings.client_color.b,
1),
) )
settings.user_uuid = client.add(usr) settings.user_uuid = client.add(usr)
delayables.append(delayable.DrawClients()) # delayables.append(delayable.DrawClients())
delayables.append(delayable.ClientUpdate(client_uuid=settings.user_uuid)) delayables.append(delayable.ClientUpdate(client_uuid=settings.user_uuid))
# Push all added values # Push all added values
client.push() client.push()
# Launch drawing module # Launch drawing module
# if settings.enable_presence: if settings.enable_presence:
# presence.renderer.run() presence.renderer.run()
for d in delayables: for d in delayables:
d.register() d.register()
@ -159,11 +160,7 @@ class SessionStopOperator(bpy.types.Operator):
for d in delayables: for d in delayables:
d.unregister() d.unregister()
presence.renderer.stop()
# del client_instance
# unregister_ticks()
# presence.renderer.stop()
return {"FINISHED"} return {"FINISHED"}

View File

@ -3,6 +3,7 @@ import bgl
import blf import blf
import gpu import gpu
import mathutils import mathutils
import copy
import math import math
@ -50,7 +51,7 @@ def get_target_far(region, rv3d, coord, distance):
return [target.x, target.y, target.z] return [target.x, target.y, target.z]
def get_client_view_rect(): def get_client_cam_points():
area, region, rv3d = view3d_find() area, region, rv3d = view3d_find()
v1 = [0, 0, 0] v1 = [0, 0, 0]
@ -70,12 +71,10 @@ def get_client_view_rect():
v4 = get_target(region, rv3d, (width, 0)) v4 = get_target(region, rv3d, (width, 0))
v5 = get_target(region, rv3d, (width/2, height/2)) v5 = get_target(region, rv3d, (width/2, height/2))
v6 = get_target_far(region, rv3d, (width/2, height/2), 10) v6 = list(rv3d.view_location)
v7 = get_target_far(region, rv3d, (width/2, height/2), -.8)
coords = v5 coords = [v1,v2,v3,v4,v5,v6,v7]
indices = (
(1, 3), (2, 1), (3, 0), (2, 0)
)
return coords return coords
@ -91,16 +90,16 @@ class User():
def __init__(self, username=None, color=(0,0,0,1)): def __init__(self, username=None, color=(0,0,0,1)):
self.name = username self.name = username
self.color = color self.color = color
self.location = [0,0,0] self.location = [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]]
self.active_object = "" self.active_object = ""
def update_location(self): def update_location(self):
current_coords = get_client_view_rect() current_coords = get_client_cam_points()
area, region, rv3d = view3d_find() area, region, rv3d = view3d_find()
current_coords = construct_camera(area)[0] current_coords = get_client_cam_points()
if current_coords: if current_coords:
self.location = current_coords self.location = list(current_coords)
@ -208,32 +207,31 @@ class DrawFactory(object):
else: else:
pass pass
def draw_client(self, client): def draw_client_camera(self,client_uuid, client_location, client_color):
if client: if client_location:
name = client['id']
local_username = bpy.context.window_manager.session.username local_username = bpy.context.window_manager.session.username
if name != local_username: try:
try: indices = (
indices = ( (1, 3), (2, 1), (3, 0), (2, 0),(4,5),(1, 6), (2, 6), (3, 6), (0, 6)
(1, 3), (2, 1), (3, 0), (2, 0),(4, 5) )
)
shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
position = client['location'] position = [tuple(coord) for coord in client_location]
color = client['color'] color = client_color
batch = batch_for_shader(
shader, 'LINES', {"pos": position}, indices=indices)
self.d3d_items[name] = (shader, batch, color) batch = batch_for_shader(
self.d2d_items[name] = (position[1], name, color) shader, 'LINES', {"pos": position}, indices=indices)
except Exception as e: self.d3d_items[client_uuid] = (shader, batch, color)
print("Draw client exception {}".format(e)) self.d2d_items[client_uuid] = (position[1], client_uuid, color)
except Exception as e:
print("Draw client exception {}".format(e))
def draw3d_callback(self): def draw3d_callback(self):
bgl.glLineWidth(2) bgl.glLineWidth(1.5)
try: try:
for shader, batch, color in self.d3d_items.values(): for shader, batch, color in self.d3d_items.values():
shader.bind() shader.bind()
@ -249,44 +247,13 @@ class DrawFactory(object):
if coords: if coords:
blf.position(0, coords[0], coords[1]+10, 0) blf.position(0, coords[0], coords[1]+10, 0)
blf.size(0, 10, 72) blf.size(0, 16, 72)
blf.color(0, color[0], color[1], color[2], color[3]) blf.color(0, color[0], color[1], color[2], color[3])
blf.draw(0, font) blf.draw(0, font)
except Exception as e: except Exception as e:
print("2D EXCEPTION") print("2D EXCEPTION")
def construct_camera(area):
"""
Construct the camera frustum as a box
"""
r3dv = area.spaces[0]
box = [[0, 0, 0] for i in range(8)]
aspx = area.width
aspy = area.height
ratiox = min(aspx / aspy, 1.0)
ratioy = min(aspy / aspx, 1.0)
angleofview = 2.0 * \
math.atan(36 / (2.0 * r3dv.lens))
oppositeclipsta = math.tan(angleofview / 2.0) * r3dv.clip_start
oppositeclipend = math.tan(angleofview / 2.0) * r3dv.clip_end
box[2][0] = box[1][0] = -oppositeclipsta * ratiox
box[0][0] = box[3][0] = -oppositeclipend * ratiox
box[5][0] = box[6][0] = +oppositeclipsta * ratiox
box[4][0] = box[7][0] = +oppositeclipend * ratiox
box[1][1] = box[5][1] = -oppositeclipsta * ratioy
box[0][1] = box[4][1] = -oppositeclipend * ratioy
box[2][1] = box[6][1] = +oppositeclipsta * ratioy
box[3][1] = box[7][1] = +oppositeclipend * ratioy
box[0][2] = box[3][2] = box[4][2] = box[7][2] = -r3dv.clip_end
box[1][2] = box[2][2] = box[5][2] = box[6][2] = -r3dv.clip_start
return [r3dv.view_matrix @ mathutils.Vector(i) for i in box]
def register(): def register():
global renderer global renderer
renderer = DrawFactory() renderer = DrawFactory()

2
ui.py
View File

@ -178,7 +178,7 @@ class SESSION_PT_user(bpy.types.Panel):
detail_item_row.label( detail_item_row.label(
text="{} {}".format(username, info)) text="{} {}".format(username, info))
detail_item_row.label(text=str(pointer))
if not is_local_user: if not is_local_user:
detail_item_row.operator( detail_item_row.operator(
"session.snapview", text="", icon='VIEW_CAMERA').target_client = key "session.snapview", text="", icon='VIEW_CAMERA').target_client = key

View File

@ -25,10 +25,6 @@ def random_string_digits(stringLength=6):
lettersAndDigits = string.ascii_letters + string.digits lettersAndDigits = string.ascii_letters + string.digits
return ''.join(random.choice(lettersAndDigits) for i in range(stringLength)) return ''.join(random.choice(lettersAndDigits) for i in range(stringLength))
def refresh_window():
bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
def clean_scene(): def clean_scene():
for datablock in BPY_TYPES: for datablock in BPY_TYPES:
datablock_ref = getattr(bpy.data, BPY_TYPES[datablock]) datablock_ref = getattr(bpy.data, BPY_TYPES[datablock])