Пример #1
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])))
Пример #2
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)
Пример #3
0
 def set_active(self, active):
     self.active = active
     if active:
         self.scene.update_object(
             self.button, material=Material(color=CLR_SELECT))
     else:
         self.scene.update_object(
             self.button, material=Material(color=CLR_BUTTON))
         self.scene.update_object(
             self.text, material=Material(color=self.colortxt))
Пример #4
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)
Пример #5
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)
Пример #6
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)
Пример #7
0
def occlude_obj(scene: Scene, object_id, occlude):
    if object_id in scene.all_objects:
        # NOTE: transparency does not allow occlusion so remove transparency here.
        scene.update_object(scene.all_objects[object_id],
                            **{"material-extras": {"transparentOccluder": (occlude != BOOLS[1])}},
                            material=Material(transparent=False, opacity=1))
        print(f"Occluded {object_id}")
Пример #8
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)
Пример #9
0
 def set_hover(self, hover):
     if hover:
         opacity = OPC_BUTTON_HOVER
     else:
         opacity = OPC_BUTTON
     self.scene.update_object(
         self.button,
         material=Material(transparent=True, opacity=opacity, shader="flat"))
Пример #10
0
 def set_lamp(self, enabled):
     if enabled:
         self.lamp = Light(object_id=f"{self.camname}_lamp",
                           parent=self.hud.object_id,
                           material=Material(color=Color(144, 144, 173)),
                           type="point",
                           intensity=0.75)
         self.scene.add_object(self.lamp)
     elif self.lamp:
         self.scene.delete_object(self.lamp)
Пример #11
0
def handle_clickline_event(event, mode):
    # naming order: objectname_clicktype_axis_direction
    click_id = event.object_id.split(f"_{mode.value}_")
    object_id = click_id[0]
    direction = (click_id[1])[0:2]
    move = (click_id[1])[1:4]
    if event.type == EVT_MOUSEENTER:
        scene.update_object(CONTROLS[object_id][event.object_id],
                            material=Material(transparent=True,
                                              opacity=arblib.OPC_CLINE_HOVER))
    elif event.type == EVT_MOUSELEAVE:
        scene.update_object(CONTROLS[object_id][event.object_id],
                            material=Material(transparent=True,
                                              opacity=arblib.OPC_CLINE))
    # allow any user to change an object
    if event.type != EVT_MOUSEDOWN:
        return None, None, None
    if USERS[event.data.source].mode != mode:
        return None, None, None
    obj = scene.get_persisted_obj(object_id)
    return (obj, direction, move)
Пример #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 create_obj(camname, clipboard, position):
    randstr = str(random.randrange(0, 1000000))
    # make a copy of static object in place
    new_obj = Object(
        persist=True,
        object_id=f"{clipboard.data.object_type}_{randstr}",
        object_type=clipboard.data.object_type,
        position=position,
        # undo clipboard rotation for visibility
        rotation=Rotation(0, 0, 0, 1),
        scale=clipboard.data.scale,
        material=Material(color=clipboard.data.material.color,
                          transparent=False),
        url=clipboard.data.url,
        clickable=True)
    scene.add_object(new_obj)
    USERS[camname].target_id = new_obj.object_id
    print("Created " + new_obj.object_id)
Пример #14
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
Пример #15
0
def color_obj(scene: Scene, object_id, color):
    if object_id in scene.all_objects:
        scene.update_object(
            scene.all_objects[object_id], material=Material(color=color))
        print(f"Colored {object_id}")
Пример #16
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)
Пример #17
0
def opaque_obj(scene: Scene, object_id, opacity):
    if object_id in scene.all_objects:
        scene.update_object(scene.all_objects[object_id],
                            material=Material(transparent=True, opacity=opacity))
        print(f"Opaqued {object_id}")
Пример #18
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)}")
Пример #19
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
Пример #20
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)