diff --git a/examples/showcase/ai-model/index.html b/examples/showcase/ai-model/index.html new file mode 100644 index 00000000000..f2b5e1d3a7d --- /dev/null +++ b/examples/showcase/ai-model/index.html @@ -0,0 +1,20 @@ + + + + + Anchor (Mixed Reality) • A-Frame + + + + + + + + + + + + + + diff --git a/examples/showcase/ai-model/message.html b/examples/showcase/ai-model/message.html new file mode 100644 index 00000000000..ccd0d158377 --- /dev/null +++ b/examples/showcase/ai-model/message.html @@ -0,0 +1,11 @@ +

+This demo requires a browser supporting the WebXR Anchors Module +

+ +

+In AR mode the user can pinch to grab the painting and release it at any position and orientation. The painting will remain anchored to the real world coordinate where it was released by the user. The anchor will persists upon page reload. +

+ +

+Paintings by Van Gogh, Alphonse Mucha, El Greco and Edvard Munch. Frame model by theGentleGiant +

\ No newline at end of file diff --git a/package.json b/package.json index beebbc92765..bb5b135bf80 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "buffer": "^6.0.3", "debug": "ngokevin/debug#noTimestamp", "deep-assign": "^2.0.0", + "@gradio/client": "0.14.0", "load-bmfont": "^1.2.3", "super-animejs": "^3.1.0", "super-three": "0.162.0", @@ -73,6 +74,7 @@ "karma-webpack": "^5.0.0", "markserv": "github:sukima/markserv#feature/fix-broken-websoketio-link", "mocha": "^10.0.0", + "node-polyfill-webpack-plugin": "^3.0.0", "replace-in-file": "^2.5.3", "shelljs": "^0.7.7", "shx": "^0.2.2", @@ -115,7 +117,7 @@ "webxr" ], "engines": { - "node": ">= 4.6.0", - "npm": ">= 2.15.9" + "node": ">= 21.7.1", + "npm": ">= 10.5.0" } } diff --git a/src/components/ai-model.js b/src/components/ai-model.js new file mode 100644 index 00000000000..e6f06c256ee --- /dev/null +++ b/src/components/ai-model.js @@ -0,0 +1,35 @@ +var registerComponent = require('../core/component').registerComponent; +var GRADIOCLIENT = require('../lib/gradio'); + +/** + * AI model loader. + */ +module.exports.Component = registerComponent('ai-model', { + schema: { + prompt: {type: 'string', default: 'robot'}, + api: {type: 'string', oneOf: ['perflow']}, + key: {type: 'string', default: ''} + }, + + init: function () { + this.generateAndRender(this.data.prompt); + }, + + update: function () { + + }, + + generateAndRender: async function generateAndRender (prompt) { + var modelEl = document.createElement('a-entity'); + modelEl.setAttribute('position', '0 1.6 -2'); + modelEl.setAttribute('rotation', '0 180 0'); + var app = await GRADIOCLIENT('hansyan/perflow-triposr', {}); + var result = await app.predict( + '/render', + (await app.predict('/generate', [prompt, '0'])).data + ); + console.log('Model URL: ' + result.data[0].url); + modelEl.setAttribute('obj-model', {obj: result.data[0].url}); + this.el.sceneEl.appendChild(modelEl); + } +}); diff --git a/src/components/index.js b/src/components/index.js index 7ccb4843bca..bdc0b20c954 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -1,3 +1,4 @@ +require('./ai-model'); require('./animation'); require('./anchored'); require('./camera'); diff --git a/src/lib/gradio.js b/src/lib/gradio.js new file mode 100644 index 00000000000..4df8c52e122 --- /dev/null +++ b/src/lib/gradio.js @@ -0,0 +1,3 @@ +var GRADIOCLIENT = require('./gradio.module.js').default; + +module.exports = GRADIOCLIENT; diff --git a/src/lib/gradio.module.js b/src/lib/gradio.module.js new file mode 100644 index 00000000000..5b1c93f3cbd --- /dev/null +++ b/src/lib/gradio.module.js @@ -0,0 +1,5 @@ +import { client } from '@gradio/client'; + +var GRADIOCLIENT = client; + +export default GRADIOCLIENT; diff --git a/webpack.config.js b/webpack.config.js index 5ade0f60e56..75316b714db 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,5 +1,6 @@ var path = require('path'); var webpack = require('webpack'); +var NodePolyfillPlugin = require('node-polyfill-webpack-plugin'); module.exports = { entry: './src/index.js', @@ -29,11 +30,32 @@ module.exports = { new webpack.ProvidePlugin({ process: 'process/browser', Buffer: ['buffer', 'Buffer'] - }) + }), + new webpack.NormalModuleReplacementPlugin(/node:/, (resource) => { + resource.request = resource.request.replace(/^node:/, ''); + }), + new NodePolyfillPlugin() ], resolve: { alias: { three: 'super-three' + }, + fallback: { + // fixes proxy-agent dependencies + crypto: false, + net: false, + dns: false, + tls: false, + assert: false, + http: false, + https: false, + // fixes next-i18next dependencies + path: false, + fs: false, + // fixes mapbox dependencies + events: false, + // fixes sentry dependencies + process: false } }, module: {