diff --git a/src/bit-systems/object-menu.ts b/src/bit-systems/object-menu.ts index fef415163f..36bac452e3 100644 --- a/src/bit-systems/object-menu.ts +++ b/src/bit-systems/object-menu.ts @@ -222,18 +222,21 @@ function updateVisibility(world: HubsWorld, menu: EntityID, frozen: boolean) { world.eid2obj.get(ObjectMenu.pinButtonRef[menu])!.visible = visible && !isPinned(target) && canPin(APP.hubChannel!, target); + // Hide unimplemented features for now. + // TODO: Implement and show the buttons. + world.eid2obj.get(ObjectMenu.cameraFocusButtonRef[menu])!.visible = false; + world.eid2obj.get(ObjectMenu.cameraTrackButtonRef[menu])!.visible = false; + world.eid2obj.get(ObjectMenu.deserializeDrawingButtonRef[menu])!.visible = false; + world.eid2obj.get(ObjectMenu.mirrorButtonRef[menu])!.visible = false; + world.eid2obj.get(ObjectMenu.inspectButtonRef[menu])!.visible = false; + world.eid2obj.get(ObjectMenu.dropButtonRef[menu])!.visible = false; + world.eid2obj.get(ObjectMenu.refreshButtonRef[menu])!.visible = false; + [ - ObjectMenu.cameraFocusButtonRef[menu], - ObjectMenu.cameraTrackButtonRef[menu], ObjectMenu.removeButtonRef[menu], - ObjectMenu.dropButtonRef[menu], - ObjectMenu.inspectButtonRef[menu], - ObjectMenu.deserializeDrawingButtonRef[menu], ObjectMenu.openLinkButtonRef[menu], - ObjectMenu.refreshButtonRef[menu], ObjectMenu.cloneButtonRef[menu], ObjectMenu.rotateButtonRef[menu], - ObjectMenu.mirrorButtonRef[menu], ObjectMenu.scaleButtonRef[menu] ].forEach(buttonRef => { const buttonObj = world.eid2obj.get(buttonRef)!; diff --git a/src/hub.js b/src/hub.js index 7b4128a313..c381b3ba1f 100644 --- a/src/hub.js +++ b/src/hub.js @@ -190,7 +190,7 @@ import { sleep } from "./utils/async-utils"; import { platformUnsupported } from "./support"; import { renderAsEntity } from "./utils/jsx-entity"; import { VideoMenuPrefab } from "./prefabs/video-menu"; -import { ObjectMenuPrefab } from "./prefabs/object-menu"; +import { loadObjectMenuButtonIcons, ObjectMenuPrefab } from "./prefabs/object-menu"; import { LinkHoverMenuPrefab } from "./prefabs/link-hover-menu"; import { PDFMenuPrefab } from "./prefabs/pdf-menu"; import { loadWaypointPreviewModel, WaypointPreview } from "./prefabs/waypoint-preview"; @@ -208,8 +208,7 @@ function addToScene(entityDef, visible) { }); } preload(addToScene(PDFMenuPrefab(), false)); -preload(addToScene(ObjectMenuPrefab(), false)); -preload(addToScene(ObjectMenuPrefab(), false)); +preload(loadObjectMenuButtonIcons().then(() => addToScene(ObjectMenuPrefab(), false))); preload(addToScene(LinkHoverMenuPrefab(), false)); preload(loadWaypointPreviewModel().then(() => addToScene(WaypointPreview(), false))); diff --git a/src/prefabs/button3D.tsx b/src/prefabs/button3D.tsx index 164ace96ee..6b26cdbf7b 100644 --- a/src/prefabs/button3D.tsx +++ b/src/prefabs/button3D.tsx @@ -3,6 +3,8 @@ import { Attrs, createElementEntity, createRef, Ref } from "../utils/jsx-entity" import { Layers } from "../camera-layers"; import buttonSrc from "../assets/hud/button.9.png"; import { textureLoader } from "../utils/media-utils"; +import { ProjectionMode } from "../utils/projection-mode"; +import { AlphaMode } from "../utils/create-image-mesh"; import { Texture } from "three"; const buttonTexture = textureLoader.load(buttonSrc); @@ -18,10 +20,11 @@ export interface Refable { } export interface Button3DParams extends Attrs { - text: string; + text?: string; width: number; height: number; texture?: Texture; + icon?: { texture: Texture; cacheKey: string; scale: [number, number, number] }; name?: string; type: ButtonType; labelRef?: Ref; @@ -33,12 +36,36 @@ export function Button3D({ text, width, height, + icon, texture = buttonTexture, name = "Button", type, ...props }: Button3DParams) { const labelRef = createRef(); + + // TODO: Can here be rewritten more elegantly? + // TODO: Avoid any + const iconOrText: Record = {}; + if (icon !== undefined) { + iconOrText.image = { + texture: icon.texture, + ratio: 1, + projection: ProjectionMode.FLAT, + alphaMode: AlphaMode.BLEND, + cacheKey: icon.cacheKey + }; + iconOrText.scale = icon.scale; + } else { + iconOrText.text = { + value: text || "", + color: "#000000", + textAlign: "center", + anchorX: "center", + anchorY: "middle" + }; + } + return ( ); diff --git a/src/prefabs/object-menu.tsx b/src/prefabs/object-menu.tsx index 46d2e08258..9531daeb87 100644 --- a/src/prefabs/object-menu.tsx +++ b/src/prefabs/object-menu.tsx @@ -1,9 +1,21 @@ /** @jsx createElementEntity */ import { ArrayVec3, Attrs, createElementEntity, createRef } from "../utils/jsx-entity"; +import { loadTexture, loadTextureFromCache } from "../utils/load-texture"; import { Button3D, BUTTON_TYPES } from "./button3D"; +import rotateIconSrc from "../assets/rotate-action.png"; +import scaleIconSrc from "../assets/scale-action.png"; +import removeIconSrc from "../assets/remove-action.png"; + +export async function loadObjectMenuButtonIcons() { + return Promise.all([ + loadTexture(rotateIconSrc, 1, "image/png"), + loadTexture(scaleIconSrc, 1, "image/png"), + loadTexture(removeIconSrc, 1, "image/png") + ]); +} const buttonHeight = 0.2; -const buttonScale: ArrayVec3 = [0.4, 0.4, 0.4]; +const buttonScale: ArrayVec3 = [0.6, 0.6, 0.6]; const uiZ = 0.25; function PinButton(props: Attrs) { @@ -63,14 +75,15 @@ function CameraTrackButton(props: Attrs) { } function RemoveButton(props: Attrs) { + const { texture, cacheKey } = loadTextureFromCache(removeIconSrc, 1); return ( ); @@ -161,15 +174,16 @@ function CloneButton(props: Attrs) { } function RotateButton(props: Attrs) { + const { texture, cacheKey } = loadTextureFromCache(rotateIconSrc, 1); return ( ); @@ -190,15 +204,16 @@ function MirrorButton(props: Attrs) { } function ScaleButton(props: Attrs) { + const { texture, cacheKey } = loadTextureFromCache(scaleIconSrc, 1); return ( ); @@ -210,16 +225,16 @@ const position = { unpin: [ 0, 0.125, uiZ] as ArrayVec3, focus: [-0.25, 0.375, uiZ] as ArrayVec3, track: [ 0.25, 0.375, uiZ] as ArrayVec3, - remove: [ 0, -0.375, uiZ] as ArrayVec3, + remove: [ 0, -0.275, uiZ] as ArrayVec3, drop: [ 0.1, -0.625, uiZ] as ArrayVec3, inspect: [ -0.1, -0.625, uiZ] as ArrayVec3, deserializeDrawing: [ -0.3, -0.625, uiZ] as ArrayVec3, - openLink: [ 0.43, -0.375, uiZ] as ArrayVec3, + openLink: [ 0.25, -0.275, uiZ] as ArrayVec3, refresh: [ 0.3, -0.625, uiZ] as ArrayVec3, - clone: [-0.43, -0.375, uiZ] as ArrayVec3, - rotate: [ -0.3, -0.125, uiZ] as ArrayVec3, + clone: [-0.25, -0.275, uiZ] as ArrayVec3, + rotate: [ -0.2, -0.125, uiZ] as ArrayVec3, mirror: [ 0, -0.125, uiZ] as ArrayVec3, - scale: [ 0.3, -0.125, uiZ] as ArrayVec3, + scale: [ 0.2, -0.125, uiZ] as ArrayVec3, }; export function ObjectMenuPrefab() {