示例#1
0
def boxline(object_id, axis, direction, delim, suffix, start, end, line_width,
            move, color, parent):
    line_width = line_width / SCL_CLICK
    end = Position(x=(end.x - start.x) / SCL_CLICK,
                   y=(end.y - start.y) / SCL_CLICK,
                   z=(end.z - start.z) / SCL_CLICK)
    if start.y == end.y and start.z == end.z:
        scale = Scale(x=abs(start.x - end.x), y=line_width, z=line_width)
    elif start.x == end.x and start.z == end.z:
        scale = Scale(x=line_width, y=abs(start.y - end.y), z=line_width)
    elif start.x == end.x and start.y == end.y:
        scale = Scale(x=line_width, y=line_width, z=abs(start.z - end.z))
    name = f"{object_id}{delim}{axis}{direction}_{suffix}"
    position = Position(statistics.median([start.x, end.x]),
                        statistics.median([start.y, end.y]),
                        statistics.median([start.z, end.z]))
    if name not in CONTROLS[object_id]:
        CONTROLS[object_id][name] = Box(
            object_id=name,
            # TODO: restore ttl=arblib.TTL_TEMP,
            parent=parent,
            scale=scale,
            position=position,
            material=Material(color=color,
                              transparent=True,
                              opacity=0.4,
                              shader="flat"),
        )
        scene.add_object(CONTROLS[object_id][name])
    elif move:
        scene.update_object(CONTROLS[object_id][name],
                            position=position,
                            scale=scale)
示例#2
0
def init_origin(scene: Scene):
    """Origin object, construction cone, so user knows ARB is running."""
    # TODO: migrate to shared-scene setting
    size = [0.2, 0.4, 0.2]
    scene.add_object(Cone(  # 370mm x 370mm # 750mm
        object_id="arb-origin",
        material=Material(
            color=Color(255, 114, 33),
            transparent=True,
            opacity=0.5,
            shader="flat"),
        position=Position(0, size[1] / 2, 0),
        scale=Scale(size[0] / 2, size[1], size[2] / 2)))
    scene.add_object(Cone(
        object_id="arb-origin-hole",
        **{"material-extras": {"transparentOccluder": True}},
        position=Position(0, size[1] - (size[1] / 2 / 15), 0),
        scale=Scale(size[0] / 15, size[1] / 10, size[2] / 15)))
    scene.add_object(Box(
        object_id="arb-origin-base",
        material=Material(
            color=Color(0, 0, 0),
            transparent=True,
            opacity=0.5,
            shader="flat"),
        position=Position(0, size[1] / 20, 0),
        scale=Scale(size[0], size[1] / 10, size[2])))
示例#3
0
def dir_clickers(object_id, axis, direction, delim, position, color, cones,
                 callback, move, parent):
    position = Position(x=position.x / SCL_CLICK,
                        y=position.y / SCL_CLICK,
                        z=position.z / SCL_CLICK)
    loc = Position(x=position.x / SCL_CLICK,
                   y=position.y / SCL_CLICK,
                   z=position.z / SCL_CLICK)
    npos = 0.1 / SCL_CLICK
    if direction == "p":
        npos = -0.1 / SCL_CLICK
    if axis == "x":
        loc = Position(x=position.x + npos, y=position.y, z=position.z)
    elif axis == "y":
        loc = Position(x=position.x, y=position.y + npos, z=position.z)
    elif axis == "z":
        loc = Position(x=position.x, y=position.y, z=position.z + npos)
    name_pos = f"{object_id}{delim}{axis}p_{direction}"
    name_neg = f"{object_id}{delim}{axis}n_{direction}"
    if name_pos not in CONTROLS[object_id]:
        CONTROLS[object_id][name_pos] = Cone(  # click object positive
            object_id=name_pos,
            clickable=True,
            position=position,
            rotation=cones[axis + direction][0],
            scale=Scale(0.05 / SCL_CLICK, 0.09 / SCL_CLICK, 0.05 / SCL_CLICK),
            material=Material(color=color,
                              transparent=True,
                              opacity=arblib.OPC_CLINE),
            # TODO: restore ttl=arblib.TTL_TEMP,
            parent=parent,
            evt_handler=callback)
        scene.add_object(CONTROLS[object_id][name_pos])
    elif move:
        scene.update_object(CONTROLS[object_id][name_pos], position=position)
    if name_neg not in CONTROLS[object_id]:
        CONTROLS[object_id][name_neg] = Cone(  # click object negative
            object_id=name_neg,
            clickable=True,
            position=loc,
            rotation=cones[axis + direction][1],
            scale=Scale(0.05 / SCL_CLICK, 0.09 / SCL_CLICK, 0.05 / SCL_CLICK),
            material=Material(color=color,
                              transparent=True,
                              opacity=arblib.OPC_CLINE),
            # TODO: restore ttl=arblib.TTL_TEMP,
            parent=parent,
            evt_handler=callback)
        scene.add_object(CONTROLS[object_id][name_neg])
    elif move:
        scene.update_object(CONTROLS[object_id][name_neg], position=loc)
