diff --git a/src/bit-systems/object-menu-transform-system.ts b/src/bit-systems/object-menu-transform-system.ts
index b2f06feaa4..a82a727bc9 100644
--- a/src/bit-systems/object-menu-transform-system.ts
+++ b/src/bit-systems/object-menu-transform-system.ts
@@ -1,4 +1,4 @@
-import { defineQuery } from "bitecs";
+import { defineQuery, removeComponent } from "bitecs";
import { HubsWorld } from "../app";
import { ObjectMenuTarget, ObjectMenuTransform } from "../bit-components";
import { EntityID } from "../utils/networking-types";
@@ -7,7 +7,6 @@ import { isFacingCamera, setFromObject, setMatrixWorld } from "../utils/three-ut
import { ObjectMenuTargetFlags } from "../inflators/object-menu-target";
import { ObjectMenuTransformFlags } from "../inflators/object-menu-transform";
-const offset = new Vector3();
const tmpVec1 = new Vector3();
const tmpVec2 = new Vector3();
const tmpQuat1 = new Quaternion();
@@ -45,18 +44,6 @@ function transformMenu(world: HubsWorld, menu: EntityID) {
if (!targetObj || !enabled) return;
const menuObj = world.eid2obj.get(menu)!;
-
- // Calculate the menu offset based on visible elements
- const center = (ObjectMenuTransform.flags[menu] & ObjectMenuTransformFlags.Center) !== 0 ? true : false;
- if (center && ObjectMenuTransform.targetObjectRef[menu] !== ObjectMenuTransform.prevObjectRef[menu]) {
- getAABB(menuObj, aabb);
- aabb.getCenter(tmpVec1);
- getAABB(menuObj, aabb, true);
- aabb.getCenter(tmpVec2);
- offset.subVectors(tmpVec1, tmpVec2);
- offset.z = 0;
- }
-
const camera = APP.scene?.systems["hubs-systems"].cameraSystem.viewingCamera;
camera.updateMatrices();
@@ -75,11 +62,6 @@ function transformMenu(world: HubsWorld, menu: EntityID) {
menuObj.lookAt(tmpVec2.setFromMatrixPosition(camera.matrixWorld));
menuObj.translateZ(sphere.radius);
- if (center) {
- menuObj.position.add(offset);
- menuObj.matrixNeedsUpdate = true;
- }
-
// TODO We need to handle the menu positioning when the player is inside the bounding sphere.
// For now we are defaulting to the current AFrame behavior.
} else {
@@ -102,11 +84,6 @@ function transformMenu(world: HubsWorld, menu: EntityID) {
tmpMat4.multiply(tmpMat42);
}
- if (center) {
- tmpMat42.makeTranslation(offset.x, offset.y, offset.z);
- tmpMat4.multiply(tmpMat42);
- }
-
setMatrixWorld(menuObj, tmpMat4);
}
ObjectMenuTransform.prevObjectRef[menu] = ObjectMenuTransform.targetObjectRef[menu];
diff --git a/src/bit-systems/object-menu.ts b/src/bit-systems/object-menu.ts
index adc20f7ab4..0b181e8835 100644
--- a/src/bit-systems/object-menu.ts
+++ b/src/bit-systems/object-menu.ts
@@ -46,6 +46,7 @@ import { ObjectMenuTransformFlags } from "../inflators/object-menu-transform";
import { COLLISION_LAYERS } from "../constants";
import { FLOATY_OBJECT_FLAGS } from "../systems/floaty-object-system";
import { INSPECTABLE_FLAGS } from "./inspect-system";
+import { ObjectMenuPositions } from "../prefabs/object-menu";
// Working variables.
const _vec3_1 = new Vector3();
const _vec3_2 = new Vector3();
@@ -282,26 +283,62 @@ function updateVisibility(world: HubsWorld, menu: EntityID, frozen: boolean) {
const media = MediaLoader.mediaRef[target];
const isVideoImagePdf = hasAnyComponent(world, [MediaVideo, MediaImage, MediaPDF], media);
const isMirrored = hasComponent(world, MediaMirrored, target);
+ const isDropped = hasComponent(world, ObjectDropped, target);
const isInspectable = hasComponent(world, Inspectable, target);
const isInspected = hasComponent(world, Inspected, target);
const isRefreshing = hasComponent(world, MediaRefresh, target);
- // Parent visibility doesn't block raycasting, so we must set each button to be invisible
- // TODO: Ensure that children of invisible entities aren't raycastable
- world.eid2obj.get(ObjectMenu.unpinButtonRef[menu])!.visible = visible && isEntityPinned && canIPin;
- world.eid2obj.get(ObjectMenu.pinButtonRef[menu])!.visible = visible && !isEntityPinned && canIPin;
- world.eid2obj.get(ObjectMenu.removeButtonRef[menu])!.visible = visible && !isEntityPinned && canISpawnMove;
- world.eid2obj.get(ObjectMenu.cloneButtonRef[menu])!.visible = visible && canISpawnMove;
- world.eid2obj.get(ObjectMenu.rotateButtonRef[menu])!.visible =
- visible && (!isEntityPinned || canIPin) && canISpawnMove;
- world.eid2obj.get(ObjectMenu.scaleButtonRef[menu])!.visible =
- visible && (!isEntityPinned || canIPin) && canISpawnMove;
- world.eid2obj.get(ObjectMenu.openLinkButtonRef[menu])!.visible = visible;
- world.eid2obj.get(ObjectMenu.dropButtonRef[menu])!.visible =
- !isVideoImagePdf && !isEntityPinned && !hasComponent(world, ObjectDropped, target);
- world.eid2obj.get(ObjectMenu.mirrorButtonRef[menu])!.visible = isVideoImagePdf && !isMirrored;
- world.eid2obj.get(ObjectMenu.inspectButtonRef[menu])!.visible = isVideoImagePdf && isInspectable && !isInspected;
- world.eid2obj.get(ObjectMenu.refreshButtonRef[menu])!.visible = visible && canIPin && canISpawnMove && !isRefreshing;
+ const openLinkButtonObj = world.eid2obj.get(ObjectMenu.openLinkButtonRef[menu])!;
+ const mirrorButtonObj = world.eid2obj.get(ObjectMenu.mirrorButtonRef[menu])!;
+ const inspectButtonObj = world.eid2obj.get(ObjectMenu.inspectButtonRef[menu])!;
+ const refreshButtonObj = world.eid2obj.get(ObjectMenu.refreshButtonRef[menu])!;
+
+ openLinkButtonObj.visible = visible;
+ mirrorButtonObj.visible = visible && isVideoImagePdf && !isMirrored;
+ inspectButtonObj.visible = visible && isInspectable && !isInspected;
+ refreshButtonObj.visible = visible && !isRefreshing;
+
+ if (canISpawnMove) {
+ world.eid2obj.get(ObjectMenu.unpinButtonRef[menu])!.visible = visible && isEntityPinned && canIPin;
+ world.eid2obj.get(ObjectMenu.pinButtonRef[menu])!.visible = visible && !isEntityPinned && canIPin;
+ world.eid2obj.get(ObjectMenu.removeButtonRef[menu])!.visible = visible && !isEntityPinned;
+ world.eid2obj.get(ObjectMenu.cloneButtonRef[menu])!.visible = visible;
+ world.eid2obj.get(ObjectMenu.rotateButtonRef[menu])!.visible = visible && (!isEntityPinned || canIPin);
+ world.eid2obj.get(ObjectMenu.scaleButtonRef[menu])!.visible = visible && (!isEntityPinned || canIPin);
+ world.eid2obj.get(ObjectMenu.dropButtonRef[menu])!.visible =
+ visible && !isVideoImagePdf && !isEntityPinned && !isDropped;
+
+ openLinkButtonObj.position.fromArray(ObjectMenuPositions.openLink);
+ mirrorButtonObj.position.fromArray(ObjectMenuPositions.mirror);
+ if (isEntityPinned) {
+ inspectButtonObj.position.fromArray(ObjectMenuPositions.inspectP);
+ } else {
+ inspectButtonObj.position.fromArray(ObjectMenuPositions.inspect);
+ }
+ refreshButtonObj.position.fromArray(ObjectMenuPositions.refresh);
+ } else {
+ [
+ ObjectMenu.unpinButtonRef[menu],
+ ObjectMenu.pinButtonRef[menu],
+ ObjectMenu.removeButtonRef[menu],
+ ObjectMenu.cloneButtonRef[menu],
+ ObjectMenu.rotateButtonRef[menu],
+ ObjectMenu.scaleButtonRef[menu],
+ ObjectMenu.dropButtonRef[menu]
+ ].forEach(ref => {
+ world.eid2obj.get(ref)!.visible = false;
+ });
+
+ openLinkButtonObj.position.fromArray(ObjectMenuPositions.openLinkU);
+ mirrorButtonObj.position.fromArray(ObjectMenuPositions.mirrorU);
+ inspectButtonObj.position.fromArray(ObjectMenuPositions.inspectU);
+ refreshButtonObj.position.fromArray(ObjectMenuPositions.refreshU);
+ }
+
+ openLinkButtonObj.matrixNeedsUpdate = true;
+ mirrorButtonObj.matrixNeedsUpdate = true;
+ inspectButtonObj.matrixNeedsUpdate = true;
+ refreshButtonObj.matrixNeedsUpdate = true;
// This is a hacky way of giving a chance to the object-menu-transform system to center the menu based on the
// visible buttons without accounting for the background plane.
diff --git a/src/inflators/object-menu-transform.ts b/src/inflators/object-menu-transform.ts
index 7f8cb3c099..ccb31f667a 100644
--- a/src/inflators/object-menu-transform.ts
+++ b/src/inflators/object-menu-transform.ts
@@ -5,8 +5,7 @@ import { ObjectMenuTransform } from "../bit-components";
export const ObjectMenuTransformFlags = {
Enabled: 1 << 0,
- Center: 1 << 1,
- Scale: 1 << 2
+ Scale: 1 << 1
};
export type ObjectMenuTransformParams = {
@@ -21,9 +20,6 @@ const DEFAULTS = {
export function inflateObjectMenuTransform(world: HubsWorld, eid: EntityID, params: ObjectMenuTransformParams) {
params = Object.assign({}, DEFAULTS, params);
addComponent(world, ObjectMenuTransform, eid);
- if (params.center === true) {
- ObjectMenuTransform.flags[eid] |= ObjectMenuTransformFlags.Center;
- }
if (params.scale === true) {
ObjectMenuTransform.flags[eid] |= ObjectMenuTransformFlags.Scale;
}
diff --git a/src/prefabs/object-menu.tsx b/src/prefabs/object-menu.tsx
index 1198f51fbd..eb1dcc4ec1 100644
--- a/src/prefabs/object-menu.tsx
+++ b/src/prefabs/object-menu.tsx
@@ -123,6 +123,7 @@ function InspectButton(props: Attrs) {
height={buttonHeight}
type={BUTTON_TYPES.DEFAULT}
holdable
+ holdableButton
icon={{ texture, cacheKey, scale: [0.165, 0.165, 0.165] }}
{...props}
/>
@@ -195,6 +196,7 @@ function RotateButton(props: Attrs) {
height={buttonHeight}
type={BUTTON_TYPES.ACTION}
holdable
+ holdableButton
icon={{ texture, cacheKey, scale: [0.165, 0.165, 0.165] }}
{...props}
/>
@@ -226,6 +228,7 @@ function ScaleButton(props: Attrs) {
height={buttonHeight}
type={BUTTON_TYPES.ACTION}
holdable
+ holdableButton
icon={{ texture, cacheKey, scale: [0.165, 0.165, 0.165] }}
{...props}
/>
@@ -233,22 +236,27 @@ function ScaleButton(props: Attrs) {
}
// prettier-ignore
-const position = {
+export const ObjectMenuPositions = {
background: [ 0, 0, uiZ - 0.0005] as ArrayVec3,
- pin: [ 0, 0.125, uiZ] as ArrayVec3,
- 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.275, uiZ] as ArrayVec3,
- drop: [ 0, -0.425, uiZ] as ArrayVec3,
- inspect: [ 0, -0.425, uiZ] as ArrayVec3,
- deserializeDrawing: [ -0.3, -0.625, uiZ] as ArrayVec3,
- openLink: [ 0.25, -0.275, uiZ] as ArrayVec3,
- refresh: [ 0.25, -0.425, 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.2, -0.125, uiZ] as ArrayVec3,
+ pin: [ 0, 0.225, uiZ] as ArrayVec3,
+ unpin: [ 0, 0.225, uiZ] as ArrayVec3,
+ focus: [-0.25, 0.575, uiZ] as ArrayVec3,
+ track: [ 0.25, 0.575, uiZ] as ArrayVec3,
+ remove: [ 0, -0.075, uiZ] as ArrayVec3,
+ drop: [ 0, -0.225, uiZ] as ArrayVec3,
+ inspect: [ 0, -0.225, uiZ] as ArrayVec3,
+ inspectU: [ 0, 0.075, uiZ] as ArrayVec3,
+ inspectP: [ 0, -0.075, uiZ] as ArrayVec3,
+ deserializeDrawing: [ -0.3, -0.425, uiZ] as ArrayVec3,
+ openLink: [ 0.25, -0.075, uiZ] as ArrayVec3,
+ openLinkU: [ 0, -0.075, uiZ] as ArrayVec3,
+ refresh: [ 0.25, -0.225, uiZ] as ArrayVec3,
+ refreshU: [ 0, -0.225, uiZ] as ArrayVec3,
+ clone: [-0.25, -0.075, uiZ] as ArrayVec3,
+ rotate: [ -0.2, 0.075, uiZ] as ArrayVec3,
+ mirror: [ 0, 0.075, uiZ] as ArrayVec3,
+ mirrorU: [ 0, 0.225, uiZ] as ArrayVec3,
+ scale: [ 0.2, 0.075, uiZ] as ArrayVec3,
};
export function ObjectMenuPrefab() {
@@ -273,7 +281,7 @@ export function ObjectMenuPrefab() {
return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
-
-// ui interactable-ui
-// layers mask 768
-// withPermission: spawn_and_move_media
-
-// pinButtonTip: Pinning will broadcast this object to Discord.
-
-// sprite camera-action.png
-// cameraFocusLabel focus
-
-// sprite camera-action.png
-// cameraTrackLabel track
-
-// sprite remove-action.png
-//
-
-// visibility on content types:
-// "contentTypes: video/ audio/ image/ application/vnd.apple.mpegurl application/x-mpegurl application/pdf; visible: false;"
-// sprite drop-action.png
-// hide-when-pinned-and-forbidden
-
-// holdable
-// sprite focus-action.png
-// visibility-on-content-types="contentTypes: video/ audio/ image/ application/vnd.apple.mpegurl application/x-mpegurl application/pdf;"
-
-// sprite deserialize-action.png
-// class="deserialize-drawing" : lookup what else is using this
-
-// text: open link
-
-// text: refresh
-
-// text: clone
-
-// sprite: rotate-action.png
-// hide-when-pinned-and-forbidden
-
-// sprite: inspect-action.png
-// visibility-on-content-types="contentTypes: video/ audio/ image/ application/vnd.apple.mpegurl application/x-mpegurl application/pdf;"
-
-// sprite: scale-action.png
-// hide-when-pinned-and-forbidden
-
-// unprivileged menu...
-// refreshButton
-// openLinkButton
-// mirrorMediaButton
-// inspectButton
diff --git a/src/prefabs/pdf-menu.tsx b/src/prefabs/pdf-menu.tsx
index 6b87d72573..ef2f1da72b 100644
--- a/src/prefabs/pdf-menu.tsx
+++ b/src/prefabs/pdf-menu.tsx
@@ -61,7 +61,7 @@ export function PDFMenuPrefab() {
return (