Ejemplo n.º 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)
Ejemplo n.º 2
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})")
Ejemplo n.º 3
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)
Ejemplo n.º 4
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])))
Ejemplo n.º 5
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)
Ejemplo n.º 6
0
def temp_loc_marker(position, color):
    return Sphere(ttl=120,
                  material=Material(color=color, transparent=True,
                                    opacity=0.5),
                  position=position,
                  scale=Scale(0.02, 0.02, 0.02),
                  clickable=True)
Ejemplo n.º 7
0
def temp_rot_marker(position, rotation):
    return Box(ttl=120,
               rotation=rotation,
               material=Material(color=Color(255, 255, 255)),
               position=position,
               scale=Scale(0.02, 0.01, 0.15),
               clickable=True)
Ejemplo n.º 8
0
 def get_clipboard(self):
     obj_actual = self.clipboard
     obj_actual.data.scale = Scale(
         self.clipboard.data.scale.x*SCL_HUD,
         self.clipboard.data.scale.y*SCL_HUD,
         self.clipboard.data.scale.z*SCL_HUD)
     return obj_actual
Ejemplo n.º 9
0
def get_clicklines_len(obj):
    object_type = "box"
    if "object_type" in obj.data:
        object_type = obj.data.object_type
    scale = Scale()
    if "scale" in obj.data:
        scale = obj.data.scale
    if object_type == "gltf-model":
        # TODO: if we can get the gltf size (not scale), we can make accurate clicklines
        scale = Scale(1, 1, 1)
        line_extension = arblib.CLICKLINE_LEN_MOD
    else:
        line_extension = arblib.CLICKLINE_LEN_OBJ
    xl = scale.x + line_extension
    yl = scale.y + line_extension
    zl = scale.z + line_extension
    print(xl, yl, zl)
    return xl, yl, zl
Ejemplo n.º 10
0
def scaleline_callback(_scene, event, msg):
    obj, direction, move = handle_clickline_event(event, Mode.SCALE)
    if not obj or not direction or "scale" not in obj.data:
        return
    scaled = sca = obj.data.scale
    inc = meters_increment(USERS[event.data.source].target_style)
    if direction == "xp":
        scaled = Scale(x=incr_pos(sca.x, inc),
                       y=incr_pos(sca.y, inc),
                       z=incr_pos(sca.z, inc))
    elif direction == "xn":
        scaled = Scale(x=incr_neg(sca.x, inc),
                       y=incr_neg(sca.y, inc),
                       z=incr_neg(sca.z, inc))
    if scaled.x <= 0 or scaled.y <= 0 or scaled.z <= 0:
        return
    arblib.scale_obj(scene, obj.object_id, scaled)
    print(f"{str(obj.data.scale)} to {str(scaled)}")
    do_scale_select(event.data.source, obj.object_id, scale=scaled)
Ejemplo n.º 11
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
Ejemplo n.º 12
0
def model_callback(_scene, event, msg):
    camname, objid, drop = handle_panel_event(event, dropdown=True)
    if not camname or not drop:
        return
    model = drop
    idx = MODELS.index(model)
    url = MANIFEST[idx]['url_gltf']
    sca = MANIFEST[idx]['scale']
    USERS[camname].set_clipboard(callback=clipboard_callback,
                                 object_type=GLTF.object_type,
                                 scale=Scale(sca, sca, sca),
                                 url=url)
    USERS[camname].set_textright(model)
    USERS[camname].target_style = model
Ejemplo n.º 13
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)
Ejemplo n.º 14
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})"
    ]))
Ejemplo n.º 15
0
def make_clickroot(objid, position, delim, rotation=None, move=False):
    if objid not in CONTROLS.keys():
        CONTROLS[objid] = {}
    name = f"{objid}{delim}clickroot"
    if rotation:
        name += "_rotated"
    else:
        rotation = Rotation(0, 0, 0, 1)
    if name not in CONTROLS[objid]:
        CONTROLS[objid][name] = Box(
            object_id=name,
            material=Material(transparent=True, opacity=0),
            position=position,
            scale=Scale(SCL_CLICK, SCL_CLICK, SCL_CLICK),
            rotation=rotation,
        )
        scene.add_object(CONTROLS[objid][name])
    elif move:
        scene.update_object(CONTROLS[objid][name],
                            position=position,
                            rotation=rotation)
    return name
Ejemplo n.º 16
0
def do_move_select(camname, object_id):
    obj = scene.get_persisted_obj(object_id)
    USERS[camname].target_id = object_id
    object_type = "box"
    if "object_type" in obj.data:
        object_type = obj.data.object_type
    scale = Scale()
    if "scale" in obj.data:
        scale = obj.data.scale
    color = Color()
    if "material" in obj.data and "color" in obj.data.material:
        color = obj.data.material.color
    url = None
    if "url" in obj.data:
        url = obj.data.url
    USERS[camname].set_clipboard(
        callback=clipboard_callback,
        object_type=object_type,
        scale=scale,
        color=color,
        url=url,
    )