示例#4
0
    def update(self, data):
        self.src_width = data["image"]["width"]
        self.src_height = data["image"]["height"]

        # update rotation
        new_quat = data["pose"]["quaternions"]
        new_euler = Rotation(*new_quat).euler
        filtered_euler = self.rot_filter.add(
            (new_euler.x, new_euler.y, new_euler.z))  # filter
        filtered_euler[0] *= -1.2  # flip direction and scale up a bit
        filtered_euler[0] += 5  # rotate up a bit
        filtered_euler[1] *= 0.7  # scale down
        # head faces backward at first, rotate head 180 to correct
        filtered_euler[1] += 180
        self.rot = Rotation(*filtered_euler)

        # update translation
        new_trans = data["pose"]["translation"]
        new_trans[0] = 0.0
        new_trans[1] = -0.07
        new_trans[2] = -0.045
        self.trans = self.trans_filter.add(new_trans)  # filter
        self.trans = Position(*new_trans)

        self.bbox = np.array(data["bbox"]).reshape((2, -1))

        new_lmks = np.array(data["landmarks"])  # [x1, y1, x2, y2...]
        self.lmks_raw = self.lmks_filter.add(new_lmks)  # filter
        self.landmarks = self.lmks_raw.reshape((-1, 2))  # [[x1,y1],[x2,y2]...]
        self.center = np.mean(self.landmarks,
                              axis=0)  # "center of mass" of face
        self.landmarks = self.normalize_to_COM(self.landmarks, self.center)
示例#5
0
def do_scale_select(camname, objid, scale=None):
    color = arblib.CLR_SCALE
    delim = f"_{Mode.SCALE.value}_"
    callback = scaleline_callback
    obj = scene.get_persisted_obj(objid)
    position = Position()
    if "position" in obj.data:
        position = obj.data.position
    if not scale:
        scale = Scale()
        if "scale" in obj.data:
            scale = obj.data.scale
    xl, yl, zl = get_clicklines_len(obj)
    # scale entire object + or - on all axis
    root = make_clickroot(objid, position, delim, move=True)
    make_clickline("x",
                   xl,
                   objid,
                   position,
                   delim,
                   color,
                   callback,
                   move=True,
                   parent=root)
    # TODO: restore make_followspot(objid, position, delim, color)
    sca = Scale(round(scale.x, 3), round(scale.y, 3), round(scale.z, 3))
    USERS[camname].set_textright(
        f"{USERS[camname].target_style} s({sca.x},{sca.y},{sca.z})")
示例#6
0
 def set_clipboard(self,
                   callback=None,
                   object_type=None,
                   scale=Scale(0.05, 0.05, 0.05),
                   position=Position(0, 0, -CLIP_RADIUS/SCL_HUD),
                   color=Color(255, 255, 255),
                   url=None):
     if object_type:
         self.clipboard = Object(  # show item to be created
             object_id=f"{self.camname}_clipboard",
             object_type=object_type,
             position=position,
             parent=self.hud.object_id,
             scale=Scale(scale.x/SCL_HUD, scale.y/SCL_HUD, scale.z/SCL_HUD),
             material=Material(color=color, transparent=True, opacity=0.4),
             url=url,
             clickable=True,
             evt_handler=callback)
         self.scene.add_object(self.clipboard)
     self.cliptarget = Circle(  # add helper target object to find true origin
         object_id=f"{self.camname}_cliptarget",
         position=position,
         parent=self.hud.object_id,
         scale=Scale(0.005/SCL_HUD, 0.005/SCL_HUD, 0.005/SCL_HUD),
         material=Material(color=Color(255, 255, 255),
                           transparent=True, opacity=0.4),
         clickable=True,
         evt_handler=callback)
     self.scene.add_object(self.cliptarget)
