From b08383e8be024b02eef1645d0dd1f83d52e2a381 Mon Sep 17 00:00:00 2001 From: Paul Brachmann Date: Thu, 15 Jul 2021 13:55:31 +0200 Subject: [PATCH 1/8] Disable hit-test --- apps/ar-demo/src/constants.ts | 2 ++ apps/ar-demo/src/lib/renderer/renderer.ts | 30 ++++++++++++++--------- 2 files changed, 21 insertions(+), 11 deletions(-) create mode 100644 apps/ar-demo/src/constants.ts diff --git a/apps/ar-demo/src/constants.ts b/apps/ar-demo/src/constants.ts new file mode 100644 index 000000000..e95b5d40e --- /dev/null +++ b/apps/ar-demo/src/constants.ts @@ -0,0 +1,2 @@ +// TODO: Auto-detect if `hit-test` feature is available +export const USE_HIT_TEST = false; diff --git a/apps/ar-demo/src/lib/renderer/renderer.ts b/apps/ar-demo/src/lib/renderer/renderer.ts index c376cd9ee..21bd67dd9 100644 --- a/apps/ar-demo/src/lib/renderer/renderer.ts +++ b/apps/ar-demo/src/lib/renderer/renderer.ts @@ -1,6 +1,7 @@ import * as THREE from "three"; import { IDisposable } from ".."; +import { USE_HIT_TEST } from "../../constants"; import * as SCAN from "../staticScan"; import { defaultStructureColor, @@ -216,8 +217,8 @@ export default class Renderer implements IDisposable { this.domOverlay.style.display = ""; const sessionInit = { - requiredFeatures: ["hit-test"], - optionalFeatures: ["dom-overlay"], + requiredFeatures: [], + optionalFeatures: ["hit-test", "dom-overlay"], domOverlay: { root: this.domOverlay }, }; @@ -232,9 +233,11 @@ export default class Renderer implements IDisposable { this.renderer.xr.setReferenceSpaceType("local"); this.renderer.xr.setSession(session); - this.reticle.activate(); + if (USE_HIT_TEST) { + this.reticle.activate(); + } - this.scanContainer.visible = false; + this.scanContainer.visible = !USE_HIT_TEST; this.updateUI(); @@ -269,6 +272,7 @@ export default class Renderer implements IDisposable { this.reticle.hide(); + // TODO: Fix camera reset if (this.oldCameraPosition) { this.camera.position.copy(this.oldCameraPosition); this.oldCameraPosition = undefined; @@ -301,16 +305,20 @@ export default class Renderer implements IDisposable { private onARSelect = () => { if (!this.acceptARSelect) return; - this.scanContainer.visible = true; + if (USE_HIT_TEST) { + this.scanContainer.visible = true; - if (this.reticle.active) { - if (this.reticle.visible) { - this.scanContainer.position.setFromMatrixPosition(this.reticle.matrix); + if (this.reticle.active) { + if (this.reticle.visible) { + this.scanContainer.position.setFromMatrixPosition( + this.reticle.matrix, + ); - this.reticle.activate(false); + this.reticle.activate(false); + } + } else { + this.reticle.activate(); } - } else { - this.reticle.activate(); } }; From cf91396c260d45853537a5612015e4ff7a3b947a Mon Sep 17 00:00:00 2001 From: Paul Brachmann Date: Thu, 15 Jul 2021 17:55:17 +0200 Subject: [PATCH 2/8] Add basic drag & drop interaction --- apps/ar-demo/src/lib/renderer/renderer.ts | 54 ++++++++++++++++--- .../src/lib/volume-renderer/xr-manager.ts | 3 +- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/apps/ar-demo/src/lib/renderer/renderer.ts b/apps/ar-demo/src/lib/renderer/renderer.ts index 21bd67dd9..b6ea3053d 100644 --- a/apps/ar-demo/src/lib/renderer/renderer.ts +++ b/apps/ar-demo/src/lib/renderer/renderer.ts @@ -241,9 +241,20 @@ export default class Renderer implements IDisposable { this.updateUI(); - const controller = this.renderer.xr.getController(0); - controller.addEventListener("select", this.onARSelect); - this.scene.add(controller); + // TODO: The HoloLens sadly does not stay consistent in its controller enumeration. + // Instead, the primary (right) hand is controller 0, as long as it is visible. + // If only the other (left) hand is visible, it becomes controller 0 + // until the primary hand becomes visible (again). + // This has to be accounted for when trying to ensure continous drag & drop interactions. + const controller1 = this.renderer.xr.getController(0); + controller1.addEventListener("selectstart", this.onARSelect); + controller1.addEventListener("selectend", this.onARDeselect); + + const controller2 = this.renderer.xr.getController(1); + controller2.addEventListener("selectstart", this.onARSelect); + controller2.addEventListener("selectend", this.onARDeselect); + + this.scene.add(controller1); }) .catch((e) => { // eslint-disable-next-line no-console @@ -267,8 +278,13 @@ export default class Renderer implements IDisposable { // The XR session hides everything else. So we have to show it again. document.getElementById("root")?.setAttribute("style", ""); - const controller = this.renderer.xr.getController(0); - controller.removeEventListener("select", this.onARSelect); + const controller1 = this.renderer.xr.getController(0); + controller1.removeEventListener("selectstart", this.onARSelect); + controller1.removeEventListener("selectend", this.onARDeselect); + + const controller2 = this.renderer.xr.getController(1); + controller2.removeEventListener("selectstart", this.onARSelect); + controller2.removeEventListener("selectend", this.onARDeselect); this.reticle.hide(); @@ -302,7 +318,25 @@ export default class Renderer implements IDisposable { }); }; - private onARSelect = () => { + // Controller Interaction + protected startGrab = (controller: THREE.Group) => { + controller.attach(this.scanContainer); + this.scanContainer.userData.selections = + (this.scanContainer.userData.selections || 0) + 1; + controller.userData.selected = this.scanContainer; + }; + protected endGrab = (controller: THREE.Group) => { + if (controller.userData.selected !== undefined) { + const object = controller.userData.selected; + object.userData.selections = (object.userData.selections || 1) - 1; + controller.userData.selected = undefined; + if (!object.userData.selections) { + this.scene.attach(object); + } + } + }; + + private onARSelect = (event: THREE.Event) => { if (!this.acceptARSelect) return; if (USE_HIT_TEST) { @@ -319,6 +353,14 @@ export default class Renderer implements IDisposable { } else { this.reticle.activate(); } + } else { + this.startGrab(event.target); + } + }; + + private onARDeselect = (event: THREE.Event) => { + if (!USE_HIT_TEST) { + this.endGrab(event.target); } }; diff --git a/libs/rendering/src/lib/volume-renderer/xr-manager.ts b/libs/rendering/src/lib/volume-renderer/xr-manager.ts index a60fe887f..dcc097a09 100644 --- a/libs/rendering/src/lib/volume-renderer/xr-manager.ts +++ b/libs/rendering/src/lib/volume-renderer/xr-manager.ts @@ -16,8 +16,7 @@ export class XRManager implements IXRManager { protected endGrab = (controller: THREE.Group) => { if (controller.userData.selected !== undefined) { const object = controller.userData.selected; - object.userData.selections = - (this.renderer.volume.userData.selections || 1) - 1; + object.userData.selections = (object.userData.selections || 1) - 1; controller.userData.selected = undefined; if (!object.userData.selections) { this.renderer.scene.attach(object); From d7167d40143a21e599cb4fced2450f11649269e5 Mon Sep 17 00:00:00 2001 From: Jonas Kordt Date: Sat, 31 Jul 2021 15:45:10 +0200 Subject: [PATCH 3/8] First (buggy) version of moving slices in AR --- .../src/lib/renderer/helpers/scanNavigator.ts | 21 ++-- .../src/lib/renderer/helpers/spriteHandler.ts | 12 +-- apps/ar-demo/src/lib/renderer/renderer.ts | 95 ++++++++++++++++--- apps/ar-demo/src/lib/staticScan/index.ts | 30 ++---- 4 files changed, 106 insertions(+), 52 deletions(-) diff --git a/apps/ar-demo/src/lib/renderer/helpers/scanNavigator.ts b/apps/ar-demo/src/lib/renderer/helpers/scanNavigator.ts index 83c67f2c6..05e9b4628 100644 --- a/apps/ar-demo/src/lib/renderer/helpers/scanNavigator.ts +++ b/apps/ar-demo/src/lib/renderer/helpers/scanNavigator.ts @@ -194,21 +194,12 @@ export default class ScanNavigator implements IDisposable { }; private handleTransformMove = () => { - this.workingVector.copy(this.transformObject.position); - - this.workingVector.x = - Math.round(this.workingVector.x / this.voxelDimensions.x) * - this.voxelDimensions.x; - this.workingVector.y = - Math.round(this.workingVector.y / this.voxelDimensions.y) * - this.voxelDimensions.y; - this.workingVector.z = - Math.round(this.workingVector.z / this.voxelDimensions.z) * - this.voxelDimensions.z; - - this.workingVector.divide(this.voxelDimensions); - this.workingVector.max(this.minSelectedVoxel); - this.workingVector.min(this.maxSelectedVoxel); + this.workingVector + .copy(this.transformObject.position) + .divide(this.voxelDimensions) + .round() + .max(this.minSelectedVoxel) + .min(this.maxSelectedVoxel); // x is inverted... this.workingVector.x = SCAN.voxelCount.x - this.workingVector.x - 1; diff --git a/apps/ar-demo/src/lib/renderer/helpers/spriteHandler.ts b/apps/ar-demo/src/lib/renderer/helpers/spriteHandler.ts index 1cfc8ab3f..b573df248 100644 --- a/apps/ar-demo/src/lib/renderer/helpers/spriteHandler.ts +++ b/apps/ar-demo/src/lib/renderer/helpers/spriteHandler.ts @@ -22,11 +22,11 @@ export default class SpriteHandler { private cameraOctant?: number; - public selectedVoxel: Voxel = { - x: Math.floor(SCAN.voxelCount.x / 2), - y: Math.floor(SCAN.voxelCount.y / 2), - z: Math.floor(SCAN.voxelCount.z / 2), - }; + public selectedVoxel = new THREE.Vector3( + Math.floor(SCAN.voxelCount.x / 2), + Math.floor(SCAN.voxelCount.y / 2), + Math.floor(SCAN.voxelCount.z / 2), + ); constructor(private renderer: Renderer) { const loader = new THREE.TextureLoader(); @@ -151,7 +151,7 @@ export default class SpriteHandler { }; public setSelectedVoxel = (voxel: Voxel) => { - this.selectedVoxel = voxel; + this.selectedVoxel.set(voxel.x, voxel.y, voxel.z); this.materials.forEach((material) => { // eslint-disable-next-line no-param-reassign diff --git a/apps/ar-demo/src/lib/renderer/renderer.ts b/apps/ar-demo/src/lib/renderer/renderer.ts index b6ea3053d..5b80fa449 100644 --- a/apps/ar-demo/src/lib/renderer/renderer.ts +++ b/apps/ar-demo/src/lib/renderer/renderer.ts @@ -67,6 +67,18 @@ export default class Renderer implements IDisposable { private scanBaseRotation = Math.PI; private acceptARSelect = true; + private controller1?: THREE.Group; + private controller2?: THREE.Group; + + private grabbedDimension?: number; + private startPosition = new THREE.Vector3(); + private startSlice?: number; + + private helperBall = new THREE.Mesh( + new THREE.SphereBufferGeometry(0.003), + new THREE.MeshBasicMaterial(), + ); + constructor(private canvas: HTMLCanvasElement, public updateUI: () => void) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this.domOverlay = document.getElementById("ar-overlay")!; @@ -191,6 +203,37 @@ export default class Renderer implements IDisposable { if (frame) { this.reticle.update(frame); } + + if ( + this.controller1 && + this.grabbedDimension !== undefined && + this.startSlice !== undefined + ) { + const offset = new THREE.Vector3() + .copy(this.controller1.position) + .sub(this.startPosition); + this.scanOffsetGroup.worldToLocal(offset); + offset.divide(SCAN.voxelDimensions).round(); + + const sliceOffset = offset.getComponent(this.grabbedDimension); + const newSlice = Math.max( + 0, + Math.min( + SCAN.voxelCount.getComponent(this.grabbedDimension) - 1, + this.startSlice + sliceOffset, + ), + ); + + const newSelectedVoxel = new THREE.Vector3() + .copy(this.spriteHandler.selectedVoxel) + .setComponent(this.grabbedDimension, newSlice); + + if (this.grabbedDimension === 0) { + newSelectedVoxel.x = SCAN.voxelCount.x - newSelectedVoxel.x - 1; + } + + this.spriteHandler.setSelectedVoxel(newSelectedVoxel); + } } if (this.renderDirty || this.arActive) this.forceRender(); @@ -246,15 +289,18 @@ export default class Renderer implements IDisposable { // If only the other (left) hand is visible, it becomes controller 0 // until the primary hand becomes visible (again). // This has to be accounted for when trying to ensure continous drag & drop interactions. - const controller1 = this.renderer.xr.getController(0); - controller1.addEventListener("selectstart", this.onARSelect); - controller1.addEventListener("selectend", this.onARDeselect); + this.controller1 = this.renderer.xr.getController(0); + this.controller1.addEventListener("selectstart", this.onARSelect); + this.controller1.addEventListener("selectend", this.onARDeselect); - const controller2 = this.renderer.xr.getController(1); - controller2.addEventListener("selectstart", this.onARSelect); - controller2.addEventListener("selectend", this.onARDeselect); + this.controller2 = this.renderer.xr.getController(1); + this.controller2.addEventListener("selectstart", this.onARSelect); + this.controller2.addEventListener("selectend", this.onARDeselect); + + this.controller1.add(this.helperBall); - this.scene.add(controller1); + this.scene.add(this.controller1); + this.scene.add(this.controller2); }) .catch((e) => { // eslint-disable-next-line no-console @@ -320,12 +366,39 @@ export default class Renderer implements IDisposable { // Controller Interaction protected startGrab = (controller: THREE.Group) => { - controller.attach(this.scanContainer); - this.scanContainer.userData.selections = - (this.scanContainer.userData.selections || 0) + 1; - controller.userData.selected = this.scanContainer; + const controllerPosition = new THREE.Vector3(); + controller.getWorldPosition(controllerPosition); + this.scanOffsetGroup.worldToLocal(controllerPosition); + controllerPosition.divide(SCAN.voxelDimensions); + controllerPosition.sub(this.spriteHandler.selectedVoxel); + let index = 0; + let distance = Infinity; + controllerPosition.toArray().forEach((d, i) => { + const absD = Math.abs(d); + if (absD < distance) { + distance = absD; + index = i; + } + }); + + if (distance < 50) { + this.grabbedDimension = index; + this.startPosition.copy(controller.position); + this.startSlice = [ + this.spriteHandler.selectedVoxel.x, + this.spriteHandler.selectedVoxel.y, + this.spriteHandler.selectedVoxel.z, + ][index]; + } else { + controller.attach(this.scanContainer); + this.scanContainer.userData.selections = + (this.scanContainer.userData.selections || 0) + 1; + controller.userData.selected = this.scanContainer; + } }; protected endGrab = (controller: THREE.Group) => { + this.grabbedDimension = undefined; + this.startSlice = undefined; if (controller.userData.selected !== undefined) { const object = controller.userData.selected; object.userData.selections = (object.userData.selections || 1) - 1; diff --git a/apps/ar-demo/src/lib/staticScan/index.ts b/apps/ar-demo/src/lib/staticScan/index.ts index 678bb0c63..50b80dfa0 100644 --- a/apps/ar-demo/src/lib/staticScan/index.ts +++ b/apps/ar-demo/src/lib/staticScan/index.ts @@ -1,31 +1,21 @@ import * as THREE from "three"; -import { Pixel, Voxel } from "../types"; import preGeneratedGeometries from "./preGeneratedGeometries"; -export const voxelCount: Voxel = { - x: 170, - y: 244, - z: 216, -}; +export const voxelCount = new THREE.Vector3(170, 244, 216); // in meters -export const voxelDimensions: Voxel = { - x: 0.0009999985694885254, - y: 0.001, - z: 0.001, -}; +export const voxelDimensions = new THREE.Vector3( + 0.0009999985694885254, + 0.001, + 0.001, +); -export const scanSize = { - x: voxelCount.x * voxelDimensions.x, - y: voxelCount.y * voxelDimensions.y, - z: voxelCount.z * voxelDimensions.z, -}; +export const scanSize = new THREE.Vector3() + .copy(voxelCount) + .multiply(voxelDimensions); -export const atlasGrid: Pixel = { - x: 18, - y: 12, -}; +export const atlasGrid = new THREE.Vector2(18, 12); export const getConnectedStructureGeometries: () => Promise[] = () => { const geometryLoader = new THREE.BufferGeometryLoader(); From ca7d626f50a011bb06fae2d122d9af60a9f1e443 Mon Sep 17 00:00:00 2001 From: Jonas Kordt Date: Tue, 3 Aug 2021 20:21:13 +0200 Subject: [PATCH 4/8] Fix slices jumpng when being grabbed in AR --- apps/ar-demo/src/lib/renderer/renderer.ts | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/apps/ar-demo/src/lib/renderer/renderer.ts b/apps/ar-demo/src/lib/renderer/renderer.ts index 5b80fa449..5b67c09a5 100644 --- a/apps/ar-demo/src/lib/renderer/renderer.ts +++ b/apps/ar-demo/src/lib/renderer/renderer.ts @@ -209,11 +209,11 @@ export default class Renderer implements IDisposable { this.grabbedDimension !== undefined && this.startSlice !== undefined ) { - const offset = new THREE.Vector3() - .copy(this.controller1.position) - .sub(this.startPosition); + const offset = new THREE.Vector3().copy(this.controller1.position); this.scanOffsetGroup.worldToLocal(offset); + offset.sub(this.startPosition); offset.divide(SCAN.voxelDimensions).round(); + offset.x *= -1; const sliceOffset = offset.getComponent(this.grabbedDimension); const newSlice = Math.max( @@ -227,11 +227,6 @@ export default class Renderer implements IDisposable { const newSelectedVoxel = new THREE.Vector3() .copy(this.spriteHandler.selectedVoxel) .setComponent(this.grabbedDimension, newSlice); - - if (this.grabbedDimension === 0) { - newSelectedVoxel.x = SCAN.voxelCount.x - newSelectedVoxel.x - 1; - } - this.spriteHandler.setSelectedVoxel(newSelectedVoxel); } } @@ -370,6 +365,7 @@ export default class Renderer implements IDisposable { controller.getWorldPosition(controllerPosition); this.scanOffsetGroup.worldToLocal(controllerPosition); controllerPosition.divide(SCAN.voxelDimensions); + controllerPosition.x = SCAN.voxelCount.x - controllerPosition.x - 1; controllerPosition.sub(this.spriteHandler.selectedVoxel); let index = 0; let distance = Infinity; @@ -384,6 +380,7 @@ export default class Renderer implements IDisposable { if (distance < 50) { this.grabbedDimension = index; this.startPosition.copy(controller.position); + this.scanOffsetGroup.worldToLocal(this.startPosition); this.startSlice = [ this.spriteHandler.selectedVoxel.x, this.spriteHandler.selectedVoxel.y, From df4cab42994b12531a789d2a21525ab8bce838e2 Mon Sep 17 00:00:00 2001 From: Jonas Kordt Date: Tue, 3 Aug 2021 20:37:13 +0200 Subject: [PATCH 5/8] Add max distance for grabbing slices --- apps/ar-demo/src/lib/renderer/renderer.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/ar-demo/src/lib/renderer/renderer.ts b/apps/ar-demo/src/lib/renderer/renderer.ts index 5b67c09a5..4eae18f19 100644 --- a/apps/ar-demo/src/lib/renderer/renderer.ts +++ b/apps/ar-demo/src/lib/renderer/renderer.ts @@ -377,7 +377,9 @@ export default class Renderer implements IDisposable { } }); - if (distance < 50) { + const maxDistance = Math.max(...controllerPosition.toArray()); + + if (distance < 50 && maxDistance < 300) { this.grabbedDimension = index; this.startPosition.copy(controller.position); this.scanOffsetGroup.worldToLocal(this.startPosition); From 0f62bdc16850a176b6f4079ee2ba1332edb81409 Mon Sep 17 00:00:00 2001 From: Jonas Kordt Date: Tue, 3 Aug 2021 20:44:10 +0200 Subject: [PATCH 6/8] Use working vectors instead of new vectors --- apps/ar-demo/src/lib/renderer/renderer.ts | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/apps/ar-demo/src/lib/renderer/renderer.ts b/apps/ar-demo/src/lib/renderer/renderer.ts index 4eae18f19..977b14fbf 100644 --- a/apps/ar-demo/src/lib/renderer/renderer.ts +++ b/apps/ar-demo/src/lib/renderer/renderer.ts @@ -79,6 +79,9 @@ export default class Renderer implements IDisposable { new THREE.MeshBasicMaterial(), ); + private workingVector1 = new THREE.Vector3(); + private workingVector2 = new THREE.Vector3(); + constructor(private canvas: HTMLCanvasElement, public updateUI: () => void) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this.domOverlay = document.getElementById("ar-overlay")!; @@ -129,13 +132,11 @@ export default class Renderer implements IDisposable { this.cameraNavigator, ); - this.camera.position.copy( - this.scanOffsetGroup.localToWorld( - new THREE.Vector3( - -0.25 * SCAN.scanSize.x, - 1.25 * SCAN.scanSize.y, - 1.25 * SCAN.scanSize.z, - ), + this.scanOffsetGroup.localToWorld( + this.camera.position.set( + -0.25 * SCAN.scanSize.x, + 1.25 * SCAN.scanSize.y, + 1.25 * SCAN.scanSize.z, ), ); const target = this.scanOffsetGroup.localToWorld( @@ -209,7 +210,7 @@ export default class Renderer implements IDisposable { this.grabbedDimension !== undefined && this.startSlice !== undefined ) { - const offset = new THREE.Vector3().copy(this.controller1.position); + const offset = this.workingVector1.copy(this.controller1.position); this.scanOffsetGroup.worldToLocal(offset); offset.sub(this.startPosition); offset.divide(SCAN.voxelDimensions).round(); @@ -224,7 +225,7 @@ export default class Renderer implements IDisposable { ), ); - const newSelectedVoxel = new THREE.Vector3() + const newSelectedVoxel = this.workingVector1 .copy(this.spriteHandler.selectedVoxel) .setComponent(this.grabbedDimension, newSlice); this.spriteHandler.setSelectedVoxel(newSelectedVoxel); @@ -361,7 +362,7 @@ export default class Renderer implements IDisposable { // Controller Interaction protected startGrab = (controller: THREE.Group) => { - const controllerPosition = new THREE.Vector3(); + const controllerPosition = this.workingVector2; controller.getWorldPosition(controllerPosition); this.scanOffsetGroup.worldToLocal(controllerPosition); controllerPosition.divide(SCAN.voxelDimensions); From 24ab0e46c1d73764506733dbfaec78ad0ea01785 Mon Sep 17 00:00:00 2001 From: Jonas Kordt Date: Mon, 9 Aug 2021 10:05:34 +0200 Subject: [PATCH 7/8] Increase default opacity --- apps/ar-demo/src/lib/renderer/helpers/spriteHandler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/ar-demo/src/lib/renderer/helpers/spriteHandler.ts b/apps/ar-demo/src/lib/renderer/helpers/spriteHandler.ts index b573df248..71a674578 100644 --- a/apps/ar-demo/src/lib/renderer/helpers/spriteHandler.ts +++ b/apps/ar-demo/src/lib/renderer/helpers/spriteHandler.ts @@ -57,7 +57,7 @@ export default class SpriteHandler { contrast: { value: 1 }, brightness: { value: 1 }, blueTint: { value: true }, - opacity: { value: 0.5 }, + opacity: { value: 0.7 }, }; this.materials = viewTypes.map( From d54babf393f3f0c629a444dc74811e62cf62fec8 Mon Sep 17 00:00:00 2001 From: Paul Brachmann Date: Tue, 10 Aug 2021 13:22:02 +0200 Subject: [PATCH 8/8] Add AR demo deployment job --- .github/workflows/nx_affected.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.github/workflows/nx_affected.yml b/.github/workflows/nx_affected.yml index b90864797..0082d16ee 100644 --- a/.github/workflows/nx_affected.yml +++ b/.github/workflows/nx_affected.yml @@ -99,3 +99,29 @@ jobs: publish_branch: main publish_dir: ./dist force_orphan: true + + deploy-ar-demo: + runs-on: ubuntu-latest + needs: build + #if: success() && github.ref == 'refs/heads/develop' + + steps: + - uses: actions/download-artifact@v2 + with: + name: ar-demo-build + path: dist + - name: Check if build exists + id: check_files + uses: andstor/file-existence-action@v1 + with: + files: "dist/index.html" + - name: Deploy to production + uses: peaceiris/actions-gh-pages@v3 + if: steps.check_files.outputs.files_exists == 'true' + with: + cname: ar.visian.org + deploy_key: ${{ secrets.AR_REPO_DEPLOY_KEY }} + external_repository: HealthML/visian-ar + publish_branch: main + publish_dir: ./dist + force_orphan: true