diff --git a/packages/player/src/player.tsx b/packages/player/src/player.tsx index f2e1693a1c0c5a00a45b8fe74c62c153f75ebb84..4f666b4587fde4d4875f18ae9411541b023eaeee 100644 --- a/packages/player/src/player.tsx +++ b/packages/player/src/player.tsx @@ -19,6 +19,7 @@ class FTLFrameset { export interface FTLPlayer extends Emitter {}; export class FTLPlayer { + running = true; framesets = {}; handlers = {}; private outer: HTMLElement; @@ -135,6 +136,8 @@ export class FTLPlayer { console.log('INIT XR'); const nav = (navigator as unknown) as Navigator; + //this.renderer.setSize( window.innerWidth, window.innerHeight ); + const onRequestSession = () => { // Requests an 'immersive-ar' session, which ensures that the users // environment will be visible either via video passthrough or a @@ -145,7 +148,7 @@ export class FTLPlayer { this.renderer.xr.setSession(session as THREE.XRSession); this.renderer.xr.enabled = true; // @ts-ignore - this.renderer.xr.cameraAutoUpdate = false; + //this.renderer.xr.cameraAutoUpdate = false; onSessionStarted(session as XRSession); }); } @@ -153,12 +156,14 @@ export class FTLPlayer { const onSessionStarted = (session: XRSession) => { session.addEventListener('end', onSessionEnded); - session.requestReferenceSpace('local').then((refSpace) => { - this.xrImmersiveRefSpace = refSpace; - //session.requestAnimationFrame(onXRFrame); + //session.requestReferenceSpace('local').then((refSpace) => { + //this.xrImmersiveRefSpace = refSpace; this.renderer.xr.setAnimationLoop(onXRFrame); this.renderer.xr.getCamera = () => this.camera; - }); + //const size = new THREE.Vector2(); + //this.renderer.getDrawingBufferSize(size); + //console.log('Render size', size); + //}); } const onSessionEnded = (event) => { @@ -166,20 +171,9 @@ export class FTLPlayer { } const onXRFrame = (t, frame) => { - let session = frame.session; - let pose = frame.getViewerPose(this.renderer.xr.getReferenceSpace()); - //console.log('POSES', pose.views.length); - const transform = pose.views[1].transform; - const position = transform.position; - const orientation = transform.orientation; - this.cameraObject.translateX = position.x; - this.cameraObject.translateY = position.y; - this.cameraObject.translateZ = -position.z; - this.cameraObject.rotationX = orientation.x * 57.3; - this.cameraObject.rotationY = orientation.y * 57.3; - this.cameraObject.rotationZ = orientation.z * 57.3; - this.updatePose(); - //session.requestAnimationFrame(onXRFrame); + const pose = frame.getViewerPose(this.renderer.xr.getReferenceSpace()); + const transform = pose.views[0].transform; + this.emit('pose', Array.from(transform.matrix)); this._update(); } @@ -249,6 +243,7 @@ export class FTLPlayer { }); const animate = () => { + if (!this.running) return; requestAnimationFrame( animate ); this._update(); } @@ -297,6 +292,13 @@ export class FTLPlayer { }); } + stop() { + this.running = false; + if (this.renderer.xr.enabled) { + this.renderer.xr.getSession().end(); + } + } + pause() { this.element.pause(); } diff --git a/packages/player/src/react.tsx b/packages/player/src/react.tsx index e46c2e03ac0e94ab086c71633b211be826857f3d..ccc532c9b2cab4e7a14f1006ab269b221ecca562 100644 --- a/packages/player/src/react.tsx +++ b/packages/player/src/react.tsx @@ -77,6 +77,11 @@ export function ReactPlayer({stream, channel, movement, onSelectPoint, points, i }); state.player.play(); + + return () => { + stream.stop(); + state.player.stop(); + } }, []); useEffect(() => { diff --git a/packages/socket-service/src/source.ts b/packages/socket-service/src/source.ts index 69c11d21c2d44ff8c1c4d594bd192cd6c7054cd4..f1fc7e93d4c42a4b370e612d694969ad04bd512b 100644 --- a/packages/socket-service/src/source.ts +++ b/packages/socket-service/src/source.ts @@ -5,7 +5,7 @@ import { AccessToken } from '@ftl/types'; import { redisSetStreamCallback } from '@ftl/common'; import { sendNodeUpdateEvent, sendNodeStatsEvent } from '@ftl/api'; import { - removeStreams, getStreams, bindToStream, createStream, initStream, startStream, + removeStreams, getStreams, bindToStream, createStream, initStream, startStream, unbindFromStream, } from './streams'; const peerData = []; @@ -126,7 +126,7 @@ export function createSource(ws, address: string, token: AccessToken, ephemeral: p.bind('enable_stream', (uri: string, frameset: number, frame: number) => bindToStream(p, uri)); // eslint-disable-next-line no-unused-vars - p.bind('disable_stream', (uri: string, frameset: number, frame: number) => true); + p.bind('disable_stream', (uri: string, frameset: number, frame: number) => unbindFromStream(p, uri)); // eslint-disable-next-line no-unused-vars p.bind('create_stream', (uri: string, frameset: number, frame: number) => { diff --git a/packages/socket-service/src/streams.ts b/packages/socket-service/src/streams.ts index 9dea59e141117ae5e867ad44e0e3f0d8112aae93..42ac9a203298cf45b6cc9a8cb5d307ad6f425ee4 100644 --- a/packages/socket-service/src/streams.ts +++ b/packages/socket-service/src/streams.ts @@ -58,6 +58,19 @@ export async function bindToStream(p: Peer, uri: string) { return null; } +export async function unbindFromStream(p: Peer, uri: string) { + const parsedURI = removeQueryString(uri); + + if (p.isBound(parsedURI)) { + console.log('Removing local stream binding: ', parsedURI); + outputStreams.get(p.uri).destroy(); + outputStreams.delete(p.uri); + p.unbind(parsedURI); + } + + return [Peer.uuid]; +} + export function removeStreams(peer: Peer) { if (outputStreams.has(peer.uri)) { const os = outputStreams.get(peer.uri); diff --git a/packages/stream/src/stream.ts b/packages/stream/src/stream.ts index 006add719a9dfa0e631dbee8aa9122cf7c7f9d68..38a2e0139017afa27808f5bbb08c46bcaf1afa30 100644 --- a/packages/stream/src/stream.ts +++ b/packages/stream/src/stream.ts @@ -138,7 +138,7 @@ export class FTLStream { this.interval = null; } if (this.found) { - this.peer.rpc("disable_stream", () => {}); + this.peer.rpc("disable_stream", () => {}, this.uri); this.peer.unbind(this.uri); this.found = false; }