示例#7
0
def do_rotate_select(camname, objid, rotation=None):
    color = arblib.CLR_ROTATE
    delim = f"_{Mode.ROTATE.value}_"
    callback = rotateline_callback
    obj = scene.get_persisted_obj(objid)
    position = Position()
    if "position" in obj.data:
        position = obj.data.position
    if not rotation:
        rotation = Rotation()
        if "rotation" in obj.data:
            rotation = obj.data.rotation
    xl, yl, zl = get_clicklines_len(obj)
    # rotate object + or - on 3 axis, plus show original axis as after
    # effect
    root = make_clickroot(objid, position, delim)
    ghost = make_clickroot(objid,
                           position,
                           delim,
                           rotation=rotation,
                           move=True)
    make_clickline("x",
                   xl,
                   objid,
                   position,
                   delim,
                   color,
                   callback,
                   ghost=ghost,
                   parent=root)
    make_clickline("y",
                   yl,
                   objid,
                   position,
                   delim,
                   color,
                   callback,
                   ghost=ghost,
                   parent=root)
    make_clickline("z",
                   zl,
                   objid,
                   position,
                   delim,
                   color,
                   callback,
                   ghost=ghost,
                   parent=root)
    # TODO: restore make_followspot(objid, position, delim, color)
    try:
        rote = arblib.rotation_quat2euler(
            (rotation.x, rotation.y, rotation.z, rotation.w))
    except ValueError as error:
        print(f"Rotation error: {error}")
        return
    euler = (round(rote[0], 1), round(rote[1], 1), round(rote[2], 1))
    USERS[camname].set_textright(
        f"{USERS[camname].target_style}d r({euler[0]},{euler[1]},{euler[2]})")
示例#8
0
def do_nudge_select(camname, objid, position=None):
    color = arblib.CLR_NUDGE
    delim = f"_{Mode.NUDGE.value}_"
    callback = nudgeline_callback
    obj = scene.get_persisted_obj(objid)
    if not position:
        position = Position()
        if "position" in obj.data:
            position = obj.data.position
    xl, yl, zl = get_clicklines_len(obj)
    # nudge object + or - on 3 axis
    root = make_clickroot(objid, position, delim, move=True)
    make_clickline("x",
                   xl,
                   objid,
                   position,
                   delim,
                   color,
                   callback,
                   move=True,
                   parent=root)
    make_clickline("y",
                   yl,
                   objid,
                   position,
                   delim,
                   color,
                   callback,
                   move=True,
                   parent=root)
    make_clickline("z",
                   zl,
                   objid,
                   position,
                   delim,
                   color,
                   callback,
                   move=True,
                   parent=root)
    # TODO: restore make_followspot(objid, position, delim, color, move=True)
    pos = Position(round(position.x, 3), round(position.y, 3),
                   round(position.z, 3))
    USERS[camname].set_textright(
        f"{USERS[camname].target_style} p({pos.x},{pos.y},{pos.z})")
示例#9
0
 def make_hudtext(self, label, position, text):
     text = Text(
         object_id=f"{label}_{self.camname}",
         parent=self.hud.object_id,
         text=text,
         position=Position(position.x / SCL_HUD, position.y / SCL_HUD,
                           position.z / SCL_HUD),
         color=CLR_HUDTEXT,
         scale=Scale(0.1 / SCL_HUD, 0.1 / SCL_HUD, 0.1 / SCL_HUD),
     )
     self.scene.add_object(text)
     return text
示例#10
0
def show_redpill_obj(camname, object_id):
    # any scene changes must not persist
    obj = scene.get_persisted_obj(object_id)
    # enable mouse enter/leave pos/rot/scale
    position = Position()
    if "position" in obj.data:
        position = obj.data.position
    rotation = Rotation()
    if "rotation" in obj.data:
        rotation = obj.data.rotation
    scale = Scale()
    if "scale" in obj.data:
        scale = obj.data.scale
    USERS[camname].set_textstatus(" ".join([
        f"{object_id}", f"p({position.x},{position.y},{position.z})",
        f"r({rotation.x},{rotation.y},{rotation.z},{rotation.w})",
        f"s({scale.x},{scale.y},{scale.z})"
    ]))
示例#11
0
def regline(object_id, axis, direction, delim, suffix, start, end, line_width,
            move, color, parent):
    line_width = line_width / SCL_CLICK
    end = Position(x=(end.x - start.x) / SCL_CLICK,
                   y=(end.y - start.y) / SCL_CLICK,
                   z=(end.z - start.z) / SCL_CLICK)
    name = f"{object_id}{delim}{axis}{direction}_{suffix}"
    if name not in CONTROLS[object_id]:
        CONTROLS[object_id][name] = Line(
            object_id=name,
            color=color,
            # TODO: restore ttl=arblib.TTL_TEMP,
            parent=parent,
            start=start,
            end=end)
        scene.add_object(CONTROLS[object_id][name])
    elif move:
        scene.update_object(CONTROLS[object_id][name], start=start, end=end)
