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 Jan 30, 2023
1 parent bcb4277 commit 1516b93
Show file tree
Hide file tree
Showing 4 changed files with 61 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 @@ -199,3 +199,4 @@ export const Billboard = defineComponent({
onlyY: Types.ui8
});
export const SimpleWater = defineComponent();
export const Mirror = defineComponent();
51 changes: 51 additions & 0 deletions src/inflators/mirror.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
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();
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 @@ -7,6 +7,7 @@ import {
MediaImage,
MediaFrame,
MediaVideo,
Mirror,
Object3DTag,
Slice9,
Text,
Expand Down Expand Up @@ -73,6 +74,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 @@ -127,6 +129,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(removeFromMap);
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 @@ -34,7 +34,8 @@ import {
NetworkDebug,
WaypointPreview,
NetworkedFloatyObject,
Billboard
Billboard,
Mirror
} from "../bit-components";
import { inflateMediaLoader } from "../inflators/media-loader";
import { inflateMediaFrame } from "../inflators/media-frame";
Expand Down Expand Up @@ -66,6 +67,7 @@ import { ProjectionMode } from "./projection-mode";
import { inflateSkybox, SkyboxParams } from "../inflators/skybox";
import { inflateSpawner, SpawnerParams } from "../inflators/spawner";
import { SimpleWaterParams, inflateSimpleWater } from "../inflators/simple-water";
import { MirrorParams, inflateMirror } from "../inflators/mirror";

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

export interface JSXComponentData extends ComponentData {
Expand Down Expand Up @@ -344,7 +347,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 1516b93

Please sign in to comment.