Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added URL loading of USDZ file in the GET request URL params. #6

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
# Three USDZ Loader
# Three.js + USDZ Loader

This is a demo project showing how to load a **USDZ file** with ThreeJS (Pixar Universal Scene Description) in a 100% frontend based application.
For more information about the USDZ loader used in this demo please take a look at the **loader package** [three-usdz-loader](https://www.npmjs.com/package/three-usdz-loader).
This is a demo project showing how to load a **USDZ file** with **Three.JS** (Pixar Universal Scene Description) in a 100% frontend based application.
For more information about the USDZ loader please take a look at the original **loader package** [three-usdz-loader](https://www.npmjs.com/package/three-usdz-loader).

## Features
- 100% frontend (no backend or GLTF converter of some sort)
- Uses ThreeJS + Vue + Vuetify + Typescript
- Passing USDZ file as URL (https://url.endpoint/?url=<someUrlEncodedUrl>)

## Demo
This repository build is published to [usdz-viewer.net](https://www.usdz-viewer.net)
The original repository build is published to [usdz-viewer.net](https://www.usdz-viewer.net)

## How to use
Clone the repository
```
git clone https://github.com/ponahoum/usdz-web-viewer.git
cd .\usdz-web-viewer\
git clone [https://github.com/ponahoum/usdz-web-viewer.git](https://github.com/anomaloushuman/USDZ-xPlat-Viewer)
cd .\USDZ-xPlat-Viewer\
```

Install Vue Cli and the dependencies
Expand Down Expand Up @@ -44,4 +45,4 @@ headers: {
"Cross-Origin-Embedder-Policy": "require-corp",
"Cross-Origin-Opener-Policy": "same-origin",
},
```
```
48 changes: 37 additions & 11 deletions src/components/Home.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,30 @@ export default class Home extends Vue {

// Setup windows events
window.addEventListener("resize", this.onWindowResize);

// Load file from URL after the window has fully loaded
this.loadFileFromUrl();
}

async loadFileFromUrl(): Promise<void> {
const urlParams = new URLSearchParams(window.location.search);
const fileUrl = urlParams.get('url');
if (fileUrl) {
const decodedUrl = decodeURIComponent(fileUrl); // Decode the URL
try {
const response = await fetch(decodedUrl);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const fileBlob = await response.blob();
// Specify the correct MIME type for USDZ files
const file = new File([fileBlob], 'loadedFile.usdz', { type: 'model/vnd.usdz+zip' }); // Use the correct MIME type
await this.loadFile(file);
} catch (error) {
console.error("Failed to load the file from URL:", error);
this.error = error instanceof Error ? error.message : "An unknown error occurred."; // Set error message for user feedback
}
}
}

/**
Expand All @@ -126,7 +150,7 @@ export default class Home extends Vue {
async loadFile(file: File): Promise<void> {
// Prevents multiple loadings in parallel
if (this.modelIsLoading) {
return;
return;
}

// Notice model is now loading
Expand All @@ -135,10 +159,12 @@ export default class Home extends Vue {
// Reset any previous error
this.error = null;

// Clearup any previsouly loaded model
// We could technically load multiple files by removing this for loop
// Log the file details for debugging
console.log("Loading file:", file.name, "Type:", file.type, "Size:", file.size);

// Clear up any previously loaded model
for (const el of this.loadedModels) {
el.clear();
el.clear();
}
this.loadedModels = [];

Expand All @@ -148,18 +174,18 @@ export default class Home extends Vue {

// Load file and catch any error to show the user
try {
const loadedModel = await this.loader.loadFile(file, group);
this.loadedModels.push(loadedModel);
const loadedModel = await this.loader.loadFile(file, group);
this.loadedModels.push(loadedModel);
} catch (e) {
this.error = e as string;
console.error("An error occured when trying to load the model" + e);
this.modelIsLoading = false;
return;
this.error = e as string;
console.error("An error occurred when trying to load the model:", e);
this.modelIsLoading = false;
return;
}

// Fits the camera to match the loaded model
const allContainers = this.loadedModels.map((el: USDZInstance) => {
return el.getGroup();
return el.getGroup();
});
this.fitCamera(this.camera, this.controls, allContainers);

Expand Down