示例#12
0
def make_followspot(object_id, position, delim, color, parent, move=False):
    name = f"{object_id}{delim}spot"
    if name not in CONTROLS[object_id]:
        CONTROLS[object_id][name] = Circle(  # follow spot on ground
            object_id=name,
            scale=Scale(0.1, 0.1, 0.1),
            # TODO: restore ttl=arblib.TTL_TEMP,
            position=Position(position.x, arblib.FLOOR_Y, position.z),
            rotation=Rotation(-0.7, 0, 0, 0.7),
            parent=parent,
            material=Material(color=color,
                              transparent=True,
                              opacity=0.4,
                              shader="flat"),
        )
        scene.add_object(CONTROLS[object_id][name])
    elif move:
        scene.update_object(CONTROLS[object_id][name], position=position)
示例#13
0
def stretchline_callback(_scene, event, msg):
    obj, direction, move = handle_clickline_event(event, Mode.STRETCH)
    if not obj or not direction or not move or "scale" not in obj.data or "position" not in obj.data:
        return
    scaled = sca = obj.data.scale
    moved = loc = obj.data.position
    inc = meters_increment(USERS[event.data.source].target_style)
    if direction == "xp":
        scaled = Scale(x=incr_pos(sca.x, inc), y=sca.y, z=sca.z)
        moved = Position(x=recenter(scaled.x, sca.x, loc.x, move),
                         y=loc.y,
                         z=loc.z)
    elif direction == "xn":
        scaled = Scale(x=incr_neg(sca.x, inc), y=sca.y, z=sca.z)
        moved = Position(x=recenter(scaled.x, sca.x, loc.x, move),
                         y=loc.y,
                         z=loc.z)
    elif direction == "yp":
        scaled = Scale(x=sca.x, y=incr_pos(sca.y, inc), z=sca.z)
        moved = Position(x=loc.x,
                         y=recenter(scaled.y, sca.y, loc.y, move),
                         z=loc.z)
    elif direction == "yn":
        scaled = Scale(x=sca.x, y=incr_neg(sca.y, inc), z=sca.z)
        moved = Position(x=loc.x,
                         y=recenter(scaled.y, sca.y, loc.y, move),
                         z=loc.z)
    elif direction == "zp":
        scaled = Scale(x=sca.x, y=sca.y, z=incr_pos(sca.z, inc))
        moved = Position(x=loc.x,
                         y=loc.y,
                         z=recenter(scaled.z, sca.z, loc.z, move))
    elif direction == "zn":
        scaled = Scale(x=sca.x, y=sca.y, z=incr_neg(sca.z, inc))
        moved = Position(x=loc.x,
                         y=loc.y,
                         z=recenter(scaled.z, sca.z, loc.z, move))
    if scaled.x <= 0 or scaled.y <= 0 or scaled.z <= 0:
        return
    arblib.stretch_obj(scene, obj.object_id, scale=scaled, position=moved)
    print(f"{str(obj.data.scale)} to {str(scaled)}")
    do_stretch_select(event.data.source, obj.object_id, scale=scaled)
示例#14
0
def nudgeline_callback(_scene, event, msg):
    obj, direction, move = handle_clickline_event(event, Mode.NUDGE)
    if not obj or not direction or "position" not in obj.data:
        return
    nudged = loc = obj.data.position
    inc = meters_increment(USERS[event.data.source].target_style)
    if direction == "xp":
        nudged = Position(x=incr_pos(loc.x, inc), y=loc.y, z=loc.z)
    elif direction == "xn":
        nudged = Position(x=incr_neg(loc.x, inc), y=loc.y, z=loc.z)
    elif direction == "yp":
        nudged = Position(x=loc.x, y=incr_pos(loc.y, inc), z=loc.z)
    elif direction == "yn":
        nudged = Position(x=loc.x, y=incr_neg(loc.y, inc), z=loc.z)
    elif direction == "zp":
        nudged = Position(x=loc.x, y=loc.y, z=incr_pos(loc.z, inc))
    elif direction == "zn":
        nudged = Position(x=loc.x, y=loc.y, z=incr_neg(loc.z, inc))
    arblib.move_obj(scene, obj.object_id, nudged)
    print(f"{str(obj.data.position)} to {str(nudged)}")
    # always redraw nudgelines
    do_nudge_select(event.data.source, obj.object_id, position=nudged)
