Skip to content

Commit

Permalink
Added scene viewer.
Browse files Browse the repository at this point in the history
  • Loading branch information
ffrank913 committed Nov 29, 2024
1 parent 7bff77f commit 8e74e2f
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 2 deletions.
98 changes: 98 additions & 0 deletions src/ar/AR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ export class DIVEAR {
private _scene: DIVEScene;
private _controller: DIVEOrbitControls;

private arPlacement: string = 'floor';
private arScale: string = 'auto';

constructor(
renderer: DIVERenderer,
scene: DIVEScene,
Expand Down Expand Up @@ -38,6 +41,9 @@ export class DIVEAR {
}

if (system === 'Android') {
this.openSceneViewer();
return;

const support = await DIVEInfo.GetSupportsWebXR();
if (!support) {
console.log(
Expand All @@ -63,4 +69,96 @@ export class DIVEAR {
'AR not supported. Not a mobile system. (System is ' + system + ')',
);
}

private openSceneViewer(): void {
const src = this.createSceneViewerSrc();
const anchor = document.createElement('a');
const noArViewerSigil = '#model-viewer-no-ar-fallback';
// let isSceneViewerBlocked = false;

const location = self.location.toString();
const locationUrl = new URL(location);
const modelUrl = new URL(src, location);
if (modelUrl.hash) modelUrl.hash = '';
const params = new URLSearchParams(modelUrl.search);

locationUrl.hash = noArViewerSigil;

// modelUrl can contain title/link/sound etc.
params.set('mode', 'ar_preferred');
if (!params.has('disable_occlusion')) {
params.set('disable_occlusion', 'true');
}
if (this.arScale === 'fixed') {
params.set('resizable', 'false');
}
if (this.arPlacement === 'wall') {
params.set('enable_vertical_placement', 'true');
}
if (params.has('sound')) {
const soundUrl = new URL(params.get('sound')!, location);
params.set('sound', soundUrl.toString());
}
if (params.has('link')) {
const linkUrl = new URL(params.get('link')!, location);
params.set('link', linkUrl.toString());
}

console.log('modelUrl.toString()', modelUrl.toString());
console.log(
'encodeURIComponent(modelUrl.toString())',
encodeURIComponent(modelUrl.toString()),
);

let intent = `intent://arvr.google.com/scene-viewer/1.2?${
params.toString() + '&file=' + modelUrl.toString()
}#Intent;scheme=https;package=com.google.android.googlequicksearchbox;action=android.intent.action.VIEW;S.browser_fallback_url=${encodeURIComponent(
locationUrl.toString(),
)};end;`;
// intent =
// 'intent://arvr.google.com/scene-viewer/1.0?file=https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/Avocado/glTF/Avocado.gltf#Intent;scheme=https;package=com.google.android.googlequicksearchbox;action=android.intent.action.VIEW;S.browser_fallback_url=https://developers.google.com/ar;end;';
console.log({ intent });

const undoHashChange = (): void => {
if (self.location.hash === noArViewerSigil) {
// isSceneViewerBlocked = true;
// The new history will be the current URL with a new hash.
// Go back one step so that we reset to the expected URL.
// NOTE(cdata): this should not invoke any browser-level navigation
// because hash-only changes modify the URL in-place without
// navigating:
self.history.back();
console.warn(
'Error while trying to present in AR with Scene Viewer',
);
console.warn('Falling back to next ar-mode');
// this[$selectARMode]();
// Would be nice to activateAR() here, but webXR fails due to not
// seeing a user activation.
}
};

self.addEventListener('hashchange', undoHashChange, { once: true });

anchor.setAttribute('href', intent);
console.log('Attempting to present in AR with Scene Viewer...');
anchor.click();
}

private createSceneViewerSrc(): string {
let uri: string | null = null;

this._scene.traverse((object) => {
if (uri) return;
if (object.userData.uri) {
uri = object.userData.uri;
}
});

if (!uri) {
throw new Error('No model found in scene');
}

return uri;
}
}
7 changes: 5 additions & 2 deletions src/dive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,11 @@ export const DIVEDefaultSettings: DIVESettings = {

export default class DIVE {
// static members
public static QuickView(uri: string): DIVE {
const dive = new DIVE();
public static QuickView(
uri: string,
settings?: Partial<DIVESettings>,
): DIVE {
const dive = new DIVE(settings);

dive.Communication.PerformAction('SET_CAMERA_TRANSFORM', {
position: { x: 0, y: 2, z: 2 },
Expand Down
1 change: 1 addition & 0 deletions src/scene/root/Root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ export class DIVERoot extends Object3D {
const created = new DIVEModel();
sceneObject = created;
sceneObject.userData.id = model.id;
sceneObject.userData.uri = model.uri;
this.add(sceneObject);
}

Expand Down

0 comments on commit 8e74e2f

Please sign in to comment.