Beg-in / vue-babylonjs

A ready-to-go 3d environment for Vue.js using Babylon.js
https://vuebabylonjs.com
MIT License
459 stars 73 forks source link

Add a ready event for asset component / Compile error #64

Open JustinFincher opened 4 years ago

JustinFincher commented 4 years ago

Hi, firstly thank you for this amazing project. When using it I encountered a situation where I need to listen to the asset loaded event to trigger UI changes. Specifically, I am working on my product website, in it, there is a mockup phone initially paired with a loading indicator, and once the GLTF file is loaded into the scene I want the indicator gone so that the user could see the lock screen UI along with the loaded GLTF model. Currently, I haven't found a workaround. The v-model watcher for the asset seems to be triggered way before the asset is actually loaded, and thus my lock screen UI is set as visible even the asset is still loading. Thus I propose to add an asset ready event so that people could use v-on syntax to listen for state changes. I have made some preliminary changes at https://github.com/JustinFincher/vue-babylonjs/commit/0582067bd82abe36a09ebdfea124d07bc7c71729, but upon npm start it throws errors related to babylon.js itself (no matter with or without my addition):

➜  vue-babylonjs git:(master) ✗ npm start   

> vue-babylonjs@1.0.0-beta.7 start /Volumes/DEVDRIVE/Develop/FE/vue-babylonjs
> npm run b start:client

> vue-babylonjs@1.0.0-beta.7 b /Volumes/DEVDRIVE/Develop/FE/vue-babylonjs
> CONTEXT=$(pwd) npm explore begin-build -- npm run "start:client"

> begin-build@0.16.15 start:client /Volumes/DEVDRIVE/Develop/FE/vue-babylonjs/node_modules/begin-build
> node begin.js; npm run watch:client

> begin-build@0.16.15 watch:client /Volumes/DEVDRIVE/Develop/FE/vue-babylonjs/node_modules/begin-build
> npm run watcher -- --exec 'nf run npm run b dev:client'

> begin-build@0.16.15 watcher /Volumes/DEVDRIVE/Develop/FE/vue-babylonjs/node_modules/begin-build
> cd $CONTEXT; nodemon --watch yarn.lock --watch properties.js --watch .env "--exec" "nf run npm run b dev:client"

[nodemon] 1.19.4
[nodemon] to restart at any time, enter `rs`
[nodemon] watching dir(s): yarn.lock properties.js .env
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `nf run npm run b dev:client`

> vue-babylonjs@1.0.0-beta.7 b /Volumes/DEVDRIVE/Develop/FE/vue-babylonjs
> CONTEXT=$(pwd) npm explore begin-build -- npm run "dev:client"

> begin-build@0.16.15 dev:client /Volumes/DEVDRIVE/Develop/FE/vue-babylonjs/node_modules/begin-build
> webpack-dev-server -d --host ${IP:=0.0.0.0} --config webpack.config.js --env.stage=development --env.port=${PORT:=8080} --env.context=$CONTEXT --progress $(if [ $C9_HOSTNAME ]; then echo "--public $C9_HOSTNAME --env.url=https://$C9_HOSTNAME"; fi)

10% building 1/1 modules 0 activeℹ 「wds」: Project is running at http://0.0.0.0:8080/
ℹ 「wds」: webpack output is served from /
ℹ 「wds」: Content not from webpack is served from /Volumes/DEVDRIVE/Develop/FE/vue-babylonjs/node_modules/begin-build
ℹ 「wds」: 404s will fallback to /index.html
✖ 「wdm」:    1086 modules