示例#15
0
    def __init__(self, scene: Scene, camname, panel_callback):
        self.scene = scene
        self.camname = camname
        self.mode = Mode.NONE
        self.clipboard = self.cliptarget = None
        self.target_id = self.target_control_id = None
        self.position = self.rotation = None
        self.position_last = self.rotation_last = None
        self.gesturing = False
        self.target_style = self.typetext = ""
        self.locky = LOCK_YOFF
        self.lockx = LOCK_XOFF
        self.wloc_start = self.wloc_end = None
        self.wrot_start = self.wrot_end = None
        self.lamp = None
        init_origin(self.scene)

        # set HUD to each user
        self.hud = Box(
            object_id=f"hud_{camname}",
            parent=camname,
            material=Material(transparent=True, opacity=0),
            position=Position(0, 0, 0),
            scale=Scale(SCL_HUD, SCL_HUD, SCL_HUD),
            rotation=Rotation(0, 0, 0, 1),
        )
        self.scene.add_object(self.hud)
        self.hudtext_left = self.make_hudtext(
            "hudTextLeft", Position(-0.15, 0.15, -0.5), str(self.mode))
        self.hudtext_right = self.make_hudtext(
            "hudTextRight", Position(0.1, 0.15, -0.5), "")
        self.hudtext_status = self.make_hudtext(
            "hudTextStatus", Position(0.02, -0.15, -0.5), "")  # workaround x=0 bad?

        # AR Control Panel
        self.follow_lock = False
        self.follow = Box(
            object_id=f"follow_{camname}",
            parent=camname,
            material=Material(transparent=True, opacity=0),
            position=Position(0, 0, -PANEL_RADIUS * 0.1),
            scale=Scale(0.1, 0.01, 0.1),
            rotation=Rotation(0.7, 0, 0, 0.7),
        )
        self.scene.add_object(self.follow)
        self.redpill = False
        self.slider = False
        self.panel = {}  # button dictionary
        self.dbuttons = {}
        buttons = [
            # top row
            [Mode.ROTATE, -2, 1, True, ButtonType.ACTION],
            [Mode.NUDGE, -1, 1, True, ButtonType.ACTION],
            [Mode.SCALE, 0, 1, True, ButtonType.ACTION],
            [Mode.STRETCH, 1, 1, True, ButtonType.ACTION],
            [Mode.MODEL, 2, 1, True, ButtonType.ACTION],
            [Mode.CREATE, 3, 1, True, ButtonType.ACTION],
            # center row
            [Mode.REDPILL, -2, 0, True, ButtonType.TOGGLE],
            [Mode.MOVE, -1, 0, True, ButtonType.ACTION],
            [Mode.LOCK, 0, 0, True, ButtonType.TOGGLE],
            [Mode.DELETE, 1, 0, True, ButtonType.ACTION],
            [Mode.PARENT, 2, 0, True, ButtonType.ACTION],
            # bottom row
            [Mode.WALL, -2, -1, True, ButtonType.ACTION],
            [Mode.OCCLUDE, -1, -1, True, ButtonType.ACTION],
            [Mode.RENAME, 0, -1, True, ButtonType.ACTION],
            [Mode.COLOR, 1, -1, True, ButtonType.ACTION],
            [Mode.LAMP, 2, -1, True, ButtonType.TOGGLE],
            [Mode.SLIDER, 3, -1, False, ButtonType.TOGGLE],  # TODO: adjust scale
        ]
        for but in buttons:
            pbutton = Button(
                scene, camname, but[0], but[1], but[2], enable=but[3], btype=but[4],
                parent=self.follow.object_id, callback=panel_callback)
            self.panel[pbutton.button.object_id] = pbutton
示例#16
0
def make_clickline(axis,
                   linelen,
                   objid,
                   start,
                   delim,
                   color,
                   callback,
                   ghost=None,
                   parent=None,
                   move=False):
    if objid not in CONTROLS.keys():
        CONTROLS[objid] = {}
    endx = endy = endz = 0
    direction = "p"
    if linelen < 0:
        direction = "n"
    if axis == "x":
        endx = linelen
    elif axis == "y":
        endy = linelen
    elif axis == "z":
        endz = linelen
    start = Position(0, 0, 0)
    end = Position(x=start.x + endx, y=start.y + endy, z=start.z + endz)
    boxline(  # reference line
        object_id=objid,
        axis=axis,
        direction=direction,
        delim=delim,
        suffix="line",
        color=color,
        start=start,
        end=end,
        line_width=0.005,
        move=move,
        parent=parent)
    if ghost:
        boxline(  # ghostline aligns to parent rotation
            object_id=objid,
            axis=axis,
            direction=direction,
            delim=delim,
            suffix="ghost",
            color=(255, 255, 255),
            start=start,
            end=end,
            line_width=0.005,
            move=move,
            parent=ghost)
    if ghost:
        cones = arblib.ROTATE_CONES
    else:
        cones = arblib.DIRECT_CONES
    dir_clickers(  # click objects
        object_id=objid,
        axis=axis,
        direction=direction,
        delim=delim,
        position=end,
        color=color,
        cones=cones,
        callback=callback,
        move=move,
        parent=parent)
