@fps-games/editor-deployment 0.2.3-beta.15 → 0.2.3-beta.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/fps-editor-prepare.mjs +1 -1
- package/bin/fps-editor-project.mjs +1 -1
- package/licenses/THIRD_PARTY_NOTICES.txt +2 -2
- package/manifest.json +49 -49
- package/npm-shrinkwrap.json +2 -2
- package/package.json +6 -6
- package/public/assets/index-Cv7z0zVA.js +1 -0
- package/public/assets/index-Cv7z0zVA.js.br +0 -0
- package/public/assets/index-Cv7z0zVA.js.gz +0 -0
- package/public/assets/{playable-sdk-D9T6SBmM.js → playable-sdk-DO95mXOf.js} +1 -1
- package/public/assets/playable-sdk-DO95mXOf.js.br +0 -0
- package/public/assets/playable-sdk-DO95mXOf.js.gz +0 -0
- package/public/assets/{playable-standard-project-OE-Ljuvh.js → playable-standard-project-Do0uyGjy.js} +64 -64
- package/public/assets/playable-standard-project-Do0uyGjy.js.br +0 -0
- package/public/assets/playable-standard-project-Do0uyGjy.js.gz +0 -0
- package/public/index.html +3 -3
- package/public/index.html.br +0 -0
- package/public/index.html.gz +0 -0
- package/runtime/editor-control-plane.mjs +4 -96
- package/worker/editor-service-worker.mjs +2 -2
- package/public/assets/index-NHywLCMM.js +0 -1
- package/public/assets/index-NHywLCMM.js.br +0 -0
- package/public/assets/index-NHywLCMM.js.gz +0 -0
- package/public/assets/playable-sdk-D9T6SBmM.js.br +0 -0
- package/public/assets/playable-sdk-D9T6SBmM.js.gz +0 -0
- package/public/assets/playable-standard-project-OE-Ljuvh.js.br +0 -0
- package/public/assets/playable-standard-project-OE-Ljuvh.js.gz +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{fD as he,fC as me,a4 as be,eu as ye,mt as ge,iV as we,fu as Se,ca as Ie,jM as Ee,hW as Me}from"./playable-standard-project-OE-Ljuvh.js";import{registerFpsEditorContribution as je}from"@fps-games/editor-core/plugin-host";import"./hemisphericLight-C4swwL68.js";(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))n(i);new MutationObserver(i=>{for(const r of i)if(r.type==="childList")for(const s of r.addedNodes)s.tagName==="LINK"&&s.rel==="modulepreload"&&n(s)}).observe(document,{childList:!0,subtree:!0});function o(i){const r={};return i.integrity&&(r.integrity=i.integrity),i.referrerPolicy&&(r.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?r.credentials="include":i.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function n(i){if(i.ep)return;i.ep=!0;const r=o(i);fetch(i.href,r)}})();const _e="0.2.3-beta.15",Z="fps.plugin.hierarchy";function xe(){return he({id:Z,version:_e,apiVersion:1,requires:{},provides:{features:["fps.editor.hierarchy"]},entries:{editor:"./editor"},environmentContracts:{editor:{requires:{services:["fps.editor.contributions"]},provides:{}}},deploymentConstraints:{allowedTargets:["editor"]}})}const Pe=me({pluginId:Z,environment:"editor",register(e){je(e,{id:be,kind:"hierarchy",value:ye()})}}),Oe=256*1024,ee=1024*1024,Ae=new Set(["snapshot","list","search","describe","execute","executeBatch"]),B=new Set(["surfaceInstanceId","projectId","runtimeGeneration"]),$e=new Set(["requestId","operation","payload","expected"]);function Te(e){return typeof e=="string"&&Ae.has(e)}function Fe(e){if(!e||typeof e!="object"||Array.isArray(e))return!1;const t=e,o=Reflect.ownKeys(t);return o.length===B.size&&o.every(n=>B.has(n))&&C(t.surfaceInstanceId,128)&&C(t.projectId,256)&&C(t.runtimeGeneration,256)}function ve(e){if(!e||typeof e!="object"||Array.isArray(e))return!1;const t=e;return Ce(t,$e)&&C(t.requestId,256)&&Te(t.operation)&&Fe(t.expected)}function te(e,t,o){let n;try{re(e,new Set,0),n=JSON.stringify(e)}catch{throw new Error(`${o} must be JSON-safe.`)}if(new TextEncoder().encode(n).byteLength>t)throw new Error(`${o} exceeds the ${t} byte limit.`)}function Re(e,t){return e.surfaceInstanceId===t.surfaceInstanceId&&e.projectId===t.projectId&&e.runtimeGeneration===t.runtimeGeneration}function re(e,t,o){if(e===null||typeof e=="string"||typeof e=="boolean")return;if(typeof e=="number"){if(!Number.isFinite(e))throw new Error("Non-finite number.");return}if(typeof e!="object")throw new Error(`Unsupported ${typeof e}.`);if(o>=64)throw new Error("Maximum nesting depth exceeded.");if(t.has(e))throw new Error("Cyclic value.");const n=Object.getPrototypeOf(e);if(!Array.isArray(e)&&n!==Object.prototype&&n!==null)throw new Error("Non-plain object.");if(Reflect.ownKeys(e).some(i=>typeof i!="string"))throw new Error("Symbol-keyed value.");t.add(e);for(const i of Array.isArray(e)?e:Object.values(e))re(i,t,o+1);t.delete(e)}function C(e,t){return typeof e=="string"&&e.length>0&&e.length<=t}function Ce(e,t){return Reflect.ownKeys(e).every(o=>t.has(o))}function De(e){const t=ze(e.endpointBase),o=e.fetch??e.ownerWindow.fetch.bind(e.ownerWindow),n=Object.freeze({surfaceInstanceId:e.surfaceInstanceId?.trim()||Le(e.ownerWindow),projectId:e.api.projectId,runtimeGeneration:e.api.runtimeGeneration}),i=Number.isSafeInteger(e.retryDelayMs)&&e.retryDelayMs>0?e.retryDelayMs:500,r=new AbortController;let s=null,a=!1,u=Promise.resolve();const b=async(c,h,w)=>(te(h,c==="result"?ee:Oe,`Editor Surface ${c} payload`),o(`${t}/${c}`,{method:"POST",cache:"no-store",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify(h),signal:w})),d=async()=>{const c=await b("register",{identity:n},r.signal),h=await c.json().catch(()=>null);if(!c.ok||typeof h?.leaseId!="string"||!h.leaseId)throw new Error(`Editor Surface registration failed with HTTP ${c.status}.`);return h.leaseId};return u=(async()=>{for(;!a;)try{s||(s=await d());const c=await b("poll",{leaseId:s,identity:n},r.signal);if(c.status===204)continue;const h=await c.json().catch(()=>null);if(!c.ok||!ve(h?.request))throw new Error(`Editor Surface poll failed with HTTP ${c.status}.`);const w=h.request,m=await Ne(e.ownerWindow,e.api,n,w),l=await b("result",{leaseId:s,identity:n,result:m},r.signal);if(!l.ok&&l.status!==404)throw new Error(`Editor Surface receipt failed with HTTP ${l.status}.`)}catch{if(a||r.signal.aborted)return;s=null,await Be(i,r.signal).catch(()=>{})}})(),Object.freeze({identity:n,async dispose(){if(a)return;a=!0,r.abort();const c=s;s=null,c&&await b("dispose",{leaseId:c,identity:n}).catch(()=>{}),await u.catch(()=>{})}})}async function Ne(e,t,o,n){let i;try{if(!Re(n.expected,o))throw R("editor.surfaceMismatch","Editor Surface identity changed before execution.",!0);if(e.__FPS_EDITOR_API__!==t)throw R("editor.surfaceDisposed","Editor Surface was disposed or refreshed.",!0);const r=await ke(t,n.operation,n.payload);i=Object.freeze({requestId:n.requestId,ok:!0,result:r})}catch(r){i=Object.freeze({requestId:n.requestId,ok:!1,error:Ue(r)?r:R("editor.executionFailed",r instanceof Error?r.message:String(r),!1)})}try{return te(i,ee,"Editor Surface result"),i}catch{const r=n.operation==="execute"||n.operation==="executeBatch";return Object.freeze({requestId:n.requestId,ok:!1,error:R(r?"editor.outcomeUnknown":"editor.resultTooLarge",r?"Editor capability execution completed, but its result exceeds the Surface response budget. The Browser Draft may have changed; inspect current state and do not blindly retry.":"Editor capability result exceeds the Surface response budget.",!r,{requestId:n.requestId,operation:n.operation,...qe(n.payload),target:o})})}}async function ke(e,t,o){switch(t){case"snapshot":return e.capabilities.snapshot();case"list":return e.capabilities.list(o);case"search":return e.capabilities.search(o);case"describe":if(typeof o!="string")throw R("editor.invalidRequest","describe requires a capabilityId string.",!0);return e.capabilities.describe(o);case"execute":return e.capabilities.execute(o);case"executeBatch":return e.capabilities.executeBatch(o)}}function R(e,t,o,n){return Object.freeze({code:e,message:t,retrySafe:o,...n!==void 0?{details:n}:{}})}function Ue(e){return!!e&&typeof e=="object"&&typeof e.code=="string"&&typeof e.message=="string"&&typeof e.retrySafe=="boolean"}function ze(e){const t=typeof e=="string"?e.trim().replace(/\/$/,""):"";if(!t)throw new Error("Editor Surface endpoint is required.");return t}function Le(e){const t=e.crypto?.randomUUID?.bind(e.crypto);return t?t():`surface-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}async function Be(e,t){t.aborted||await new Promise(o=>{let n=!1;const i=()=>{n||(n=!0,clearTimeout(r),t.removeEventListener("abort",i),o())},r=setTimeout(i,e);t.addEventListener("abort",i,{once:!0})})}function qe(e){if(!e||typeof e!="object"||Array.isArray(e))return Object.freeze({});const t=e.traceId;return typeof t=="string"&&t.length>0&&t.length<=256?Object.freeze({traceId:t}):Object.freeze({})}const Ve=1e3,He=5e3,Ge="Project I/O health request failed.";function We(e){const t=Qe(e.endpointBase),o=q(e.pollIntervalMs,Ve),n=q(e.requestTimeoutMs,He);let i=Je(e.initial),r=!1,s=null,a=null;const u=new Set,b=c=>{if(!Ye(i,c)){i=c;for(const h of u)h(c)}},d=()=>{r||(s=e.ownerWindow.setTimeout(f,o))},f=async()=>{if(s=null,r)return;const c=new AbortController;a=c;const h=e.ownerWindow.setTimeout(()=>c.abort(),n);try{const w=await e.fetchJson(`${t}/health`,{cache:"no-store",signal:c.signal});b(Ke(w))}catch{r||b(Object.freeze({ready:!1,generation:i.generation,reason:Ge}))}finally{e.ownerWindow.clearTimeout(h),a===c&&(a=null),d()}};return d(),Object.freeze({availability:Object.freeze({getAvailability:()=>i,subscribeAvailability(c){return r?()=>{}:(u.add(c),()=>u.delete(c))}}),stop(){r||(r=!0,s!==null&&e.ownerWindow.clearTimeout(s),s=null,a?.abort(),a=null,u.clear())}})}function Ke(e){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("Project I/O health response must be an object.");const t=e;if(t.schemaVersion!==1||t.kind!=="project-io"||typeof t.ready!="boolean"||!Number.isSafeInteger(t.generation)||t.status!=="ready"&&t.status!=="unavailable")throw new Error("Project I/O health response is invalid.");const o=String(t.generation);return t.ready&&t.status==="ready"?Object.freeze({ready:!0,generation:o}):Object.freeze({ready:!1,generation:o,reason:typeof t.reason=="string"&&t.reason.trim()?t.reason:"Project I/O is unavailable."})}function Je(e){const t=e.generation?.trim();if(!t)throw new Error("Project I/O initial generation is required.");return e.ready?Object.freeze({ready:!0,generation:t}):Object.freeze({ready:!1,generation:t,reason:e.reason?.trim()||"Project I/O is unavailable."})}function Ye(e,t){return e.ready===t.ready&&e.generation===t.generation&&(e.ready||t.ready||e.reason===t.reason)}function Qe(e){const t=typeof e=="string"?e.trim().replace(/\/$/,""):"";if(!t)throw new Error("Project I/O endpoint is required.");return t}function q(e,t){return Number.isSafeInteger(e)&&e>0?e:t}async function Xe(e){let t=null,o=!1,n=Promise.resolve(),i=null,r=null;const s=e.container.ownerDocument,a=s.defaultView??window;let u=null;if(!e.projectIOAvailability&&e.projectIOInitialAvailability&&e.authoringEndpointBase){const l=e.authoringFetchJson??(async(p,y)=>{const g=await a.fetch(p,y),E=await g.json().catch(()=>null);if(!g.ok)throw new Error(`Project I/O health request failed (${g.status}).`);return E});u=We({endpointBase:e.authoringEndpointBase,initial:e.projectIOInitialAvailability,ownerWindow:a,fetchJson:l})}const b=e.projectIOAvailability??u?.availability,d=s.createElement("canvas");d.id="renderCanvas",d.style.cssText="display:block;width:100%;height:100%;touch-action:none;outline:none";const f=()=>{i?.(),i=null,d.remove()},c=l=>{const p=n.then(l,l);return n=p.catch(()=>{}),p},h=()=>{const l=a.__FPS_EDITOR_API__;if(!l)throw new Error("Browser Editor API is unavailable.");return l},w=async(l,p)=>{const y=t?.getHost();if(!y)throw new Error("Editor host is unavailable for asset import.");const g=p?y.harness.projectAssetDropPoint({space:"scene-view-normalized",x:p.x,y:p.y}):null,E=l.objectId??Se([],`${l.assetName??l.projectAssetId??"asset"}_${Ie()}`),S=await h().capabilities.execute({capabilityId:"asset.importAndPlace",input:{...l,objectId:E,...g?{position:g}:{}}});if(S.outcome!=="applied"&&S.outcome!=="no-op")throw new Error(S.diagnostics[0]?.message??"Browser asset import and placement failed.")};async function m(){if(o)return;let l=null;try{const p=ge(e.projectDefinition);i?.(),i=Ze(a,e.runtimeAssetBaseUrl),d.parentNode!==e.container&&e.container.appendChild(d);const y=xe(),g=Object.freeze({environment:"editor",buildTarget:"editor",manifests:Object.freeze([y]),entries:Object.freeze([{pluginId:y.id,config:null,load:async()=>Pe}]),pluginConfigs:Object.freeze({...Object.fromEntries(p.plugins.map(S=>[S.pluginId,S.config])),[y.id]:null})});if(l=await we(p.project,{root:e.container,window:a,authoringEndpointBase:e.authoringEndpointBase,authoringFetchJson:e.authoringFetchJson,projectIOAvailability:b,onExternalAssetDrop:e.onExternalAssetDrop?async S=>{const v=await e.onExternalAssetDrop?.(S);v&&await w(v,{x:S.point.sceneX,y:S.point.sceneY})}:void 0,projectMode:{async enterEditorMode(){},...e.onEnterPlayMode?{enterPlayMode:e.onEnterPlayMode}:{}},pluginModule:g,getCanvas:()=>d,...e.materialShaderDefinitions?{materialShaderDefinitions:e.materialShaderDefinitions}:{},...e.materialProjectionAdapters?{materialProjectionAdapters:e.materialProjectionAdapters}:{}}),o){await l.dispose(),f();return}t=l,await l.enterEditor(),e.surfaceEndpointBase&&(r=De({endpointBase:e.surfaceEndpointBase,ownerWindow:a,api:h()}));const E=a.__FPS_EDITOR_SYSTEM_FUNCTIONAL_REGISTER__;typeof E=="function"&&E(Object.freeze({readDraft(){const S=t?.getHost()?.harness,v=S?.getWorkingDocument(),z=S?.getPersistedDocument(),L=S?.getDocumentState();return v&&z&&L?Object.freeze({summary:L,workingDocument:v,persistedDocument:z}):null}}))}catch(p){t===l&&(t=null);let y=null;try{const g=r;r=null,await g?.dispose(),await l?.dispose()}catch(g){y=g}finally{f()}if(y){const g=y instanceof Error?y.message:String(y),E=new Error(`Editor mount failed and cleanup also failed: ${g}`);throw Object.assign(E,{cause:p,cleanupError:y}),E}throw p}}try{await c(m)}catch(l){throw u?.stop(),u=null,l}return{async save(){if(!t?.getHost())return!1;const l=await h().capabilities.execute({capabilityId:"document.save",input:{}});return l.outcome==="applied"||l.outcome==="no-op"},reload(){return c(async()=>{const l=t,p=r;t=null,r=null;try{await p?.dispose(),await l?.dispose()}finally{f()}await m()})},async importAsset({point:l,...p}){await w(p,l)},dispose(){return o=!0,u?.stop(),u=null,c(async()=>{a.__FPS_EDITOR_SYSTEM_FUNCTIONAL_REGISTER__?.(null);const l=t,p=r;t=null,r=null;try{await p?.dispose(),await l?.dispose()}finally{f()}})}}}function Ze(e,t){const o=e,n=Object.getOwnPropertyDescriptor(o,"__FPS_EDITOR_RUNTIME_URL__");t&&(o.__FPS_EDITOR_RUNTIME_URL__=t);let i=!1;return()=>{i||(i=!0,t&&o.__FPS_EDITOR_RUNTIME_URL__===t&&(n?Object.defineProperty(o,"__FPS_EDITOR_RUNTIME_URL__",n):delete o.__FPS_EDITOR_RUNTIME_URL__))}}const M=(e,t)=>({kind:"number",...e!=null?{min:e}:{},...t!=null?{max:t}:{}}),x={kind:"texture"},V={kind:"color"},et={kind:"enum",values:["lit","unlit"]},tt={kind:"enum",values:["opaque","mask","blend"]},ne={lightingModel:et,baseColor:{kind:"object",properties:{color:V,texture:x,brightness:M(0),saturation:M(0),contrast:M(0),hue:M(-180,180)}},normal:{kind:"object",properties:{texture:x,strength:M(0)}},emission:{kind:"object",properties:{color:V,intensity:M(0),texture:x,maskTexture:x}},alpha:{kind:"object",properties:{mode:tt,opacity:M(0,1),cutoff:M(0,1),texture:x}}},rt={kind:"object",properties:{...ne,metallic:M(0,1),roughness:M(0,1),metallicRoughness:{kind:"object",properties:{texture:x}},occlusion:{kind:"object",properties:{texture:x,strength:M(0)}}}},nt={kind:"object",properties:ne},ot={lightingModel:"lit",baseColor:{color:{r:1,g:1,b:1},brightness:1,saturation:1,contrast:1,hue:0},metallic:0,roughness:1,emission:{color:{r:0,g:0,b:0},intensity:0}},it={lightingModel:"lit",baseColor:{color:{r:1,g:1,b:1},brightness:1,saturation:1,contrast:1,hue:0},emission:{color:{r:0,g:0,b:0},intensity:0}},H=[{id:"surface",title:"Surface",order:40},{id:"geometry",title:"Geometry",order:50},{id:"emission",title:"Emission",order:60},{id:"alpha",title:"Alpha",order:70}],P={path:"properties.lightingModel",operator:"equals",value:"lit",inactiveReasonKey:"litMaterial"},oe=[$("properties.lightingModel","surface",1,"enum","assetLightingModel","lightingModel","lit",{options:[{value:"lit",labelKey:"assetLightingModelLit"},{value:"unlit",labelKey:"assetLightingModelUnlit"}],binding:"lightingModel",updateClass:"define"}),$("properties.baseColor.color","surface",2,"color","assetBaseColor","baseColor",{r:1,g:1,b:1},{binding:"baseColor.color"}),T("properties.baseColor.texture.textureAssetId","properties.baseColor.texture","surface",3,"assetBaseTexture","baseTexture","baseColor.texture"),j("properties.baseColor.brightness","surface",4,"assetBrightness","brightness",1,{softMin:0,softMax:4,step:.05,conditions:[O("properties.baseColor.texture.textureAssetId","baseTexture")]}),j("properties.baseColor.saturation","surface",5,"assetSaturation","saturation",1,{softMin:0,softMax:2,step:.05,conditions:[O("properties.baseColor.texture.textureAssetId","baseTexture")]}),j("properties.baseColor.contrast","surface",6,"assetContrast","contrast",1,{softMin:0,softMax:2,step:.05,conditions:[O("properties.baseColor.texture.textureAssetId","baseTexture")]}),j("properties.baseColor.hue","surface",7,"assetHue","hue",0,{step:1,conditions:[O("properties.baseColor.texture.textureAssetId","baseTexture")]}),T("properties.normal.texture.textureAssetId","properties.normal.texture","geometry",10,"assetNormalTexture","normalTexture","normal.texture",[P]),j("properties.normal.strength","geometry",11,"assetNormalStrength","normalStrength",1,{softMin:0,softMax:4,step:.05,conditions:[P,O("properties.normal.texture.textureAssetId","normalTexture")]}),$("properties.emission.color","emission",50,"color","assetEmissionColor","emissionColor",{r:0,g:0,b:0},{binding:"emission.color"}),j("properties.emission.intensity","emission",51,"assetEmissionIntensity","emissionIntensity",0,{softMin:0,softMax:8,step:.05}),T("properties.emission.texture.textureAssetId","properties.emission.texture","emission",52,"assetEmissionTexture","emissionTexture","emission.texture"),$("properties.alpha.mode","alpha",60,"enum","assetAlphaMode","alphaMode","opaque",{options:[{value:"opaque",labelKey:"assetAlphaModeOpaque"},{value:"mask",labelKey:"assetAlphaModeMask"},{value:"blend",labelKey:"assetAlphaModeBlend"}],binding:"alpha.mode",updateClass:"pipeline"}),j("properties.alpha.opacity","alpha",61,"assetAlphaOpacity","alphaOpacity",1,{step:.05,conditions:[{path:"properties.alpha.mode",operator:"equals",value:"blend",inactiveReasonKey:"alphaBlend"}]}),j("properties.alpha.cutoff","alpha",62,"assetAlphaCutoff","alphaCutoff",.5,{step:.01,conditions:[{path:"properties.alpha.mode",operator:"equals",value:"mask",inactiveReasonKey:"alphaMask"}]}),T("properties.alpha.texture.textureAssetId","properties.alpha.texture","alpha",63,"assetAlphaTexture","alphaTexture","alpha.texture",[{path:"properties.alpha.mode",operator:"not-equals",value:"opaque",inactiveReasonKey:"alphaTransparency"}])],at=[...oe,j("properties.metallic","geometry",20,"assetMetallic","metallic",0,{step:.05,conditions:[P]}),j("properties.roughness","geometry",21,"assetRoughness","roughness",1,{step:.05,conditions:[P]}),T("properties.metallicRoughness.texture.textureAssetId","properties.metallicRoughness.texture","geometry",22,"assetMetallicRoughnessTexture","metallicRoughnessTexture","metallicRoughness.texture",[P]),T("properties.occlusion.texture.textureAssetId","properties.occlusion.texture","geometry",23,"assetOcclusionTexture","occlusionTexture","occlusion.texture",[P]),j("properties.occlusion.strength","geometry",24,"assetOcclusionStrength","occlusionStrength",1,{softMin:0,softMax:4,step:.05,conditions:[P,O("properties.occlusion.texture.textureAssetId","occlusionTexture")]})],ie=[{shaderId:"fps.builtin.pbr",version:1,runtimeKind:"pbr",displayName:"PBR",propertiesSchema:rt,defaultProperties:ot,inspector:{sections:H,fields:at}},{shaderId:"fps.builtin.standard",version:1,runtimeKind:"standard",displayName:"Standard",propertiesSchema:nt,defaultProperties:it,inspector:{sections:H,fields:oe}}];ae(ie);function ae(e){const t=new Map;for(const n of e){st(n,t);const i=ct(n);t.set(n.shaderId,de(i))}const o=Object.freeze([...t.values()]);return Object.freeze({get(n){return typeof n=="string"?t.get(n)??null:null},list(){return o}})}function $(e,t,o,n,i,r,s,a){return{path:e,sectionId:t,order:o,control:n,labelKey:i,tooltipKey:r,defaultValue:s,updateClass:"uniform",...a}}function j(e,t,o,n,i,r,s={}){return $(e,t,o,"number",n,i,r,{binding:e.replace(/^properties\./,""),step:s.step??.05,displayPrecision:2,precision:2,...s})}function T(e,t,o,n,i,r,s,a){return $(e,o,n,"texture",i,r,"",{schemaPath:t,binding:s,updateClass:"texture",conditions:a})}function O(e,t){return{path:e,operator:"truthy",inactiveReasonKey:t}}function st(e,t){if(!Ee(e.shaderId)&&!Me(e.shaderId))throw new Error("Material Shader Definition shaderId must be a supported built-in id or a lowercase namespaced project id.");if(!Number.isInteger(e.version)||e.version<=0)throw new Error(`Material Shader Definition ${e.shaderId} must use a positive integer version.`);if(t.has(e.shaderId))throw new Error(`Duplicate Material Shader Definition: ${e.shaderId}`);if(e.sourceFile!=null&&!dt(e.sourceFile))throw new Error(`Material Shader Definition ${e.shaderId} sourceFile must be a safe project-relative path.`);se(e.shaderId,e.propertiesSchema,"properties");const o=[];if(le(e.propertiesSchema,e.defaultProperties,"properties",o),o.length>0){const r=o[0];throw new Error(`Material Shader Definition ${e.shaderId} default ${r.path} ${r.message}.`)}const n=new Set;for(const r of e.inspector.sections){if(!r.id.trim()||n.has(r.id))throw new Error(`Material Shader Definition ${e.shaderId} contains an invalid or duplicate section: ${r.id}`);n.add(r.id)}const i=new Set;for(const r of e.inspector.fields){if(!r.path.startsWith("properties.")||i.has(r.path))throw new Error(`Material Shader Definition ${e.shaderId} contains an invalid or duplicate field: ${r.path}`);if(!n.has(r.sectionId))throw new Error(`Material Shader Definition ${e.shaderId} field ${r.path} references an unknown section.`);lt(e,r),i.add(r.path)}}function ct(e){const t=structuredClone(e);return{...t,inspector:{...t.inspector,fields:t.inspector.fields.map(o=>{if(o.control!=="number")return o;const n=ce(t.propertiesSchema,o.schemaPath??o.path);return n?.kind!=="number"?o:{...o,...n.min!=null?{min:n.min}:{},...n.max!=null?{max:n.max}:{}}})}}}function lt(e,t){const o=[["min",t.min],["max",t.max],["softMin",t.softMin],["softMax",t.softMax]];for(const[i,r]of o)if(r!=null&&!Number.isFinite(r))throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} ${i} must be finite.`);if(t.control!=="number"){if(o.some(([,i])=>i!=null))throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} uses numeric ranges with a non-number control.`);return}const n=ce(e.propertiesSchema,t.schemaPath??t.path);if(n?.kind!=="number")throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} must reference a number schema.`);for(const[i,r,s]of[["min",t.min,n.min],["max",t.max,n.max]])if(r!=null&&r!==s)throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} ${i} must match propertiesSchema.`);if(t.softMin!=null&&t.softMax!=null&&t.softMin>t.softMax)throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} softMin must not exceed softMax.`);if(n.min!=null&&t.softMin!=null&&t.softMin<n.min)throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} softMin must not be below the schema minimum.`);if(n.max!=null&&t.softMax!=null&&t.softMax>n.max)throw new Error(`Material Shader Definition ${e.shaderId} field ${t.path} softMax must not exceed the schema maximum.`)}function se(e,t,o){if(t.kind==="object"){for(const[n,i]of Object.entries(t.properties))se(e,i,`${o}.${n}`);return}if(t.kind==="number"){if(t.min!=null&&!Number.isFinite(t.min))throw new Error(`Material Shader Definition ${e} number field ${o} min must be finite.`);if(t.max!=null&&!Number.isFinite(t.max))throw new Error(`Material Shader Definition ${e} number field ${o} max must be finite.`);if(t.min!=null&&t.max!=null&&t.min>t.max)throw new Error(`Material Shader Definition ${e} number field ${o} min must not exceed max.`);return}if(t.kind==="color"&&t.channels!=null&&t.channels!==3&&t.channels!==4)throw new Error(`Material Shader Definition ${e} color field ${o} channels must be 3 or 4.`)}function dt(e){const t=e.trim();return!t||t.startsWith("/")||t.includes("\\")||t.includes(":")?!1:!t.split("/").includes("..")}function ut(e){const t=e.trim();return t.startsWith("properties.")?t:`properties.${t}`}function ce(e,t){const o=ut(t).replace(/^properties\./,"").split(".").filter(Boolean);if(o.length===0)return null;let n=e;for(const i of o){if(n.kind!=="object")return null;const r=n.properties[i];if(!r)return null;n=r}return n}function le(e,t,o,n){if(e.kind==="object"){if(!N(t)){n.push({path:o,message:"must be an object"});return}for(const r of Object.keys(t))Object.prototype.hasOwnProperty.call(e.properties,r)||n.push({path:`${o}.${r}`,message:"is not supported by the selected shader"});for(const[r,s]of Object.entries(e.properties))t[r]!==void 0&&le(s,t[r],`${o}.${r}`,n);return}if(e.kind==="number"){if(typeof t!="number"||!Number.isFinite(t)){n.push({path:o,message:"must be a finite number"});return}e.min!=null&&t<e.min&&n.push({path:o,message:`must be greater than or equal to ${e.min}`}),e.max!=null&&t>e.max&&n.push({path:o,message:`must be less than or equal to ${e.max}`});return}if(e.kind==="boolean"){typeof t!="boolean"&&n.push({path:o,message:"must be a boolean"});return}if(e.kind==="string"){t!==null&&typeof t!="string"?n.push({path:o,message:"must be a string"}):t===null&&!e.nullable&&n.push({path:o,message:"must not be null"});return}if(e.kind==="enum"){(typeof t!="string"||!e.values.includes(t))&&n.push({path:o,message:`must be one of: ${e.values.join(", ")}`});return}if(e.kind==="color"){const r=e.channels===4?["r","g","b","a"]:["r","g","b"];G(t,o,r,n,e.channels===4?"an RGBA object":"an RGB object");return}if(e.kind==="vec2"||e.kind==="vec3"){G(t,o,e.kind==="vec2"?["x","y"]:["x","y","z"],n,`a ${e.kind} object`);return}if(t===null)return;if(!N(t)){n.push({path:o,message:"must be a texture reference object or null"});return}Object.keys(t).some(r=>r!=="url"&&r!=="textureAssetId")&&n.push({path:o,message:"must contain only url or textureAssetId"});for(const r of["url","textureAssetId"]){const s=t[r];s!==void 0&&(typeof s!="string"||!s.trim())&&n.push({path:`${o}.${r}`,message:"must be a non-empty string"})}}function G(e,t,o,n,i){if(!N(e)){n.push({path:t,message:`must be ${i}`});return}Object.keys(e).some(r=>!o.includes(r))&&n.push({path:t,message:`must contain only ${o.join(", ")}`});for(const r of o)(typeof e[r]!="number"||!Number.isFinite(e[r]))&&n.push({path:`${t}.${r}`,message:"must be a finite number"})}function de(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){Object.freeze(e);for(const t of Object.values(e))de(t)}return e}function N(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}const pt=Object.freeze([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),ft=Object.freeze([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]);function k(e){return mt(new TextEncoder().encode(e))}function ht(e){return`sha256:${k(JSON.stringify(e))}`}function mt(e){const t=Math.ceil((e.length+9)/64)*64,o=new Uint8Array(t);o.set(e),o[e.length]=128;const n=new DataView(o.buffer);n.setUint32(t-8,Math.floor(e.length/536870912),!1),n.setUint32(t-4,e.length*8>>>0,!1);const i=[...pt],r=new Uint32Array(64);for(let s=0;s<o.length;s+=64){for(let m=0;m<16;m+=1)r[m]=n.getUint32(s+m*4,!1);for(let m=16;m<64;m+=1){const l=r[m-15],p=r[m-2],y=_(l,7)^_(l,18)^l>>>3,g=_(p,17)^_(p,19)^p>>>10;r[m]=r[m-16]+y+r[m-7]+g>>>0}let[a,u,b,d,f,c,h,w]=i;for(let m=0;m<64;m+=1){const l=_(f,6)^_(f,11)^_(f,25),p=f&c^~f&h,y=w+l+p+ft[m]+r[m]>>>0,g=_(a,2)^_(a,13)^_(a,22),E=a&u^a&b^u&b,S=g+E>>>0;w=h,h=c,c=f,f=d+y>>>0,d=b,b=u,u=a,a=y+S>>>0}i[0]=i[0]+a>>>0,i[1]=i[1]+u>>>0,i[2]=i[2]+b>>>0,i[3]=i[3]+d>>>0,i[4]=i[4]+f>>>0,i[5]=i[5]+c>>>0,i[6]=i[6]+h>>>0,i[7]=i[7]+w>>>0}return i.map(s=>s.toString(16).padStart(8,"0")).join("")}function _(e,t){return e>>>t|e<<32-t}const bt="fps.plugin.materials";function yt(e){const t=e?.[bt];if(t==null)return null;if(!A(t)||t.schemaVersion!==1||typeof t.snapshotId!="string"||!Array.isArray(t.shaders))throw new Error("Materials Plugin snapshot is invalid. Run fps-editor-prepare again.");const o=structuredClone(t);return gt(o),pe(o)}function ue(e){return ae([...ie,...e?.shaders.map(t=>t.definition)??[]])}function gt(e){if(!/^sha256:[a-f0-9]{64}$/.test(e.snapshotId)||e.shaders.length===0)throw new Error("Materials Plugin snapshot identity is invalid. Run fps-editor-prepare again.");for(const o of e.shaders)if(!A(o)||!A(o.definition)||!A(o.program))throw new Error("Materials Plugin Shader snapshot is invalid. Run fps-editor-prepare again.");ue(e);for(const o of e.shaders){const{definition:n,program:i}=o;if(i.shaderId!==n.shaderId||i.definitionVersion!==n.version)throw new Error(`Material snapshot Definition identity does not match its program: ${n.shaderId}`);if(i.language!=="glsl"||!W(i.vertexSourcePath)||!W(i.fragmentSourcePath)||!/^[a-f0-9]{64}$/.test(i.vertexSourceHash)||!/^[a-f0-9]{64}$/.test(i.fragmentSourceHash)||typeof i.vertexSource!="string"||!i.vertexSource.trim()||typeof i.fragmentSource!="string"||!i.fragmentSource.trim())throw new Error(`Material snapshot program is invalid: ${n.shaderId}`);if(k(i.vertexSource)!==i.vertexSourceHash||k(i.fragmentSource)!==i.fragmentSourceHash)throw new Error(`Material snapshot source hash does not match its GLSL content: ${n.shaderId}`);if(!Array.isArray(i.attributes)||i.attributes.length===0||i.attributes.some(r=>!/^[A-Za-z_][A-Za-z0-9_]*$/.test(r))||new Set(i.attributes).size!==i.attributes.length)throw new Error(`Material snapshot attributes are invalid: ${n.shaderId}`);if(!["opaque","combine","add"].includes(i.alphaMode)||!A(i.enumUniformValues)||!A(i.frame)||!["on-demand","continuous"].includes(i.frame.mode))throw new Error(`Material snapshot rendering policy is invalid: ${n.shaderId}`)}const t={schemaVersion:e.schemaVersion,shaders:e.shaders};if(ht(t)!==e.snapshotId)throw new Error("Materials Plugin snapshot payload does not match its identity. Run fps-editor-prepare again.")}function W(e){return typeof e=="string"&&!!e&&!e.startsWith("/")&&!e.includes("\\")&&!e.includes(":")&&e.split("/").every(t=>!!t&&t!=="."&&t!=="..")}function pe(e){if(!e||typeof e!="object"||Object.isFrozen(e))return e;for(const t of Object.values(e))pe(t);return Object.freeze(e)}function A(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function wt(e){let t=0;const o=new WeakMap;return Object.freeze(e.shaders.map(({definition:n,program:i})=>Object.freeze({shaderId:n.shaderId,definitionVersion:n.version,snapshotId:e.snapshotId,createMaterial(r){const s=r.babylon,a=`${_t(n.shaderId)}-${t+=1}`;if(!s.Effect?.ShadersStore||!s.ShaderMaterial||!s.StandardMaterial||!s.Color3)throw new Error(`Babylon ShaderMaterial is unavailable for ${n.shaderId}.`);K(n,r.definitionVersion),s.Effect.ShadersStore[`${a}VertexShader`]=i.vertexSource,s.Effect.ShadersStore[`${a}FragmentShader`]=i.fragmentSource;const u=n.inspector.fields.filter(l=>l.updateClass==="uniform").map(l=>l.binding),b=[...new Set(["world","worldViewProjection",...i.frame.timeUniform?[i.frame.timeUniform]:[],...i.frame.cameraPositionUniform?[i.frame.cameraPositionUniform]:[],...u])];let d;try{d=new s.ShaderMaterial(a,r.scene,{vertex:a,fragment:a},{attributes:i.attributes,uniforms:b,needAlphaBlending:i.alphaMode!=="opaque"}),d.backFaceCulling=i.alphaMode==="opaque",d.alphaMode=i.alphaMode==="add"?s.Constants.ALPHA_ADD:i.alphaMode==="combine"?s.Constants.ALPHA_COMBINE:s.Constants.ALPHA_DISABLE,J(s,d,n,i,r.properties)}catch(l){throw delete s.Effect.ShadersStore[`${a}VertexShader`],delete s.Effect.ShadersStore[`${a}FragmentShader`],d?.dispose?.(),l}const f=St(s,r.scene,a),c={material:d,mesh:r.mesh,setMaterial:r.setMaterial,placeholder:f,compiled:!1,disposed:!1,failed:!1,failure:null,compilation:null,invalidateFrameParticipant:null,shaderName:a,shadersStore:s.Effect.ShadersStore};o.set(f,c),o.set(d,c);const h=()=>{c.disposed||c.failed||c.compiled||(c.compiled=!0,c.setMaterial(c.material),Et(c.mesh))},w=l=>{c.disposed||c.failed||(c.failed=!0,c.failure=l,c.invalidateFrameParticipant?.(),c.setMaterial(c.placeholder),It(c.mesh,{code:"material.shaderCompilationFailed",severity:"error",shaderId:n.shaderId,definitionVersion:n.version,snapshotId:e.snapshotId,message:String(l??"Shader compilation failed.").slice(0,2048)}))};d.onCompiled=()=>{queueMicrotask(()=>{h()})},d.onError=(l,p)=>{w(p)};try{if(typeof d.forceCompilationAsync!="function")throw new Error("Babylon ShaderMaterial.forceCompilationAsync() is unavailable.");c.compilation=Promise.resolve(d.forceCompilationAsync(c.mesh)).then(()=>{if(c.failed)throw c.failure;h()}).catch(l=>{throw w(l),l})}catch(l){w(l),c.compilation=Promise.reject(l)}c.compilation.catch(()=>{}),f.forceCompilationAsync=()=>c.compilation;const m=f.dispose.bind(f);return f.dispose=(...l)=>{c.disposed||(c.disposed=!0,c.invalidateFrameParticipant?.(),delete c.shadersStore[`${c.shaderName}VertexShader`],delete c.shadersStore[`${c.shaderName}FragmentShader`],c.material.dispose?.(),m(...l))},f},updateMaterial(r){const s=r.babylon,a=Y(r.material)?o.get(r.material):void 0;return!a||a.disposed||a.failed?!1:(K(n,r.definitionVersion),J(s,a.material,n,i,r.properties),!0)},...i.frame.mode==="continuous"?{createFrameParticipant(r){const s=r.babylon,a=Y(r.material)?o.get(r.material):void 0;if(!a)throw new Error(`ShaderMaterial state is unavailable for ${n.shaderId}.`);let u=!1;const b=new Set;return a.invalidateFrameParticipant=()=>{for(const d of[...b])d()},{frameMode:"continuous",resolveFrameMode(){return a.failed||a.disposed||u?"on-demand":"continuous"},isActive(){return!a.failed&&!a.disposed&&!u},onFrameModeChanged(d){return b.add(d),()=>b.delete(d)},updateFrame(d){if(!(a.failed||a.disposed||u)&&(i.frame.timeUniform&&a.material.setFloat(i.frame.timeUniform,d.elapsedSeconds),i.frame.cameraPositionUniform)){const f=r.scene.activeCamera;a.material.setVector3(i.frame.cameraPositionUniform,f?.globalPosition??f?.position??s.Vector3.Zero())}},dispose(){u||(u=!0,b.clear(),a.invalidateFrameParticipant&&(a.invalidateFrameParticipant=null))}}}}:{}})))}function K(e,t){if(t!==e.version)throw Object.assign(new Error(`Material Definition version mismatch for ${e.shaderId}: expected ${e.version}, received ${String(t)}.`),{code:"material.shaderDefinitionVersionMismatch",shaderId:e.shaderId,expectedVersion:e.version,actualVersion:t})}function St(e,t,o){const n=new e.StandardMaterial(`${o}.diagnostic`,t);return n.diffuseColor=new e.Color3(.8,.02,.45),n.emissiveColor=new e.Color3(.35,0,.12),n.specularColor=new e.Color3(0,0,0),n.backFaceCulling=!1,n}function It(e,t){const o=F(e.metadata)?e.metadata:{},n=F(o.editorProjection)?o.editorProjection:{};e.metadata={...o,editorProjection:{...n,materialDiagnostic:Object.freeze({...t})}}}function Et(e){if(!F(e.metadata)||!F(e.metadata.editorProjection)||!Object.prototype.hasOwnProperty.call(e.metadata.editorProjection,"materialDiagnostic"))return;const t={...e.metadata.editorProjection};delete t.materialDiagnostic,e.metadata={...e.metadata,editorProjection:t}}function J(e,t,o,n,i){for(const r of o.inspector.fields){if(r.updateClass!=="uniform")continue;const s=jt(i,r.path.replace(/^properties\./,""));if(r.control==="number")t.setFloat(r.binding,I(s,r.path));else if(r.control==="boolean")t.setFloat(r.binding,s===!0?1:0);else if(r.control==="enum"){const a=n.enumUniformValues[r.path],u=typeof s=="string"?a?.[s]:void 0;if(!Number.isFinite(u))throw new Error(`Enum uniform value is not mapped: ${r.path}=${String(s)}`);t.setFloat(r.binding,u)}else if(r.control==="color"){const a=D(s,r.path);Mt(o,r.path)===4?t.setColor4(r.binding,new e.Color4(I(a.r,`${r.path}.r`),I(a.g,`${r.path}.g`),I(a.b,`${r.path}.b`),I(a.a,`${r.path}.a`))):t.setColor3(r.binding,new e.Color3(I(a.r,`${r.path}.r`),I(a.g,`${r.path}.g`),I(a.b,`${r.path}.b`)))}else if(r.control==="vec2"){const a=D(s,r.path);t.setVector2(r.binding,new e.Vector2(I(a.x,`${r.path}.x`),I(a.y,`${r.path}.y`)))}else if(r.control==="vec3"){const a=D(s,r.path);t.setVector3(r.binding,new e.Vector3(I(a.x,`${r.path}.x`),I(a.y,`${r.path}.y`),I(a.z,`${r.path}.z`)))}else throw new Error(`Unsupported ShaderMaterial uniform control: ${r.path} (${r.control})`)}}function Mt(e,t){let o=e.propertiesSchema;for(const n of t.replace(/^properties\./,"").split(".")){if(o.kind!=="object"||!o.properties[n])return 3;o=o.properties[n]}return o.kind==="color"&&o.channels===4?4:3}function jt(e,t){let o=e;for(const n of t.split(".").filter(Boolean)){if(!F(o))return;o=o[n]}return o}function D(e,t){if(!F(e))throw new Error(`Material property must be an object: ${t}`);return e}function I(e,t){if(typeof e!="number"||!Number.isFinite(e))throw new Error(`Material property must be a finite number: ${t}`);return e}function _t(e){return e.replace(/[^a-z0-9_-]/gi,"_")}function Y(e){return!!e&&typeof e=="object"}function F(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}const fe=window.__FPS_EDITOR_PROJECT_DEFINITION__;if(!fe)throw new Error("Editor Project definition was not provided by the control plane.");const U=yt(window.__FPS_EDITOR_PLUGIN_SNAPSHOTS__),xt=ue(U),Q=U?wt(U):void 0,X=()=>{const e=window.__FPS_EDITOR_PROJECT_IO__,t=String(e?.generation??0);return e?.status==="ready"?{ready:!0,generation:t}:{ready:!1,generation:t,reason:e?.reason??"Project I/O is unavailable."}},Pt=await Xe({container:document.body,projectDefinition:fe,surfaceEndpointBase:window.__FPS_EDITOR_SURFACE__?.endpointBase,runtimeAssetBaseUrl:window.location.origin,projectIOAvailability:{getAvailability:X,subscribeAvailability(e){const t=()=>e(X());return window.addEventListener("fps-editor:project-io-availability-changed",t),()=>window.removeEventListener("fps-editor:project-io-availability-changed",t)}},async onEnterPlayMode(){const e=window.__FPS_EDITOR_RUNTIME_URL__;if(!e)throw new Error("Editor Runtime URL was not provided by the control plane.");window.location.assign(e)},materialShaderDefinitions:xt,...Q?{materialProjectionAdapters:Q}:{}});window.addEventListener("pagehide",()=>void Pt.dispose(),{once:!0});
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|