Ejemplo n.º 17
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)
Ejemplo n.º 18
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)
Ejemplo n.º 19
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)
Ejemplo n.º 20
0
def panel_callback(_scene, event, msg):
    camname, objid, drop = handle_panel_event(event)
    if not camname or not objid:
        return
    # ignore disabled
    if not USERS[camname].panel[objid].enabled:
        return

    update_controls(USERS[camname].target_id)
    mode = USERS[camname].panel[objid].mode
    btype = USERS[camname].panel[objid].type
    if btype == ButtonType.TOGGLE:
        USERS[camname].panel[objid].set_active(
            not USERS[camname].panel[objid].active)
    else:
        if mode == USERS[camname].mode:  # action cancel
            # button click is same, then goes off and NONE
            USERS[camname].panel[objid].set_active(False)
            USERS[camname].mode = Mode.NONE
            mode = Mode.NONE
        else:
            # if button goes on, last button must go off
            prev_objid = f"{camname}_button_{USERS[camname].mode.value}"
            if prev_objid in USERS[camname].panel:
                USERS[camname].panel[prev_objid].set_active(False)
            USERS[camname].panel[objid].set_active(True)
            USERS[camname].mode = mode
        USERS[camname].set_textleft(USERS[camname].mode)
        USERS[camname].set_textright("")
        USERS[camname].del_clipboard()
        # clear last dropdown
        for but in USERS[camname].dbuttons:
            USERS[camname].dbuttons[but].delete()
        USERS[camname].dbuttons.clear()

    active = USERS[camname].panel[objid].active
    # toggle buttons
    if mode == Mode.LOCK:
        USERS[camname].follow_lock = active
        # TODO: after lock ensure original ray keeps lock button in reticle
    elif mode == Mode.REDPILL:
        # TODO: migrate to shared-scene setting
        USERS[camname].redpill = active
        show_redpill_scene(active)
    elif mode == Mode.LAMP:
        USERS[camname].set_lamp(active)
    # active buttons
    if mode == Mode.CREATE:
        update_dropdown(camname, objid, mode, arblib.SHAPES, 2, shape_callback)
        USERS[camname].set_clipboard(callback=clipboard_callback,
                                     object_type=USERS[camname].target_style)
    elif mode == Mode.MODEL:
        update_dropdown(camname, objid, mode, MODELS, 2, model_callback)
        idx = MODELS.index(USERS[camname].target_style)
        url = MANIFEST[idx]['url_gltf']
        sca = MANIFEST[idx]['scale']
        USERS[camname].set_clipboard(callback=clipboard_callback,
                                     object_type=GLTF.object_type,
                                     scale=Scale(sca, sca, sca),
                                     url=url)
    elif mode == Mode.COLOR:
        update_dropdown(camname, objid, mode, arblib.COLORS, -2,
                        color_callback)
    elif mode == Mode.OCCLUDE:
        update_dropdown(camname, objid, mode, arblib.BOOLS, -2, gen_callback)
    elif mode == Mode.RENAME:
        USERS[camname].typetext = ""
        update_dropdown(camname, objid, mode, arblib.KEYS, -2, rename_callback)
        USERS[camname].set_textright(USERS[camname].typetext)
    elif mode == Mode.PARENT:
        USERS[camname].typetext = ""
        USERS[camname].set_textright(USERS[camname].typetext)
    elif mode == Mode.WALL:
        USERS[camname].set_clipboard(callback=wall_callback)
        USERS[camname].set_textright("Start: tap flush corner.")
    elif mode == Mode.NUDGE:
        update_dropdown(camname, objid, mode, arblib.METERS, 2, gen_callback)
        if USERS[camname].target_id:
            do_nudge_select(camname, USERS[camname].target_id)
    elif mode == Mode.SCALE:
        update_dropdown(camname, objid, mode, arblib.METERS, 2, gen_callback)
        if USERS[camname].target_id:
            do_scale_select(camname, USERS[camname].target_id)
    elif mode == Mode.STRETCH:
        update_dropdown(camname, objid, mode, arblib.METERS, 2, gen_callback)
        if USERS[camname].target_id:
            do_stretch_select(camname, USERS[camname].target_id)
    elif mode == Mode.ROTATE:
        update_dropdown(camname, objid, mode, arblib.DEGREES, 2, gen_callback)
        if USERS[camname].target_id:
            do_rotate_select(camname, USERS[camname].target_id)
Ejemplo n.º 21
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
Ejemplo n.º 22
0
# AR Builder Library
# Utility classes and methods for AR Builder.

# pylint: disable=missing-docstring

import enum

import scipy
from arena import (Box, Circle, Color, Cone, Cylinder, Dodecahedron,
                   Icosahedron, Light, Material, Object, Octahedron, Plane,
                   Position, Ring, Rotation, Scale, Scene, Sphere, Tetrahedron,
                   Text, Torus, TorusKnot, Triangle)

CLICKLINE_LEN_OBJ = 0.5  # meters
CLICKLINE_LEN_MOD = 0.5  # meters
CLICKLINE_SCL = Scale(1, 1, 1)  # meters
FLOOR_Y = 0.1  # meters
GRIDLEN = 20  # meters
SCL_HUD = 0.1  # meters
PANEL_RADIUS = 1  # meters
CLIP_RADIUS = PANEL_RADIUS + 0.25  # meters
LOCK_XOFF = 0  # quaternion vector
LOCK_YOFF = 0.7  # quaternion vector
CLR_HUDTEXT = Color(128, 128, 128)  # gray
CLR_NUDGE = Color(255, 255, 0)  # yellow
CLR_SCALE = Color(0, 0, 255)  # blue
CLR_STRETCH = Color(255, 0, 0)  # red
CLR_ROTATE = Color(255, 165, 0)  # orange
CLR_SELECT = Color(255, 255, 0)  # yellow
CLR_GRID = Color(0, 255, 0)  # green
CLR_BUTTON = Color(200, 200, 200)  # white-ish
Ejemplo n.º 23
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})")
Ejemplo n.º 24
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)}")