示例#17
0
def make_wall(camname):
    # Wall theory: capture two poses and use them to place a wall object.
    # Also assumes first corner easier to capture accurate rotation than last.
    # Click 1: Capture the position and rotation.
    # Click 2: Capture the position only.
    sloc = USERS[camname].wloc_start
    eloc = USERS[camname].wloc_end
    srot = USERS[camname].wrot_start
    erot = USERS[camname].wrot_end
    print(f"S POS {str(sloc)}")
    print(f"E POS {str(eloc)}")
    # center point (blue)
    locx = statistics.median([sloc.x, eloc.x])
    locy = statistics.median([sloc.y, eloc.y])
    locz = statistics.median([sloc.z, eloc.z])
    pos = Position(locx, locy, locz)
    scene.add_object(arblib.temp_loc_marker(pos, Color(0, 0, 255)))
    print(f"wall position {str(pos)}")
    # rotation
    print(f"S ROT {str(srot)}")
    print(f"E ROT {str(erot)}")
    rotx = arblib.probable_quat(srot.x)
    roty = arblib.probable_quat(srot.y)
    rotz = arblib.probable_quat(srot.z)
    rotw = arblib.probable_quat(srot.w)
    rot = Rotation(rotx, roty, rotz, rotw)
    gaze = (rotx, roty, rotz, rotw)
    scene.add_object(arblib.temp_rot_marker(pos, rot))
    print(f"wall rotation {str(rot)}")
    # which axis to use for wall? use camera gaze
    # TODO: rotation still off
    if gaze in arblib.GAZES[0]:
        height = abs(sloc.y - eloc.y)
        width = abs(sloc.x - eloc.x)
    elif gaze in arblib.GAZES[1]:
        height = abs(sloc.y - eloc.y)
        width = abs(sloc.z - eloc.z)
    elif gaze in arblib.GAZES[2]:
        height = abs(sloc.z - eloc.z)
        width = abs(sloc.x - eloc.x)
    else:
        # TODO: (placeholder) add direction and hypotenuse
        height = abs(sloc.y - eloc.y)
        width = abs(sloc.x - eloc.x)
        print(f"Non-axis parallel rotation: {str(rot)}")
    # scale
    scax = width
    scay = height
    scaz = arblib.WALL_WIDTH
    sca = Scale(scax, scay, scaz)
    print(f"wall scale {str(sca)}")
    # make wall
    randstr = str(random.randrange(0, 1000000))
    new_wall = Box(
        persist=True,
        clickable=True,
        object_id=f"wall_{randstr}",
        position=pos,
        rotation=rot,
        scale=sca,
        material=Material(color=Color(200, 200, 200),
                          transparent=True,
                          opacity=0.5),
    )
    scene.add_object(new_wall)
    USERS[camname].target_id = new_wall.object_id
    print(f"Created {new_wall.object_id} r{str(rot)} s{str(sca)}")
示例#18
0
def do_stretch_select(camname, objid, scale=None):
    color = arblib.CLR_STRETCH
    delim = f"_{Mode.STRETCH.value}_"
    callback = stretchline_callback
    obj = scene.get_persisted_obj(objid)
    position = Position()
    if "position" in obj.data:
        position = obj.data.position
    if not scale:
        object_type = "box"
        if "object_type" in obj.data:
            object_type = obj.data.object_type
        rotation = Rotation()
        if "rotation" in obj.data:
            rotation = obj.data.rotation
        scale = Scale()
        if "scale" in obj.data:
            scale = obj.data.scale
        # TODO: scale too unpredictable, modify
        if object_type == GLTF.object_type:
            return
        # TODO: scale too unpredictable, modify
        if rotation.quaternion.__dict__ != Rotation(x=0, y=0, z=0,
                                                    w=1).quaternion.__dict__:
            return
    xl, yl, zl = get_clicklines_len(obj)
    # scale and reposition on one of 6 sides
    root = make_clickroot(objid, position, delim, move=True)
    make_clickline("x",
                   xl,
                   objid,
                   position,
                   delim,
                   color,
                   callback,
                   move=True,
                   parent=root)
    make_clickline("x",
                   -xl,
                   objid,
                   position,
                   delim,
                   color,
                   callback,
                   move=True,
                   parent=root)
    make_clickline("y",
                   yl,
                   objid,
                   position,
                   delim,
                   color,
                   callback,
                   move=True,
                   parent=root)
    make_clickline("y",
                   -yl,
                   objid,
                   position,
                   delim,
                   color,
                   callback,
                   move=True,
                   parent=root)
    make_clickline("z",
                   zl,
                   objid,
                   position,
                   delim,
                   color,
                   callback,
                   move=True,
                   parent=root)
    make_clickline("z",
                   -zl,
                   objid,
                   position,
                   delim,
                   color,
                   callback,
                   move=True,
                   parent=root)
    # TODO: restore make_followspot(objid, position, delim, color)
    sca = Scale(round(scale.x, 3), round(scale.y, 3), round(scale.z, 3))
    USERS[camname].set_textright(
        f"{USERS[camname].target_style} s({sca.x},{sca.y},{sca.z})")
