Skip to content

Commit

Permalink
Add Mirror to bitecs
Browse files Browse the repository at this point in the history
  • Loading branch information
takahirox committed Feb 3, 2023
1 parent 6672f85 commit 73dd914
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/bit-components.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,4 @@ export const VideoTextureTarget = defineComponent({
flags: Types.ui8
});
export const SimpleWater = defineComponent();
export const Mirror = defineComponent();
53 changes: 53 additions & 0 deletions src/inflators/mirror.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { addComponent } from "bitecs";
import { PlaneGeometry } from "three";
import { Reflector } from "three/examples/jsm/objects/Reflector";
import { addObject3DComponent } from "../utils/jsx-entity";
import { Mirror } from "../bit-components";
import { HubsWorld } from "../app";
import { Layers } from "../camera-layers";

const DEFAULT_MIRROR_GEOMETRY = new PlaneGeometry();
// We may need to revisit the default texture size
// because the full window resolution may be too huge.
const DEFAULT_TEXTURE_WIDTH = window.innerWidth * window.devicePixelRatio;
const DEFAULT_TEXTURE_HEIGHT = window.innerHeight * window.devicePixelRatio;

export type MirrorParams = {
color?: string;
};

const DEFAULTS = {
color: '#7f7f7f'
};

export function inflateMirror(world: HubsWorld, eid: number, params: MirrorParams) {
params = Object.assign({}, DEFAULTS, params);
const geometry = DEFAULT_MIRROR_GEOMETRY;
const reflector = new Reflector(geometry, {
color: params.color,
textureWidth: DEFAULT_TEXTURE_WIDTH,
textureHeight: DEFAULT_TEXTURE_HEIGHT
});

// HACK the first time we render this, add the appropriate camera layers
// to the virtual camera. There is no other way to easily access camera
// used for Reflector. We may remove with Three.js r149 or newer because
// Reflector will expose camera.
const originalOnBeforeRender = reflector.onBeforeRender;
reflector.onBeforeRender = function (renderer, scene, camera, geometry, material, group) {
const originalRender = renderer.render;
renderer.render = function (scene, camera) {
camera.layers.enable(Layers.CAMERA_LAYER_THIRD_PERSON_ONLY);
camera.layers.enable(Layers.CAMERA_LAYER_VIDEO_TEXTURE_TARGET);
reflector.onBeforeRender = originalOnBeforeRender;
originalRender.call(renderer, scene, camera);
};
originalOnBeforeRender(renderer, scene, camera, geometry, material, group);
renderer.render = originalRender;
};

addObject3DComponent(world, eid, reflector);
addComponent(world, Mirror, eid);
return eid;
}

3 changes: 3 additions & 0 deletions src/systems/remove-object3D-system.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
MediaFrame,
MediaImage,
MediaVideo,
Mirror,
Object3DTag,
SimpleWater,
Skybox,
Expand Down Expand Up @@ -74,6 +75,7 @@ const cleanupSimpleWaters = cleanupObjOnExit(SimpleWater, obj => {
obj.material.dispose();
}
});
const cleanupMirrors = cleanupObjOnExit(Mirror, obj => obj.dispose());

// TODO This feels messy and brittle
//
Expand Down Expand Up @@ -135,6 +137,7 @@ export function removeObject3DSystem(world) {
cleanupAudioEmitters(world);
cleanupSkyboxes(world);
cleanupSimpleWaters(world);
cleanupMirrors(world);

// Finally remove all the entities we just removed from the eid2obj map
entities.forEach(removeObjFromMap);
Expand Down
8 changes: 6 additions & 2 deletions src/utils/jsx-entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ import {
NetworkedFloatyObject,
Billboard,
MaterialTag,
VideoTextureSource
VideoTextureSource,
Mirror
} from "../bit-components";
import { inflateMediaLoader } from "../inflators/media-loader";
import { inflateMediaFrame } from "../inflators/media-frame";
Expand Down Expand Up @@ -73,6 +74,7 @@ import { inflateVideoTextureTarget, VideoTextureTargetParams } from "../inflator
import { inflateUVScroll, UVScrollParams } from "../inflators/uv-scroll";
import { SimpleWaterParams, inflateSimpleWater } from "../inflators/simple-water";
import { inflatePDF, PDFParams } from "../inflators/pdf";
import { MirrorParams, inflateMirror } from "../inflators/mirror";

preload(
new Promise(resolve => {
Expand Down Expand Up @@ -225,6 +227,7 @@ export interface ComponentData {
grabbable?: GrabbableParams;
billboard?: { onlyY: boolean };
simpleWater?: SimpleWaterParams;
mirror?: MirrorParams;
}

export interface JSXComponentData extends ComponentData {
Expand Down Expand Up @@ -366,7 +369,8 @@ export const commonInflators: Required<{ [K in keyof ComponentData]: InflatorFn

// inflators that create Object3Ds
directionalLight: inflateDirectionalLight,
simpleWater: inflateSimpleWater
simpleWater: inflateSimpleWater,
mirror: inflateMirror
};

const jsxInflators: Required<{ [K in keyof JSXComponentData]: InflatorFn }> = {
Expand Down

0 comments on commit 73dd914

Please sign in to comment.