Skip to content

Commit

Permalink
Add a raycastable menu background
Browse files Browse the repository at this point in the history
  • Loading branch information
keianhzo committed Oct 23, 2023
1 parent 5711df6 commit 70be1cf
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/bit-components.js
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ EnvironmentSettings.map = new Map();

// TODO: Store this data elsewhere, since only one or two will ever exist.
export const ObjectMenu = defineComponent({
backgroundRef: Types.eid,
pinButtonRef: Types.eid,
unpinButtonRef: Types.eid,
cameraFocusButtonRef: Types.eid,
Expand Down
5 changes: 5 additions & 0 deletions src/bit-systems/object-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,11 @@ function updateVisibility(world: HubsWorld, menu: EntityID, frozen: boolean) {
world.eid2obj.get(ObjectMenu.scaleButtonRef[menu])!.visible = visible && APP.hubChannel!.can("spawn_and_move_media");
world.eid2obj.get(ObjectMenu.openLinkButtonRef[menu])!.visible = visible;

// 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.
const same = ObjectMenuTransform.prevObjectRef[menu] === ObjectMenuTransform.targetObjectRef[menu];
world.eid2obj.get(ObjectMenu.backgroundRef[menu])!.visible = visible && same;

// Hide unimplemented features for now.
// TODO: Implement and show the buttons.
world.eid2obj.get(ObjectMenu.cameraFocusButtonRef[menu])!.visible = false;
Expand Down
37 changes: 37 additions & 0 deletions src/inflators/plane.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { addObject3DComponent } from "../utils/jsx-entity";
import { HubsWorld } from "../app";
import { EntityID } from "../utils/networking-types";
import { Mesh, MeshBasicMaterial, PlaneGeometry } from "three";

const MATERIAL_DEFAULTS = {
color: "#000000",
opacity: 1,
transparent: false
};

const PLANE_DEFAULTS = {
width: 1,
height: 1,
material: MATERIAL_DEFAULTS
};

export interface MeshBasicMaterialParams {
color?: string;
opacity?: number;
transparent?: boolean;
}

export interface PlaneParams {
width?: number;
height?: number;
material?: MeshBasicMaterialParams;
}

export function inflatePlane(world: HubsWorld, eid: EntityID, params: PlaneParams) {
params = Object.assign({}, PLANE_DEFAULTS, params);
params.material = Object.assign({}, MATERIAL_DEFAULTS, params.material);
const geometry = new PlaneGeometry(params.width, params.height);
const material = new MeshBasicMaterial({ ...params.material });
const obj = new Mesh(geometry, material);
addObject3DComponent(world, eid, obj);
}
12 changes: 12 additions & 0 deletions src/prefabs/object-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ 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";
import { Plane } from "./plane";

export async function loadObjectMenuButtonIcons() {
return Promise.all([
Expand Down Expand Up @@ -221,6 +222,7 @@ function ScaleButton(props: Attrs) {

// prettier-ignore
const position = {
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,
Expand All @@ -239,6 +241,7 @@ const position = {

export function ObjectMenuPrefab() {
const refs = {
background: createRef(),
pin: createRef(),
unpin: createRef(),
focus: createRef(),
Expand All @@ -260,6 +263,7 @@ export function ObjectMenuPrefab() {
name="Interactable Object Menu"
objectMenuTransform={{ center: true }}
objectMenu={{
backgroundRef: refs.background,
pinButtonRef: refs.pin,
unpinButtonRef: refs.unpin,
cameraFocusButtonRef: refs.focus,
Expand All @@ -276,6 +280,14 @@ export function ObjectMenuPrefab() {
scaleButtonRef: refs.scale
}}
>
<Plane
name={"Background"}
ref={refs.background}
position={position.background}
width={0.8}
height={0.8}
material={{ transparent: true, opacity: 0 }}
/>
<PinButton ref={refs.pin} position={position.pin} />
<UnpinButton ref={refs.unpin} position={position.unpin} />
<CameraFocusButton ref={refs.focus} position={position.focus} />
Expand Down
19 changes: 19 additions & 0 deletions src/prefabs/plane.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/** @jsx createElementEntity */
import { Attrs, createElementEntity } from "../utils/jsx-entity";

export interface PlaneParams extends Attrs {
width?: number;
height?: number;
material?: MeshBasicMaterialParams;
}

export interface MeshBasicMaterialParams extends Attrs {
color?: string;
opacity?: number;
transparent?: boolean;
// TODO Add the rest of the material properties
}

export function Plane({ width, height, material, name = "Plane", ...props }: PlaneParams) {
return <entity name={name} cursorRaycastable plane={{ width, height, material }} {...props} />;
}
6 changes: 5 additions & 1 deletion src/utils/jsx-entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ import { HubsVideoTexture } from "../textures/HubsVideoTexture";
import { inflateMediaLink, MediaLinkParams } from "../inflators/media-link";
import { inflateObjectMenuTarget, ObjectMenuTargetParams } from "../inflators/object-menu-target";
import { inflateObjectMenuTransform, ObjectMenuTransformParams } from "../inflators/object-menu-transform";
import { inflatePlane, PlaneParams } from "../inflators/plane";

preload(
new Promise(resolve => {
Expand Down Expand Up @@ -314,6 +315,7 @@ export interface JSXComponentData extends ComponentData {
networkedFloatyObject?: any;
networkedTransform?: any;
objectMenu?: {
backgroundRef: Ref;
pinButtonRef: Ref;
unpinButtonRef: Ref;
cameraFocusButtonRef: Ref;
Expand Down Expand Up @@ -365,6 +367,7 @@ export interface JSXComponentData extends ComponentData {
inspectable?: boolean;
objectMenuTransform?: OptionalParams<ObjectMenuTransformParams>;
objectMenuTarget?: OptionalParams<ObjectMenuTargetParams>;
plane?: PlaneParams;
}

export interface GLTFComponentData extends ComponentData {
Expand Down Expand Up @@ -480,7 +483,8 @@ const jsxInflators: Required<{ [K in keyof JSXComponentData]: InflatorFn }> = {
video: inflateVideo,
link: inflateLink,
objectMenuTransform: inflateObjectMenuTransform,
objectMenuTarget: inflateObjectMenuTarget
objectMenuTarget: inflateObjectMenuTarget,
plane: inflatePlane
};

export const gltfInflators: Required<{ [K in keyof GLTFComponentData]: InflatorFn }> = {
Expand Down

0 comments on commit 70be1cf

Please sign in to comment.