示例#19
0
 def __init__(self, scene: Scene, camname, mode, x=0, y=0, label="", parent=None,
              drop=None, color=CLR_BUTTON, enable=True, callback=None,
              btype=ButtonType.ACTION):
     self.scene = scene
     if label == "":
         label = mode.value
     if parent is None:
         parent = camname
         scale = Scale(0.1, 0.1, 0.01)
     else:
         scale = Scale(1, 1, 1)
     self.type = btype
     self.enabled = enable
     if enable:
         self.colorbut = color
     else:
         self.colorbut = CLR_BUTTON_DISABLED
     self.colortxt = CLR_BUTTON_TEXT
     if len(label) > 8:  # easier to read
         self.label = f"{label[:6]}..."
     else:
         self.label = label
     self.mode = mode
     self.dropdown = drop
     self.active = False
     if drop is None:
         obj_name = f"{camname}_button_{mode.value}"
     else:
         obj_name = f"{camname}_button_{mode.value}_{drop}"
     shape = Box.object_type
     if btype == ButtonType.TOGGLE:
         shape = Cylinder.object_type
         scale = Scale(scale.x / 2, scale.y, scale.z / 2)
     self.button = Object(  # box is main button
         object_id=obj_name,
         object_type=shape,
         parent=parent,
         material=Material(
             color=self.colorbut,
             transparent=True,
             opacity=OPC_BUTTON,
             shader="flat"),
         position=Position(x * 1.1, PANEL_RADIUS, y * -1.1),
         scale=scale,
         clickable=True,
         evt_handler=callback,
     )
     scene.add_object(self.button)
     scale = Scale(1, 1, 1)
     if btype == ButtonType.TOGGLE:
         scale = Scale(scale.x * 2, scale.y * 2, scale.z)
     self.text = Text(  # text child of button
         object_id=f"{self.button.object_id}_text",
         parent=self.button.object_id,
         text=self.label,
         # position inside to prevent ray events
         position=Position(0, -0.1, 0),
         rotation=Rotation(-0.7, 0, 0, 0.7),
         scale=scale,
         color=self.colortxt,
     )
     scene.add_object(self.text)
