From 9a5c3f57b76bbb3176705f5fc38091bea152e970 Mon Sep 17 00:00:00 2001 From: 0reo Date: Fri, 4 Mar 2022 16:20:52 -0500 Subject: [PATCH 1/5] vrm template makes and stores toon materials --- type_templates/vrm.js | 148 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 141 insertions(+), 7 deletions(-) diff --git a/type_templates/vrm.js b/type_templates/vrm.js index a7874ca..ff67704 100644 --- a/type_templates/vrm.js +++ b/type_templates/vrm.js @@ -1,7 +1,7 @@ import * as THREE from 'three'; import metaversefile from 'metaversefile'; import { VRMMaterialImporter } from '@pixiv/three-vrm/lib/three-vrm.module'; -const { useApp, useLoaders, usePhysics, useCleanup, useActivate, useLocalPlayer } = metaversefile; +const {useApp, useLoaders, usePhysics, useCleanup, useActivate, useLocalPlayer, getGfxSettingJSON} = metaversefile; const localVector = new THREE.Vector3(); const localVector2 = new THREE.Vector3(); @@ -77,15 +77,103 @@ const _addAnisotropy = (o, anisotropyLevel) => { }); }; +const _setQuality = async (quality, app)=> { + const skinnedVrms = app.skinnedVrms; + const baseVrm = skinnedVrms.base; + + const _swapMaterials = async (type) => { + + //actually do the swap + switch (type) { + case "toon": { + const target = skinnedVrms.toon ?? skinnedVrms.base; + + let update = Object.keys(app.materials.toon).length > 0; + + skinnedVrms.base.scene.traverse((object) => { + if (object.material && app.isBasic(object.material)) { + const name = object.material.name; + app.setMaterial(name, 'base', object.material); + update && (object.material = [app.materials.toon[name]]); + } + + }); + break; + + } + default: { + let update = false; + const target = skinnedVrms.base; + target.scene.traverse((object) => { + if (!update && object.material && app.isToon(object.material)) { + update = true; + } + }); + + target.scene.traverse((object) => { + if (object.material && app.isToon(object.material)) { + const name = object.material[0].name; + update && app.setMaterial(name, 'toon', object.material[0]); + + object.material = app.materials.base[name]; + } + }); + } + } + } + + switch (quality) { + case 'LOW': + case 'MEDIUM': + case 'HIGH': { + await _swapMaterials(); + baseVrm.scene.name = "base mesh" + app.setActive('base'); + break; + } + case 'ULTRA': { + if (skinnedVrms.toon){ + + } else { + if (!skinnedVrms.toon) { + + await _toonShaderify(baseVrm); + skinnedVrms['toon'] = baseVrm; + skinnedVrms.toon.scene.name = 'base-tooned'; + } + } + + await _swapMaterials("toon"); + app.setActive('toon'); + break; + } + default: { + throw new Error('unknown avatar quality: ' + quality); + } + } + return app.getActive(); +} export default e => { const physics = usePhysics(); const app = useApp(); app.appType = 'vrm'; + app.active = 'base'; - const srcUrl = ${ this.srcUrl }; - for (const { key, value } of components) { + //make sure we have materials to work with + app.materials = { + toon: {}, + base: {} + }; + app.isToon = material => material[0] && material[0].isMToonMaterial; + app.isBasic = material => material.type == "MeshBasicMaterial" && material.name; //we're only changing named materials + app.setMaterial = (name, type, material) => app.materials[type][name] = material; + + app.skinnedVrms = {}; + + const srcUrl = ${this.srcUrl}; + for (const {key, value} of components) { app.setComponent(key, value); } @@ -93,26 +181,54 @@ export default e => { const _cloneVrm = async () => { const vrm = await parseVrm(arrayBuffer, srcUrl); vrm.cloneVrm = _cloneVrm; + vrm.toonShaderify = _toonShaderify; return vrm; }; const _prepVrm = (vrm) => { - //vrm.visible = false; //will need later + vrm.visible = false; app.add(vrm); vrm.updateMatrixWorld(); _addAnisotropy(vrm, 16); } + app.getActive = (_app = false) => { + //return scene if we have an active vrm and we're not requesting the scene. else return the(possibly) active vrm + return app.skinnedVrms[app.active] && !_app ? app.skinnedVrms[app.active].scene : app.skinnedVrms[app.active]; + } + + // use this to change which mesh we're using + app.setActive = (target) => { + for (const key in app.skinnedVrms) { + if (Object.hasOwnProperty.call(app.skinnedVrms, key)) { + app.skinnedVrms[key].scene.visible = false + } + } + + app.active = target; + !app.getActive().parent && _prepVrm(app.getActive()); + app.getActive().visible = true; + } + let physicsIds = []; let activateCb = null; e.waitUntil((async () => { arrayBuffer = await _fetchArrayBuffer(srcUrl); const skinnedVrmBase = await _cloneVrm(); - app.skinnedVrm = skinnedVrmBase; - await _toonShaderify(skinnedVrmBase); + app.skinnedVrms['base'] = skinnedVrmBase; + app.skinnedVrm = skinnedVrmBase; //temporary support for webaverse code base until it's updated _prepVrm(skinnedVrmBase.scene); - + app.skinnedVrms.base.scene.name = 'base mesh'; + //collect basic materials for reuse + app.skinnedVrms.base.scene.traverse((o) => { + if (o.material && app.isBasic(o.material)) { + const name = o.material.name; + app.setMaterial(name, 'base', o.material); + } + }); + + const _addPhysics = () => { const fakeHeight = 1.5; localMatrix.compose( @@ -144,7 +260,25 @@ export default e => { localPlayer.setAvatarApp(app); }; + const quality = getGfxSettingJSON('character').details; + await _setQuality(quality, app) + + app.updateQuality = async () => { + const quality = getGfxSettingJSON('character').details; + return await _setQuality(quality, app) + } + + //prep any outstanding meshes + //may not need this yet + for (const type in app.skinnedVrms) { + if (type !== 'base' && Object.hasOwnProperty.call(app.skinnedVrms, type)) { + const vrm = app.skinnedVrms[type]; + vrm && _prepVrm(vrm.isMesh ? vrm : vrm.scene); + } + } + })()); + useActivate(() => { activateCb && activateCb(); From 799327687a2d067411a2ee212b32367217c18d80 Mon Sep 17 00:00:00 2001 From: 0reo Date: Thu, 10 Mar 2022 22:03:33 -0500 Subject: [PATCH 2/5] read quality from localstorage --- type_templates/vrm.js | 61 ++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/type_templates/vrm.js b/type_templates/vrm.js index ff67704..7f4ae21 100644 --- a/type_templates/vrm.js +++ b/type_templates/vrm.js @@ -1,7 +1,7 @@ import * as THREE from 'three'; import metaversefile from 'metaversefile'; import { VRMMaterialImporter } from '@pixiv/three-vrm/lib/three-vrm.module'; -const {useApp, useLoaders, usePhysics, useCleanup, useActivate, useLocalPlayer, getGfxSettingJSON} = metaversefile; +const { useApp, useLoaders, usePhysics, useCleanup, useActivate, useLocalPlayer, /* getGfxSettingJSON */ } = metaversefile; const localVector = new THREE.Vector3(); const localVector2 = new THREE.Vector3(); @@ -77,29 +77,29 @@ const _addAnisotropy = (o, anisotropyLevel) => { }); }; -const _setQuality = async (quality, app)=> { +const _setQuality = async (quality, app) => { const skinnedVrms = app.skinnedVrms; const baseVrm = skinnedVrms.base; - + const _swapMaterials = async (type) => { - + //actually do the swap switch (type) { case "toon": { const target = skinnedVrms.toon ?? skinnedVrms.base; - + let update = Object.keys(app.materials.toon).length > 0; - + skinnedVrms.base.scene.traverse((object) => { if (object.material && app.isBasic(object.material)) { const name = object.material.name; app.setMaterial(name, 'base', object.material); update && (object.material = [app.materials.toon[name]]); } - + }); break; - + } default: { let update = false; @@ -109,12 +109,12 @@ const _setQuality = async (quality, app)=> { update = true; } }); - + target.scene.traverse((object) => { if (object.material && app.isToon(object.material)) { const name = object.material[0].name; update && app.setMaterial(name, 'toon', object.material[0]); - + object.material = app.materials.base[name]; } }); @@ -122,7 +122,7 @@ const _setQuality = async (quality, app)=> { } } - switch (quality) { + switch (quality ?? 'MEDIUM') { case 'LOW': case 'MEDIUM': case 'HIGH': { @@ -132,7 +132,7 @@ const _setQuality = async (quality, app)=> { break; } case 'ULTRA': { - if (skinnedVrms.toon){ + if (skinnedVrms.toon) { } else { if (!skinnedVrms.toon) { @@ -151,7 +151,7 @@ const _setQuality = async (quality, app)=> { throw new Error('unknown avatar quality: ' + quality); } } - return app.getActive(); + return app.getActive(); } export default e => { @@ -169,11 +169,11 @@ export default e => { app.isToon = material => material[0] && material[0].isMToonMaterial; app.isBasic = material => material.type == "MeshBasicMaterial" && material.name; //we're only changing named materials app.setMaterial = (name, type, material) => app.materials[type][name] = material; - + app.skinnedVrms = {}; - - const srcUrl = ${this.srcUrl}; - for (const {key, value} of components) { + + const srcUrl = ${ this.srcUrl }; + for (const { key, value } of components) { app.setComponent(key, value); } @@ -196,7 +196,7 @@ export default e => { //return scene if we have an active vrm and we're not requesting the scene. else return the(possibly) active vrm return app.skinnedVrms[app.active] && !_app ? app.skinnedVrms[app.active].scene : app.skinnedVrms[app.active]; } - + // use this to change which mesh we're using app.setActive = (target) => { for (const key in app.skinnedVrms) { @@ -204,12 +204,12 @@ export default e => { app.skinnedVrms[key].scene.visible = false } } - + app.active = target; !app.getActive().parent && _prepVrm(app.getActive()); app.getActive().visible = true; } - + let physicsIds = []; let activateCb = null; e.waitUntil((async () => { @@ -226,9 +226,9 @@ export default e => { const name = o.material.name; app.setMaterial(name, 'base', o.material); } - }); - - + }); + + const _addPhysics = () => { const fakeHeight = 1.5; localMatrix.compose( @@ -260,14 +260,15 @@ export default e => { localPlayer.setAvatarApp(app); }; - const quality = getGfxSettingJSON('character').details; - await _setQuality(quality, app) - app.updateQuality = async () => { - const quality = getGfxSettingJSON('character').details; - return await _setQuality(quality, app) + // const quality = getGfxSettingJSON('character').details; + // return await _setQuality(quality, app) + const quality = JSON.parse(localStorage.getItem('GfxSettings')); + return await _setQuality(quality?.character.details, app) } - + + await app.updateQuality(); + //prep any outstanding meshes //may not need this yet for (const type in app.skinnedVrms) { @@ -278,7 +279,7 @@ export default e => { } })()); - + useActivate(() => { activateCb && activateCb(); From bdfa7fc4e9557046bbf4a68a263f65bd8a8d7a2d Mon Sep 17 00:00:00 2001 From: Adam Clarke Date: Thu, 10 Mar 2022 22:17:06 -0500 Subject: [PATCH 3/5] remove unused target reference --- type_templates/vrm.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/type_templates/vrm.js b/type_templates/vrm.js index 7f4ae21..bab757c 100644 --- a/type_templates/vrm.js +++ b/type_templates/vrm.js @@ -86,7 +86,6 @@ const _setQuality = async (quality, app) => { //actually do the swap switch (type) { case "toon": { - const target = skinnedVrms.toon ?? skinnedVrms.base; let update = Object.keys(app.materials.toon).length > 0; @@ -324,4 +323,4 @@ export default e => { export const contentId = ${ this.contentId }; export const name = ${ this.name }; export const description = ${ this.description }; -export const components = ${ this.components }; \ No newline at end of file +export const components = ${ this.components }; From dd4e92b97dcb062c681b186f09757eb27d257b6d Mon Sep 17 00:00:00 2001 From: 0reo Date: Thu, 24 Mar 2022 17:40:24 -0400 Subject: [PATCH 4/5] get graphics settings from settings manager --- type_templates/vrm.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/type_templates/vrm.js b/type_templates/vrm.js index bab757c..a1d83ca 100644 --- a/type_templates/vrm.js +++ b/type_templates/vrm.js @@ -1,7 +1,7 @@ import * as THREE from 'three'; import metaversefile from 'metaversefile'; import { VRMMaterialImporter } from '@pixiv/three-vrm/lib/three-vrm.module'; -const { useApp, useLoaders, usePhysics, useCleanup, useActivate, useLocalPlayer, /* getGfxSettingJSON */ } = metaversefile; +const { useApp, useLoaders, usePhysics, useCleanup, useActivate, useLocalPlayer, useSettingsManager } = metaversefile; const localVector = new THREE.Vector3(); const localVector2 = new THREE.Vector3(); @@ -260,10 +260,9 @@ export default e => { }; app.updateQuality = async () => { - // const quality = getGfxSettingJSON('character').details; - // return await _setQuality(quality, app) - const quality = JSON.parse(localStorage.getItem('GfxSettings')); - return await _setQuality(quality?.character.details, app) + const gfxSettings = useSettingsManager().getSettingsJson('GfxSettings'); + const quality = gfxSettings.character.details; + return await _setQuality(quality, app) } await app.updateQuality(); From c72da563db6e1818d76b04429150dc93e1d15734 Mon Sep 17 00:00:00 2001 From: 0reo Date: Thu, 24 Mar 2022 17:41:04 -0400 Subject: [PATCH 5/5] remove premptive prep calls --- type_templates/vrm.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/type_templates/vrm.js b/type_templates/vrm.js index a1d83ca..a31e44e 100644 --- a/type_templates/vrm.js +++ b/type_templates/vrm.js @@ -205,7 +205,7 @@ export default e => { } app.active = target; - !app.getActive().parent && _prepVrm(app.getActive()); + !app.getActive().parent && _prepVrm(app.getActive()); app.getActive().visible = true; } @@ -267,14 +267,6 @@ export default e => { await app.updateQuality(); - //prep any outstanding meshes - //may not need this yet - for (const type in app.skinnedVrms) { - if (type !== 'base' && Object.hasOwnProperty.call(app.skinnedVrms, type)) { - const vrm = app.skinnedVrms[type]; - vrm && _prepVrm(vrm.isMesh ? vrm : vrm.scene); - } - } })());