ERROR in ../@babylonjs/core/Meshes/mesh.js
Module build failed (from ../babel-loader/lib/index.js):
TypeError: /Volumes/DEVDRIVE/Develop/FE/vue-babylonjs/node_modules/@babylonjs/core/Meshes/mesh.js: Property left of ForInStatement expected node to be of a type ["VariableDeclaration","LVal"] but instead got null
    at Object.validate (/Volumes/DEVDRIVE/Develop/FE/vue-babylonjs/node_modules/@babel/types/lib/definitions/utils.js:131:11)
    at validateField (/Volumes/DEVDRIVE/Develop/FE/vue-babylonjs/node_modules/@babel/types/lib/validators/validate.js:24:9)
    at Object.validate (/Volumes/DEVDRIVE/Develop/FE/vue-babylonjs/node_modules/@babel/types/lib/validators/validate.js:17:3)
    at NodePath._replaceWith (/Volumes/DEVDRIVE/Develop/FE/vue-babylonjs/node_modules/@babel/traverse/lib/path/replacement.js:172:7)
    at NodePath._remove (/Volumes/DEVDRIVE/Develop/FE/vue-babylonjs/node_modules/@babel/traverse/lib/path/removal.js:55:10)
    at NodePath.remove (/Volumes/DEVDRIVE/Develop/FE/vue-babylonjs/node_modules/@babel/traverse/lib/path/removal.js:34:8)
    at hooks (/Volumes/DEVDRIVE/Develop/FE/vue-babylonjs/node_modules/@babel/traverse/lib/path/lib/removal-hooks.js:11:12)
    at NodePath._callRemovalHooks (/Volumes/DEVDRIVE/Develop/FE/vue-babylonjs/node_modules/@babel/traverse/lib/path/removal.js:46:9)
    at NodePath.remove (/Volumes/DEVDRIVE/Develop/FE/vue-babylonjs/node_modules/@babel/traverse/lib/path/removal.js:26:12)
    at convertFunctionParams (/Volumes/DEVDRIVE/Develop/FE/vue-babylonjs/node_modules/@babel/plugin-transform-parameters/lib/params.js:88:30)
    at PluginPass.Function (/Volumes/DEVDRIVE/Develop/FE/vue-babylonjs/node_modules/@babel/plugin-transform-parameters/lib/index.js:30:53)
    at newFn (/Volumes/DEVDRIVE/Develop/FE/vue-babylonjs/node_modules/@babel/traverse/lib/visitors.js:179:21)
    at NodePath._call (/Volumes/DEVDRIVE/Develop/FE/vue-babylonjs/node_modules/@babel/traverse/lib/path/context.js:55:20)
    at NodePath.call (/Volumes/DEVDRIVE/Develop/FE/vue-babylonjs/node_modules/@babel/traverse/lib/path/context.js:42:17)
    at NodePath.visit (/Volumes/DEVDRIVE/Develop/FE/vue-babylonjs/node_modules/@babel/traverse/lib/path/context.js:90:31)
    at TraversalContext.visitQueue (/Volumes/DEVDRIVE/Develop/FE/vue-babylonjs/node_modules/@babel/traverse/lib/context.js:112:16)
ℹ 「wdm」: Failed to compile.

For the reference, I am using node v12.16.0, and the @babylonjs/core dependency in package-lock is 4.1.0. I am not familiar with TypeScript so I cannot do much about it, it would be great if you can look into it, thanks!

BrainBacon commented 4 years ago

Have you tried an @complete event on the Scene or an @entity event on your Asset?

JustinFincher commented 4 years ago

I have tried the @entity event on Asset and it kinda works, it fired twice upon scene loading, the first time with a default Mesh, isReady = true and getTotalVertices = 24, and the second time the actual Mesh, isReady = true, and getTotalVertices = 0 (I cannot quite get why it is 0 but the 3D object is loaded).
So the reason why the v-model watcher triggered before the GLTF file is actually loaded might be that the entity is firstly initialized with a default value, which instantly triggers my UI changes without checking if the value is the actual GLTF mesh. At this point, my proposal is irrelevant as this is more of a logic/documentation thing, I just have to add the check logic.

undefinederror commented 2 years ago

This isn't so great. I would expect the Asset component to fire events for @success and @fail As it stands now, success can be handled checking the Mesh for children, since @entity (and v-model target) fire twice, the first time being with a placeholder Mesh. I am not sure how to check fail. Keeping a counter and see if it reaches 2? After how long can I be sure it won't reach 2? Should I set a timeout? As you can see this isn't so great.