示例#20
0
def scene_callback(_scene, event, msg):
    # This is the MQTT message callback function for the scene
    object_id = action = msg_type = object_type = None
    if "object_id" in msg:
        object_id = msg["object_id"]
    if "action" in msg:
        action = msg["action"]
    if "type" in msg:
        msg_type = msg["type"]
    if "data" in msg and "object_type" in msg["data"]:
        object_type = msg["data"]["object_type"]
    # print(f'{object_type} {action} {msg_type} {object_id}')

    if object_type == "camera":
        # camera updates define users present
        camname = object_id
        if camname not in USERS:
            USERS[camname] = arblib.User(scene, camname, panel_callback)

        # save camera's attitude in the world
        USERS[camname].position = Position(msg["data"]["position"]["x"],
                                           msg["data"]["position"]["y"],
                                           msg["data"]["position"]["z"])
        USERS[camname].rotation = Rotation(msg["data"]["rotation"]["x"],
                                           msg["data"]["rotation"]["y"],
                                           msg["data"]["rotation"]["z"],
                                           msg["data"]["rotation"]["w"])

        rx = msg["data"]["rotation"]["x"]
        ry = msg["data"]["rotation"]["y"]

        # floating controller
        if not USERS[camname].follow_lock:
            ty = -(ry + USERS[camname].locky) / 0.7 * math.pi / 2
            tx = -(rx + USERS[camname].lockx) / 0.7 * math.pi / 2
            px = arblib.PANEL_RADIUS * -math.cos(ty)
            py = arblib.PANEL_RADIUS * math.sin(tx)
            pz = arblib.PANEL_RADIUS * math.sin(ty)
            scene.update_object(USERS[camname].follow,
                                position=Position(px, py, pz))
        # else: # TODO: panel lock position drop is inaccurate
        # users[camname].lockx = rx + arblib.LOCK_XOFF
        # users[camname].locky = -(ry * math.pi) - arblib.LOCK_YOFF

    # mouse event
    elif action == "clientEvent":
        object_id = msg["object_id"]
        # camera updates define users present
        camname = msg["data"]["source"]
        if camname not in USERS:
            USERS[camname] = arblib.User(scene, camname, panel_callback)

        # show objects with events
        if msg_type == EVT_MOUSEENTER:
            if USERS[camname].redpill:
                show_redpill_obj(camname, object_id)
            else:
                USERS[camname].set_textstatus(object_id)
        elif msg_type == EVT_MOUSELEAVE:
            USERS[camname].set_textstatus("")

        # handle click
        elif msg_type == EVT_MOUSEDOWN:
            # clicked on persisted object to modify
            update_controls(USERS[camname].target_id)
            USERS[camname].target_id = object_id  # always update
            if USERS[camname].mode == Mode.DELETE:
                arblib.delete_obj(scene, object_id)
            elif USERS[camname].mode == Mode.MOVE:
                do_move_select(camname, object_id)
            elif USERS[camname].mode == Mode.NUDGE:
                do_nudge_select(camname, object_id)
            elif USERS[camname].mode == Mode.SCALE:
                do_scale_select(camname, object_id)
            elif USERS[camname].mode == Mode.STRETCH:
                do_stretch_select(camname, object_id)
            elif USERS[camname].mode == Mode.ROTATE:
                do_rotate_select(camname, object_id)
            elif USERS[camname].mode == Mode.COLOR:
                arblib.color_obj(scene, object_id,
                                 Color(USERS[camname].target_style))
            elif USERS[camname].mode == Mode.OCCLUDE:
                arblib.occlude_obj(scene, object_id,
                                   USERS[camname].target_style)
            elif USERS[camname].mode == Mode.RENAME or USERS[
                    camname].mode == Mode.PARENT:
                if len(USERS[camname].typetext) > 0:  # edits already made
                    new_id = USERS[camname].typetext
                    USERS[camname].typetext = ""
                    if USERS[camname].mode == Mode.PARENT:
                        arblib.parent_obj(scene, object_id, new_id)
                    else:
                        do_rename(camname, object_id, new_id)
                else:  # no edits yet, load previous name to change
                    USERS[camname].typetext = object_id
                USERS[camname].set_textright(USERS[camname].typetext)
示例#21
0
def show_redpill_scene(enabled):
    # any scene changes must not persist
    # show gridlines
    name = "grid_redpill"
    path = []
    glen = arblib.GRIDLEN
    y = arblib.FLOOR_Y
    for z in range(-glen, glen + 1):
        if (z % 2) == 0:
            path.append(Position(-glen, y, z))
            path.append(Position(glen, y, z))
        else:
            path.append(Position(glen, y, z))
            path.append(Position(-glen, y, z))
    for x in range(-glen, glen + 1):
        if (x % 2) == 0:
            path.append(Position(x, y, glen))
            path.append(Position(x, y, -glen))
        else:
            path.append(Position(x, y, -glen))
            path.append(Position(x, y, glen))

    if enabled:
        scene.add_object(
            ThickLine(object_id=name, path=path, color=arblib.CLR_GRID))
    else:
        arblib.delete_obj(scene, name)

    objs = scene.get_persisted_objs()
    for object_id in objs:
        obj = objs[object_id]
        # show occluded objects
        if "material-extras" in obj.data and "transparentOccluder" in obj.data[
                "material-extras"]:
            name = "redpill_" + obj.object_id
            if enabled:
                object_type = "box"
                if "object_type" in obj.data:
                    object_type = obj.data.object_type
                position = Position()
                if "position" in obj.data:
                    position = obj.data.position
                rotation = Rotation()
                if "rotation" in obj.data:
                    rotation = obj.data.rotation
                scale = Scale()
                if "scale" in obj.data:
                    scale = obj.data.scale
                url = None
                if "url" in obj.data:
                    url = obj.data.url
                color = Color()
                if "material" in obj.data and "color" in obj.data.material:
                    color = obj.data.material.color
                scene.add_object(
                    Object(
                        object_id=name,
                        object_type=object_type,
                        position=position,
                        rotation=rotation,
                        scale=scale,
                        clickable=True,
                        url=url,
                        material=Material(color=color,
                                          transparent=True,
                                          opacity=0.5),
                    ))
                print("Wrapping occlusion " + name)
            else:
                arblib.delete_obj(scene, name)