@hology/core 0.0.208 → 0.0.210

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.
Files changed (30) hide show
  1. package/dist/data/surface-definition.d.ts +3 -0
  2. package/dist/data/surface-definition.js +4 -0
  3. package/dist/effects/sequence/sequence-player.js +1 -1
  4. package/dist/gameplay/actors/builtin/components/index.d.ts +2 -0
  5. package/dist/gameplay/actors/builtin/components/index.js +1 -1
  6. package/dist/gameplay/actors/camera/first-person-camera-component.d.ts +53 -0
  7. package/dist/gameplay/actors/camera/first-person-camera-component.js +4 -0
  8. package/dist/gameplay/actors/camera/third-person-camera-component.d.ts +4 -0
  9. package/dist/gameplay/actors/camera/third-person-camera-component.js +1 -1
  10. package/dist/gameplay/actors/index.d.ts +1 -0
  11. package/dist/gameplay/actors/index.js +1 -1
  12. package/dist/index.d.ts +2 -0
  13. package/dist/index.js +1 -1
  14. package/dist/rendering.js +1 -1
  15. package/dist/scene/batched-mesh-2.d.ts +2 -0
  16. package/dist/scene/batched-mesh-2.js +1 -1
  17. package/dist/scene/materializer.d.ts +2 -0
  18. package/dist/scene/materializer.js +1 -1
  19. package/dist/scene/model.d.ts +1 -0
  20. package/dist/scene/surface-query.d.ts +4 -0
  21. package/dist/scene/surface-query.js +4 -0
  22. package/dist/shader/builtin/landscape-composite-shader.d.ts +1 -0
  23. package/dist/shader/builtin/landscape-composite-shader.js +1 -1
  24. package/dist/shader/builtin/standard-shader.js +1 -1
  25. package/dist/test/first-person-camera-component.test.d.ts +2 -0
  26. package/dist/test/first-person-camera-component.test.js +4 -0
  27. package/dist/test/material-assignment.test.js +1 -1
  28. package/dist/test/materializer-prefetch.test.js +1 -1
  29. package/package.json +1 -1
  30. package/tsconfig.tsbuildinfo +1 -1
@@ -1,4 +1,4 @@
1
- import{__decorate as e,__metadata as a}from"tslib";import{Color as t,MeshStandardMaterial as n,Texture as r,Vector2 as i}from"three";import{Shader as s}from"../shader.js";import{Parameter as o}from"../parameter.js";import*as p from"three";import{attributes as l,colorToNormal as d,NodeShaderMaterial as h,normalize as m,Sampler2DNode as v,standardMaterial as u,UniformSampler2d as c,uniformFloat as y,uniformVec2 as g,uniformVec3 as f,varying as S,varyingAttributes as M,varyingTransformed as x,vec2 as b}from"three-shader-graph";import{parallaxOcclusionMapping as C}from"../../shader-nodes/pom.js";const w=new r,O=new i(1,1);export class StandardShader extends s{constructor(){super(...arguments),this.color=new t("#FFFFFF"),this.map=new c("map",w),this.opacity=1,this.alphaMap=new c("alphaMap",w),this.roughness=1,this.roughnessMap=new c("roughnessMap",w),this.metalness=0,this.metalnessMap=new c("metalnessMap",w),this.lightMap=new c("lightMap",w),this.aoMap=new c("aoMap",w),this.emissiveMap=new c("emissiveMap",w),this.normalMap=new c("normalMap",w),this.normalScale=new i(1,1),this.sheen=0,this.sheenColor=new t("#FFFFFF"),this.sheenColorMap=new c("sheenColorMap",w),this.sheenRoughness=.5,this.sheenRoughnessMap=new c("sheenRoughnessMap",w),this.anisotropyMap=new c("anisotropyMap",w),this.anisotropy=0,this.heightMap=new c("heightMap",w),this.vertexColor=!1,this.uvScale=O}build(){let e=!1;const a=g("uvScale",this.uvScale??O);let n=M.uv.multiply(a);T(this.heightMap)&&0!==(this.heightScale??.05)&&(n=C(n,this.heightMap,y("heightScale",this.heightScale??.05)));let r=y("opacity",this.opacity),s=f("color",(new p.Vector3).setFromColor(this.color)).rgb;if(T(this.map)){const e=this.map.sample(n);s=s.multiply(e.rgb),r=r.multiply(e.a)}T(this.alphaMap)&&(r=r.multiply(this.alphaMap.sample(n).r)),!0===this.vertexColor&&(s=s.multiply(S(l.color.rgb)));let o=null,v=null;T(this.aoMap)&&(v=y("aoMapIntensity",this.aoMapIntensity??1),o=this.aoMap.sample(n).r);let c=y("roughness",this.roughness??1);T(this.roughnessMap)&&(c=c.multiply(this.roughnessMap.sample(n).g),e=!0);let w=y("metalness",this.metalness??0);T(this.metalnessMap)&&(w=w.multiply(this.metalnessMap.sample(n).b),e=!0);let N=null;T(this.lightMap)&&(N=this.lightMap.sample(n).rgb.multiplyScalar(y("lightMapIntensity",this.lightMapIntensity??1)));let F=f("emissive",(new p.Vector3).setFromColor(this.emissive??new t(0))).rgb;T(this.emissiveMap)&&(F=F.multiply(this.emissiveMap.sample(n).rgb));const L=y("emissiveIntensity",this.emissiveIntensity??1);let R=x.normal;if(T(this.normalMap)){const e=y("normalScale",this.normalScale?.x??1);R=d(this.normalMap.sample(n),e)}let P=null,D=null;if((this.sheen??0)>0){const e=y("sheen",this.sheen??0);P=f("sheenColor",(new p.Vector3).setFromColor(this.sheenColor??new t(16777215))).rgb.multiplyScalar(e),T(this.sheenColorMap)&&(P=P.multiply(this.sheenColorMap.sample(n).rgb)),D=y("sheenRoughness",this.sheenRoughness??.5),T(this.sheenRoughnessMap)&&(D=D.multiply(this.sheenRoughnessMap.sample(n).a))}(this.roughness<1||this.metalness>0)&&(e=!0);let B=null,_=null;if((this.anisotropy??0)>0&&(B=y("anisotropy",this.anisotropy??0),_=g("anisotropyDirection",(I=this.anisotropyRotation??0,new i(Math.cos(I),Math.sin(I)))),T(this.anisotropyMap))){const e=this.anisotropyMap.sample(n),a=m(b(e.r,e.g).multiplyScalar(2).subtract(b(1,1)));_=b(_.x.multiply(a.x).subtract(_.y.multiply(a.y)),_.y.multiply(a.x).add(_.x.multiply(a.y))),B=B.multiply(e.b)}var I;const V=new h({color:u({color:s.rgba(r),roughness:c,metalness:w,ambientOcclusion:o,ambientOcclusionIntensity:v,emissive:F,emissiveIntensity:L,normal:R,bakedLight:N,sheenColor:P,sheenRoughness:D,anisotropy:B,anisotropyDirection:_,specular:e}),opacity:r,roughness:c,normal:R,emissive:F.multiplyScalar(L),envMap:this.envMap});return null!=this.envMap&&(V.uniforms.envMapIntensity={value:this.envMapIntensity??1}),V.vertexColors=!0===this.vertexColor,V}}function T(e){return null!=e&&(!(e instanceof c)||null!=e.value&&e.value!==w)}e([o(),a("design:type",t)],StandardShader.prototype,"color",void 0),e([o({label:"Color Map"}),a("design:type",v)],StandardShader.prototype,"map",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"opacity",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"alphaMap",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"roughness",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"roughnessMap",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"metalness",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"metalnessMap",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"lightMap",void 0),e([o(),a("design:type",Number)],StandardShader.prototype,"lightMapIntensity",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"aoMap",void 0),e([o(),a("design:type",Number)],StandardShader.prototype,"aoMapIntensity",void 0),e([o(),a("design:type",t)],StandardShader.prototype,"emissive",void 0),e([o({range:[0,10]}),a("design:type",Number)],StandardShader.prototype,"emissiveIntensity",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"emissiveMap",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"normalMap",void 0),e([o(),a("design:type",i)],StandardShader.prototype,"normalScale",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"sheen",void 0),e([o(),a("design:type",t)],StandardShader.prototype,"sheenColor",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"sheenColorMap",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"sheenRoughness",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"sheenRoughnessMap",void 0),e([o(),a("design:type",Number)],StandardShader.prototype,"anisotropyRotation",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"anisotropyMap",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"anisotropy",void 0),e([o(),a("design:type",r)],StandardShader.prototype,"envMap",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"envMapIntensity",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"heightMap",void 0),e([o(),a("design:type",Number)],StandardShader.prototype,"heightScale",void 0),e([o(),a("design:type",Boolean)],StandardShader.prototype,"vertexColor",void 0),e([o(),a("design:type",i)],StandardShader.prototype,"uvScale",void 0);export var ParallaxType;!function(e){e[e.none=0]="none",e[e.offset=1]="offset",e[e.pom=2]="pom"}(ParallaxType||(ParallaxType={}));export class ParallaxStandardMaterial extends n{constructor(e={}){super(e),e.heightMap&&(this.heightMap=e.heightMap),this.heightScale=e.heightScale??.05,this.parallaxType=e.parallaxType??ParallaxType.pom,this.minLayers=e.minLayers??10,this.maxLayers=e.maxLayers??32}onBeforeCompile(e){e.uniforms.heightMap={value:this.heightMap},e.uniforms.heightScale={value:this.heightScale},e.uniforms.minLayers={value:this.minLayers},e.uniforms.maxLayers={value:this.maxLayers},e.uniforms.parallaxType={value:this.parallaxType},e.vertexTangents=!0,e.vertexShader=e.vertexShader.replace("#include <uv_pars_vertex>","\n #include <uv_pars_vertex>\n "),e.vertexShader=e.vertexShader.replace("#include <begin_vertex>","\n #include <begin_vertex>\n "),e.fragmentShader=e.fragmentShader.replace("#include <uv_pars_fragment>","\n #include <uv_pars_fragment>\n uniform sampler2D heightMap;\n uniform float heightScale;\n uniform int minLayers;\n uniform int maxLayers;\n uniform int parallaxType;\n\n vec2 parallaxOffset(vec2 uv, vec3 viewDir, vec3 normal) {\n // Compute TBN in fragment shader using screen-space derivatives\n vec3 dp1 = dFdx(-vViewPosition);\n vec3 dp2 = dFdy(-vViewPosition);\n vec2 duv1 = dFdx(uv);\n vec2 duv2 = dFdy(uv);\n \n vec3 dp2perp = cross(dp2, normal);\n vec3 dp1perp = cross(normal, dp1);\n vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;\n vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;\n \n float invmax = inversesqrt(max(dot(T,T), dot(B,B)));\n mat3 tbn = mat3(T * invmax, B * invmax, normal);\n vec3 viewDirTS = -viewDir * tbn;\n\n float h = texture(heightMap, uv).r;\n return uv - (viewDirTS.xy / viewDirTS.z) * (h * heightScale);\n }\n\n vec2 parallaxOcclusion2(vec2 uv, vec3 viewDir, vec3 normal) {\n // Compute TBN in fragment shader using screen-space derivatives\n vec3 dp1 = dFdx(-vViewPosition);\n vec3 dp2 = dFdy(-vViewPosition);\n vec2 duv1 = dFdx(uv);\n vec2 duv2 = dFdy(uv);\n \n vec3 dp2perp = cross(dp2, normal);\n vec3 dp1perp = cross(normal, dp1);\n vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;\n vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;\n \n float invmax = inversesqrt(max(dot(T,T), dot(B,B)));\n mat3 tbn = mat3(T * invmax, B * invmax, normal);\n vec3 vv = -viewDir * tbn;\n\n float parallaxLimit = -length(vv.xy) / vv.z;\n parallaxLimit *= heightScale;\n\n vec2 vOffsetDir = normalize(vv.xy);\n vec2 vMaxOffset = vOffsetDir * parallaxLimit;\n\n float factor = pow(1.0 - abs(vv.z), 2.0);\n float nNumSamples = mix(float(minLayers), float(maxLayers), factor);\n float fStepSize = 1.0 / nNumSamples;\n\n float fCurrRayHeight = 1.0;\n vec2 vCurrOffset = vec2(0.0);\n vec2 vLastOffset = vec2(0.0);\n float fLastSampledHeight = 1.0;\n float fCurrSampledHeight = 1.0;\n\n for (int nCurrSample = 0; nCurrSample < 128; nCurrSample++) {\n if (float(nCurrSample) > nNumSamples) break;\n\n fCurrSampledHeight = texture2D(heightMap, uv + vCurrOffset).r;\n if (fCurrSampledHeight > fCurrRayHeight) {\n float delta1 = fCurrSampledHeight - fCurrRayHeight;\n float delta2 = (fCurrRayHeight + fStepSize) - fLastSampledHeight;\n float ratio = delta1 / (delta1 + delta2);\n vCurrOffset = ratio * vLastOffset + (1.0 - ratio) * vCurrOffset;\n break;\n } else {\n fCurrRayHeight -= fStepSize;\n vLastOffset = vCurrOffset;\n vCurrOffset += fStepSize * vMaxOffset;\n fLastSampledHeight = fCurrSampledHeight;\n }\n }\n\n return uv + vCurrOffset;\n }\n "),e.fragmentShader=e.fragmentShader.replace("#include <map_fragment>","\n vec3 pomViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n vec2 uvPOM = vMapUv ;\n if (parallaxType == 1) {\n uvPOM = parallaxOffset(vMapUv, pomViewDir, vNormal);\n } else if (parallaxType == 2) {\n uvPOM = parallaxOcclusion2(vMapUv, pomViewDir, vNormal);\n }\n\n vec4 texelColor = texture2D(map, uvPOM);\n diffuseColor *= texelColor;\n "),e.fragmentShader=e.fragmentShader.replace("#include <normal_fragment_maps>","\n #ifdef USE_NORMALMAP\n // RE-COMPUTE TBN for normal mapping consistency\n vec3 dp1 = dFdx(-vViewPosition);\n vec3 dp2 = dFdy(-vViewPosition);\n vec2 duv1 = dFdx(uvPOM);\n vec2 duv2 = dFdy(uvPOM);\n vec3 dp2perp = cross(dp2, vNormal);\n vec3 dp1perp = cross(vNormal, dp1);\n vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;\n vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;\n float invmax = inversesqrt(max(dot(T,T), dot(B,B)));\n mat3 localTBN = mat3(T * invmax, B * invmax, vNormal);\n\n vec3 mapN = texture2D(normalMap, uvPOM).xyz * 2.0 - 1.0;\n mapN.xy *= normalScale;\n normal = normalize( localTBN * mapN );\n #endif\n "),e.fragmentShader=e.fragmentShader.replace("#include <roughnessmap_fragment>","\n float roughnessFactor = roughness;\n #ifdef USE_ROUGHNESSMAP\n vec4 texelRoughness = texture2D( roughnessMap, uvPOM );\n // reads channel G, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n roughnessFactor *= texelRoughness.g;\n #endif\n "),e.fragmentShader=e.fragmentShader.replace("#include <metalnesssmap_fragment>","\n float metalnessFactor = metalness;\n #ifdef USE_METALNESSMAP\n vec4 texelMetalness = texture2D( metalnessMap, uvPOM );\n // reads channel B, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n metalnessFactor *= texelMetalness.b;\n #endif\n "),e.fragmentShader=e.fragmentShader.replace("#include <aomap_fragment>","\n #ifdef USE_AOMAP\n\n // reads channel R, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n float ambientOcclusion = ( texture2D( aoMap, uvPOM ).r - 1.0 ) * aoMapIntensity + 1.0;\n\n reflectedLight.indirectDiffuse *= ambientOcclusion;\n\n #if defined( USE_CLEARCOAT ) \n clearcoatSpecularIndirect *= ambientOcclusion;\n #endif\n\n #if defined( USE_SHEEN ) \n sheenSpecularIndirect *= ambientOcclusion;\n #endif\n\n #if defined( USE_ENVMAP ) && defined( STANDARD )\n\n float dotNV = saturate( dot( geometryNormal, geometryViewDir ) );\n\n reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );\n\n #endif\n\n #endif\n "),this.userData.shader=e}clone(){const e=super.clone();return e.heightMap=this.heightMap,e.heightScale=this.heightScale,e.parallaxType=this.parallaxType,e.minLayers=this.minLayers,e.maxLayers=this.maxLayers,e}}export function applyTiling(e,a){if(null==e||null==a)return e;if(1===a.x&&1===a.y)return e;const t=e.clone();return t.repeat.copy(a),t.needsUpdate=!0,t}/*
1
+ import{__decorate as e,__metadata as a}from"tslib";import{Color as t,MeshStandardMaterial as n,Texture as r,Vector2 as i}from"three";import{Shader as s}from"../shader.js";import{Parameter as o}from"../parameter.js";import*as p from"three";import{attributes as l,colorToNormal as d,NodeShaderMaterial as h,normalize as m,Sampler2DNode as v,standardMaterial as u,UniformSampler2d as c,uniformFloat as y,uniformVec2 as g,uniformVec3 as f,varying as S,varyingAttributes as M,varyingTransformed as x,vec2 as b,UniformVec3Node as C}from"three-shader-graph";import{parallaxOcclusionMapping as w}from"../../shader-nodes/pom.js";const O=new r,T=new i(1,1);export class StandardShader extends s{constructor(){super(...arguments),this.color=new t("#FFFFFF"),this.map=new c("map",O),this.opacity=1,this.alphaMap=new c("alphaMap",O),this.roughness=1,this.roughnessMap=new c("roughnessMap",O),this.metalness=0,this.metalnessMap=new c("metalnessMap",O),this.lightMap=new c("lightMap",O),this.aoMap=new c("aoMap",O),this.emissiveMap=new c("emissiveMap",O),this.normalMap=new c("normalMap",O),this.normalScale=new i(1,1),this.sheen=0,this.sheenColor=new t("#FFFFFF"),this.sheenColorMap=new c("sheenColorMap",O),this.sheenRoughness=.5,this.sheenRoughnessMap=new c("sheenRoughnessMap",O),this.anisotropyMap=new c("anisotropyMap",O),this.anisotropy=0,this.heightMap=new c("heightMap",O),this.vertexColor=!1,this.uvScale=T}build(){let e=!1;const a=g("uvScale",this.uvScale??T);let n=M.uv.multiply(a);N(this.heightMap)&&0!==(this.heightScale??.05)&&(n=w(n,this.heightMap,y("heightScale",this.heightScale??.05)));let r=y("opacity",this.opacity),s=new C("color",(new p.Vector3).setFromColor(this.color),void 0,!1).rgb;if(N(this.map)){const e=this.map.sample(n);s=s.multiply(e.rgb),r=r.multiply(e.a)}N(this.alphaMap)&&(r=r.multiply(this.alphaMap.sample(n).r)),!0===this.vertexColor&&(s=s.multiply(S(l.color.rgb)));let o=null,v=null;N(this.aoMap)&&(v=y("aoMapIntensity",this.aoMapIntensity??1),o=this.aoMap.sample(n).r);let c=y("roughness",this.roughness??1);N(this.roughnessMap)&&(c=c.multiply(this.roughnessMap.sample(n).g),e=!0);let O=y("metalness",this.metalness??0);N(this.metalnessMap)&&(O=O.multiply(this.metalnessMap.sample(n).b),e=!0);let F=null;N(this.lightMap)&&(F=this.lightMap.sample(n).rgb.multiplyScalar(y("lightMapIntensity",this.lightMapIntensity??1)));let L=f("emissive",(new p.Vector3).setFromColor(this.emissive??new t(0))).rgb;N(this.emissiveMap)&&(L=L.multiply(this.emissiveMap.sample(n).rgb));const R=y("emissiveIntensity",this.emissiveIntensity??1);let P=x.normal;if(N(this.normalMap)){const e=y("normalScale",this.normalScale?.x??1);P=d(this.normalMap.sample(n),e)}let D=null,B=null;if((this.sheen??0)>0){const e=y("sheen",this.sheen??0);D=f("sheenColor",(new p.Vector3).setFromColor(this.sheenColor??new t(16777215))).rgb.multiplyScalar(e),N(this.sheenColorMap)&&(D=D.multiply(this.sheenColorMap.sample(n).rgb)),B=y("sheenRoughness",this.sheenRoughness??.5),N(this.sheenRoughnessMap)&&(B=B.multiply(this.sheenRoughnessMap.sample(n).a))}(this.roughness<1||this.metalness>0)&&(e=!0);let _=null,I=null;if((this.anisotropy??0)>0&&(_=y("anisotropy",this.anisotropy??0),I=g("anisotropyDirection",(V=this.anisotropyRotation??0,new i(Math.cos(V),Math.sin(V)))),N(this.anisotropyMap))){const e=this.anisotropyMap.sample(n),a=m(b(e.r,e.g).multiplyScalar(2).subtract(b(1,1)));I=b(I.x.multiply(a.x).subtract(I.y.multiply(a.y)),I.y.multiply(a.x).add(I.x.multiply(a.y))),_=_.multiply(e.b)}var V;const E=new h({color:u({color:s.rgba(r),roughness:c,metalness:O,ambientOcclusion:o,ambientOcclusionIntensity:v,emissive:L,emissiveIntensity:R,normal:P,bakedLight:F,sheenColor:D,sheenRoughness:B,anisotropy:_,anisotropyDirection:I,specular:e}),opacity:r,roughness:c,normal:P,emissive:L.multiplyScalar(R),envMap:this.envMap});return null!=this.envMap&&(E.uniforms.envMapIntensity={value:this.envMapIntensity??1}),E.vertexColors=!0===this.vertexColor,E}}function N(e){return null!=e&&(!(e instanceof c)||null!=e.value&&e.value!==O)}e([o(),a("design:type",t)],StandardShader.prototype,"color",void 0),e([o({label:"Color Map"}),a("design:type",v)],StandardShader.prototype,"map",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"opacity",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"alphaMap",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"roughness",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"roughnessMap",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"metalness",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"metalnessMap",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"lightMap",void 0),e([o(),a("design:type",Number)],StandardShader.prototype,"lightMapIntensity",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"aoMap",void 0),e([o(),a("design:type",Number)],StandardShader.prototype,"aoMapIntensity",void 0),e([o(),a("design:type",t)],StandardShader.prototype,"emissive",void 0),e([o({range:[0,10]}),a("design:type",Number)],StandardShader.prototype,"emissiveIntensity",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"emissiveMap",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"normalMap",void 0),e([o(),a("design:type",i)],StandardShader.prototype,"normalScale",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"sheen",void 0),e([o(),a("design:type",t)],StandardShader.prototype,"sheenColor",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"sheenColorMap",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"sheenRoughness",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"sheenRoughnessMap",void 0),e([o(),a("design:type",Number)],StandardShader.prototype,"anisotropyRotation",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"anisotropyMap",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"anisotropy",void 0),e([o(),a("design:type",r)],StandardShader.prototype,"envMap",void 0),e([o({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"envMapIntensity",void 0),e([o(),a("design:type",v)],StandardShader.prototype,"heightMap",void 0),e([o(),a("design:type",Number)],StandardShader.prototype,"heightScale",void 0),e([o(),a("design:type",Boolean)],StandardShader.prototype,"vertexColor",void 0),e([o(),a("design:type",i)],StandardShader.prototype,"uvScale",void 0);export var ParallaxType;!function(e){e[e.none=0]="none",e[e.offset=1]="offset",e[e.pom=2]="pom"}(ParallaxType||(ParallaxType={}));export class ParallaxStandardMaterial extends n{constructor(e={}){super(e),e.heightMap&&(this.heightMap=e.heightMap),this.heightScale=e.heightScale??.05,this.parallaxType=e.parallaxType??ParallaxType.pom,this.minLayers=e.minLayers??10,this.maxLayers=e.maxLayers??32}onBeforeCompile(e){e.uniforms.heightMap={value:this.heightMap},e.uniforms.heightScale={value:this.heightScale},e.uniforms.minLayers={value:this.minLayers},e.uniforms.maxLayers={value:this.maxLayers},e.uniforms.parallaxType={value:this.parallaxType},e.vertexTangents=!0,e.vertexShader=e.vertexShader.replace("#include <uv_pars_vertex>","\n #include <uv_pars_vertex>\n "),e.vertexShader=e.vertexShader.replace("#include <begin_vertex>","\n #include <begin_vertex>\n "),e.fragmentShader=e.fragmentShader.replace("#include <uv_pars_fragment>","\n #include <uv_pars_fragment>\n uniform sampler2D heightMap;\n uniform float heightScale;\n uniform int minLayers;\n uniform int maxLayers;\n uniform int parallaxType;\n\n vec2 parallaxOffset(vec2 uv, vec3 viewDir, vec3 normal) {\n // Compute TBN in fragment shader using screen-space derivatives\n vec3 dp1 = dFdx(-vViewPosition);\n vec3 dp2 = dFdy(-vViewPosition);\n vec2 duv1 = dFdx(uv);\n vec2 duv2 = dFdy(uv);\n \n vec3 dp2perp = cross(dp2, normal);\n vec3 dp1perp = cross(normal, dp1);\n vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;\n vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;\n \n float invmax = inversesqrt(max(dot(T,T), dot(B,B)));\n mat3 tbn = mat3(T * invmax, B * invmax, normal);\n vec3 viewDirTS = -viewDir * tbn;\n\n float h = texture(heightMap, uv).r;\n return uv - (viewDirTS.xy / viewDirTS.z) * (h * heightScale);\n }\n\n vec2 parallaxOcclusion2(vec2 uv, vec3 viewDir, vec3 normal) {\n // Compute TBN in fragment shader using screen-space derivatives\n vec3 dp1 = dFdx(-vViewPosition);\n vec3 dp2 = dFdy(-vViewPosition);\n vec2 duv1 = dFdx(uv);\n vec2 duv2 = dFdy(uv);\n \n vec3 dp2perp = cross(dp2, normal);\n vec3 dp1perp = cross(normal, dp1);\n vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;\n vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;\n \n float invmax = inversesqrt(max(dot(T,T), dot(B,B)));\n mat3 tbn = mat3(T * invmax, B * invmax, normal);\n vec3 vv = -viewDir * tbn;\n\n float parallaxLimit = -length(vv.xy) / vv.z;\n parallaxLimit *= heightScale;\n\n vec2 vOffsetDir = normalize(vv.xy);\n vec2 vMaxOffset = vOffsetDir * parallaxLimit;\n\n float factor = pow(1.0 - abs(vv.z), 2.0);\n float nNumSamples = mix(float(minLayers), float(maxLayers), factor);\n float fStepSize = 1.0 / nNumSamples;\n\n float fCurrRayHeight = 1.0;\n vec2 vCurrOffset = vec2(0.0);\n vec2 vLastOffset = vec2(0.0);\n float fLastSampledHeight = 1.0;\n float fCurrSampledHeight = 1.0;\n\n for (int nCurrSample = 0; nCurrSample < 128; nCurrSample++) {\n if (float(nCurrSample) > nNumSamples) break;\n\n fCurrSampledHeight = texture2D(heightMap, uv + vCurrOffset).r;\n if (fCurrSampledHeight > fCurrRayHeight) {\n float delta1 = fCurrSampledHeight - fCurrRayHeight;\n float delta2 = (fCurrRayHeight + fStepSize) - fLastSampledHeight;\n float ratio = delta1 / (delta1 + delta2);\n vCurrOffset = ratio * vLastOffset + (1.0 - ratio) * vCurrOffset;\n break;\n } else {\n fCurrRayHeight -= fStepSize;\n vLastOffset = vCurrOffset;\n vCurrOffset += fStepSize * vMaxOffset;\n fLastSampledHeight = fCurrSampledHeight;\n }\n }\n\n return uv + vCurrOffset;\n }\n "),e.fragmentShader=e.fragmentShader.replace("#include <map_fragment>","\n vec3 pomViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n vec2 uvPOM = vMapUv ;\n if (parallaxType == 1) {\n uvPOM = parallaxOffset(vMapUv, pomViewDir, vNormal);\n } else if (parallaxType == 2) {\n uvPOM = parallaxOcclusion2(vMapUv, pomViewDir, vNormal);\n }\n\n vec4 texelColor = texture2D(map, uvPOM);\n diffuseColor *= texelColor;\n "),e.fragmentShader=e.fragmentShader.replace("#include <normal_fragment_maps>","\n #ifdef USE_NORMALMAP\n // RE-COMPUTE TBN for normal mapping consistency\n vec3 dp1 = dFdx(-vViewPosition);\n vec3 dp2 = dFdy(-vViewPosition);\n vec2 duv1 = dFdx(uvPOM);\n vec2 duv2 = dFdy(uvPOM);\n vec3 dp2perp = cross(dp2, vNormal);\n vec3 dp1perp = cross(vNormal, dp1);\n vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;\n vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;\n float invmax = inversesqrt(max(dot(T,T), dot(B,B)));\n mat3 localTBN = mat3(T * invmax, B * invmax, vNormal);\n\n vec3 mapN = texture2D(normalMap, uvPOM).xyz * 2.0 - 1.0;\n mapN.xy *= normalScale;\n normal = normalize( localTBN * mapN );\n #endif\n "),e.fragmentShader=e.fragmentShader.replace("#include <roughnessmap_fragment>","\n float roughnessFactor = roughness;\n #ifdef USE_ROUGHNESSMAP\n vec4 texelRoughness = texture2D( roughnessMap, uvPOM );\n // reads channel G, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n roughnessFactor *= texelRoughness.g;\n #endif\n "),e.fragmentShader=e.fragmentShader.replace("#include <metalnesssmap_fragment>","\n float metalnessFactor = metalness;\n #ifdef USE_METALNESSMAP\n vec4 texelMetalness = texture2D( metalnessMap, uvPOM );\n // reads channel B, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n metalnessFactor *= texelMetalness.b;\n #endif\n "),e.fragmentShader=e.fragmentShader.replace("#include <aomap_fragment>","\n #ifdef USE_AOMAP\n\n // reads channel R, compatible with a combined OcclusionRoughnessMetallic (RGB) texture\n float ambientOcclusion = ( texture2D( aoMap, uvPOM ).r - 1.0 ) * aoMapIntensity + 1.0;\n\n reflectedLight.indirectDiffuse *= ambientOcclusion;\n\n #if defined( USE_CLEARCOAT ) \n clearcoatSpecularIndirect *= ambientOcclusion;\n #endif\n\n #if defined( USE_SHEEN ) \n sheenSpecularIndirect *= ambientOcclusion;\n #endif\n\n #if defined( USE_ENVMAP ) && defined( STANDARD )\n\n float dotNV = saturate( dot( geometryNormal, geometryViewDir ) );\n\n reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );\n\n #endif\n\n #endif\n "),this.userData.shader=e}clone(){const e=super.clone();return e.heightMap=this.heightMap,e.heightScale=this.heightScale,e.parallaxType=this.parallaxType,e.minLayers=this.minLayers,e.maxLayers=this.maxLayers,e}}export function applyTiling(e,a){if(null==e||null==a)return e;if(1===a.x&&1===a.y)return e;const t=e.clone();return t.repeat.copy(a),t.needsUpdate=!0,t}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -0,0 +1,2 @@
1
+ import 'reflect-metadata';
2
+ //# sourceMappingURL=first-person-camera-component.test.d.ts.map
@@ -0,0 +1,4 @@
1
+ import"reflect-metadata";import{afterEach as e,expect as t,test as o,vi as n}from"vitest";n.hoisted(()=>{if("undefined"==typeof HTMLCanvasElement)return;const e=new Proxy({},{get:(e,t)=>(t in e||(e[t]=("string"!=typeof t||!t.startsWith("is"))&&n.fn()),e[t]),set:(e,t,o)=>(e[t]=o,!0)});Object.defineProperty(HTMLCanvasElement.prototype,"getContext",{configurable:!0,value:()=>e})}),n.mock("../gameplay/services/render.js",()=>({ViewController:class{}})),n.mock("../gameplay/services/physics/physics-system.js",()=>({PhysicsSystem:class{},RayTestResult:class{}})),n.mock("../gameplay/services/world.js",()=>({World:class{}})),n.mock("@hology/nebula",()=>({ease:{easeInOutCubic:e=>e}}));import{Subject as a}from"rxjs";import{Container as i}from"typedi";import{Object3D as r,Ray as s,Scene as c,Vector3 as m}from"three";import{BaseActor as p}from"../gameplay/actors/actor.js";import{FirstPersonCameraComponent as l}from"../gameplay/actors/camera/first-person-camera-component.js";import{ThirdPersonCameraComponent as d}from"../gameplay/actors/camera/third-person-camera-component.js";import{PhysicsSystem as y}from"../gameplay/services/physics/physics-system.js";import{ViewController as u}from"../gameplay/services/render.js";import{World as v}from"../gameplay/services/world.js";function f(e=new B){const t=h(),o=new l;return o.actor=e,{camera:o,actor:e,element:t}}function h(){const e=document.createElement("div"),t=document.createElement("canvas");return e.appendChild(t),Object.defineProperty(e,"clientWidth",{configurable:!0,value:1280}),Object.defineProperty(e,"clientHeight",{configurable:!0,value:720}),i.set(u,{htmlElement:e,setCamera:n.fn(),onUpdate:()=>new a,onLateUpdate:()=>new a}),i.set(v,{scene:new c}),i.set(y,{sphereCast:n.fn()}),e}function w(){Object.defineProperty(document.body,"requestPointerLock",{configurable:!0,value:n.fn()}),Object.defineProperty(document,"pointerLockElement",{configurable:!0,value:null})}function g(e,t){return e.mock.calls.filter(e=>e[0]===t).length}e(()=>{n.restoreAllMocks(),i.reset()}),o("first-person camera clamps pitch input",()=>{const{camera:e}=f();e.rotationInput.rotateX(Math.PI),t(e.rotationInput.rotation.x).toBeCloseTo(Math.PI/2-.01),e.rotationInput.rotateX(2*-Math.PI),t(e.rotationInput.rotation.x).toBeCloseTo(-Math.PI/2+.01)}),o("first-person camera follows actor eye offset",async()=>{const e=new B;e.position.set(1,2,3),e.rotation.y=Math.PI/2,e.object.updateMatrixWorld(!0);const{camera:o}=f(e);o.eyeHeight=1.5,o.offsetZ=.25,o.autoActivate=!1,await o.onInit(),o.updateCameraTransform(),t(o.camera.position.x).toBeCloseTo(1.25),t(o.camera.position.y).toBeCloseTo(3.5),t(o.camera.position.z).toBeCloseTo(3)}),o("first-person aim helpers write to caller-provided objects",async()=>{const e=new B;e.position.set(0,1,0);const{camera:o}=f(e);o.autoActivate=!1,await o.onInit();const n=new m,a=new m,i=new s;t(o.getAimOrigin(n)).toBe(n),t(o.getAimDirection(a)).toBe(a),t(o.getAimRay(i)).toBe(i),t(i.origin).toEqual(n),t(i.direction).toEqual(a),t(a.x).toBeCloseTo(0),t(a.y).toBeCloseTo(0),t(a.z).toBeCloseTo(1),t(a.length()).toBeCloseTo(1)}),o("first-person camera pitch input tilts aim downward when positive",async()=>{const{camera:e}=f();e.autoActivate=!1,await e.onInit(),e.rotationInput.rotateX(.25),e.updateCameraTransform();const o=e.getAimDirection(new m);t(o.y).toBeLessThan(0),t(o.z).toBeGreaterThan(0),t(o.length()).toBeCloseTo(1)}),o("first-person hidden objects restore their previous visibility",()=>{const{camera:e}=f(),o=new r,n=new r;n.visible=!1,e.hideObjects(o,n),t(o.visible).toBe(!1),t(n.visible).toBe(!1),e.restoreHiddenObjects(),t(o.visible).toBe(!0),t(n.visible).toBe(!1)}),o("first-person activation is idempotent",async()=>{const{camera:e,element:o}=f();e.autoActivate=!1,await e.onInit(),w();const a=n.spyOn(o,"addEventListener"),i=n.spyOn(o,"removeEventListener"),r=n.spyOn(document,"addEventListener"),s=n.spyOn(document,"removeEventListener");e.activate(),e.activate(),t(g(a,"pointerdown")).toBe(1),t(g(a,"keydown")).toBe(1),t(g(r,"pointerlockchange")).toBe(1),e.deactivate(),e.deactivate(),t(g(i,"pointerdown")).toBe(1),t(g(i,"keydown")).toBe(1),t(g(s,"pointerlockchange")).toBe(1)}),o("third-person activation remains idempotent",async()=>{const e=new B,o=h(),a=new d;a.actor=e,a.autoActivate=!1,await a.onInit(),w();const i=n.spyOn(o,"addEventListener"),r=n.spyOn(o,"removeEventListener"),s=n.spyOn(document,"addEventListener"),c=n.spyOn(document,"removeEventListener");a.activate(),a.activate(),t(g(i,"pointerdown")).toBe(1),t(g(i,"keydown")).toBe(1),t(g(s,"pointerlockchange")).toBe(1),a.deactivate(),a.deactivate(),t(g(r,"pointerdown")).toBe(1),t(g(r,"keydown")).toBe(1),t(g(c,"pointerlockchange")).toBe(1)});class B extends p{constructor(){super(),this.__isInitialised=!0}}/*
2
+ * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
+ * See the LICENSE.md file for details.
4
+ */
@@ -1,4 +1,4 @@
1
- import{describe as e,expect as t,it as n,vi as o}from"vitest";import{BoxGeometry as a,Mesh as r,MeshBasicMaterial as s,Texture as i}from"three";o.hoisted(()=>{if("undefined"==typeof HTMLCanvasElement)return;const e=new Proxy({},{get:(e,t)=>(t in e||(e[t]=("string"!=typeof t||!t.startsWith("is"))&&o.fn()),e[t]),set:(e,t,n)=>(e[t]=n,!0)});Object.defineProperty(HTMLCanvasElement.prototype,"getContext",{configurable:!0,value:()=>e}),"undefined"==typeof AudioBuffer&&Object.defineProperty(globalThis,"AudioBuffer",{configurable:!0,value:class{}})}),o.mock("../gameplay/actors/builtin/index.js",()=>({default:{}})),o.mock("../effects/vfx/vfx-actor.js",()=>({VfxActor:class{}})),o.mock("../effects/vfx/vfx-param.js",()=>({VisualEffect:class{}})),o.mock("../rendering.js",()=>({RenderingView:class{},setRenderingPaused:o.fn()}));import{applyMaterial as l,getConvertedFbxToGlbAssignedMaterialTextureFlipY as c}from"../scene/materializer.js";e("material assignments",()=>{n("matches named material assignments by name when the source color changed",async()=>{const e=new s({color:"#ffffff"});e.name="Body";const n=new s({color:"#123456"}),o=new r(new a,e);await l(o,{color:"#e7e7e7",name:"Body",materialId:"replacement"},async()=>n),t(o.material).toBe(n)}),n("keeps color matching for unnamed material assignments",async()=>{const e=new s({color:"#e7e7e7"}),n=new s({color:"#123456"}),o=new r(new a,e);await l(o,{color:"#e7e7e7",materialId:"replacement"},async()=>n),t(o.material).toBe(n)}),n("does not use color as a fallback when a non-empty assignment name is present",async()=>{const e=new s({color:"#e7e7e7"});e.name="Head";const n=new s({color:"#123456"}),o=new r(new a,e);await l(o,{color:"#e7e7e7",name:"Body",materialId:"replacement"},async()=>n),t(o.material).toBe(e)}),n("uses glTF texture orientation for converted FBX material assignments without cloning geometry",async()=>{const e=new s({color:"#e7e7e7"}),n=new i;n.flipY=!0;const o=new s({color:"#123456",map:n}),c=new a,m=new r(c,e);await l(m,{color:"#e7e7e7",materialId:"replacement"},async()=>o,void 0,{textureFlipY:!1});const f=m.material;t(f).not.toBe(o),t(f.map).not.toBe(n),t(f.map?.flipY).toBe(!1),t(n.flipY).toBe(!0),t(m.geometry).toBe(c)}),n("infers glTF texture orientation for older converted FBX asset metadata",()=>{t(c({fileFormat:"glb",originalFileKey:"models/tree.FBX"})).toBe(!1),t(c({fileFormat:"glb",originalFileKey:"models/tree.fbx",mesh:{uvConversion:{source:"fbx2gltf",flipV:!1}}})).toBeUndefined()})});/*
1
+ import{describe as e,expect as t,it as n,vi as a}from"vitest";import{BoxGeometry as o,Mesh as r,MeshBasicMaterial as s,Texture as i}from"three";a.hoisted(()=>{if("undefined"==typeof HTMLCanvasElement)return;const e=new Proxy({},{get:(e,t)=>(t in e||(e[t]=("string"!=typeof t||!t.startsWith("is"))&&a.fn()),e[t]),set:(e,t,n)=>(e[t]=n,!0)});Object.defineProperty(HTMLCanvasElement.prototype,"getContext",{configurable:!0,value:()=>e}),"undefined"==typeof AudioBuffer&&Object.defineProperty(globalThis,"AudioBuffer",{configurable:!0,value:class{}})}),a.mock("../gameplay/actors/builtin/index.js",()=>({default:{}})),a.mock("../effects/vfx/vfx-actor.js",()=>({VfxActor:class{}})),a.mock("../effects/vfx/vfx-param.js",()=>({VisualEffect:class{}})),a.mock("../rendering.js",()=>({RenderingView:class{},setRenderingPaused:a.fn()}));import{applyMaterial as l,getConvertedFbxToGlbAssignedMaterialTextureFlipY as c}from"../scene/materializer.js";e("material assignments",()=>{n("matches named material assignments by name when the source color changed",async()=>{const e=new s({color:"#ffffff"});e.name="Body";const n=new s({color:"#123456"}),a=new r(new o,e);await l(a,{color:"#e7e7e7",name:"Body",materialId:"replacement"},async()=>n),t(a.material).toBe(n)}),n("keeps color matching for unnamed material assignments",async()=>{const e=new s({color:"#e7e7e7"}),n=new s({color:"#123456"}),a=new r(new o,e);await l(a,{color:"#e7e7e7",materialId:"replacement"},async()=>n),t(a.material).toBe(n)}),n("does not use color as a fallback when a non-empty assignment name is present",async()=>{const e=new s({color:"#e7e7e7"});e.name="Head";const n=new s({color:"#123456"}),a=new r(new o,e);await l(a,{color:"#e7e7e7",name:"Body",materialId:"replacement"},async()=>n),t(a.material).toBe(e)}),n("uses glTF texture orientation for converted FBX material assignments without cloning geometry",async()=>{const e=new s({color:"#e7e7e7"}),n=new i;n.flipY=!0;const a=new s({color:"#123456",map:n}),c=new o,m=new r(c,e);await l(m,{color:"#e7e7e7",materialId:"replacement"},async()=>a,void 0,{textureFlipY:!1});const f=m.material;t(f).not.toBe(a),t(f.map).not.toBe(n),t(f.map?.flipY).toBe(!1),t(n.flipY).toBe(!0),t(m.geometry).toBe(c)}),n("preserves runtime material userData when cloning for texture orientation",async()=>{class e{}const n=new e,a=new s({color:"#e7e7e7"}),c=new i;c.flipY=!0;const m=new s({color:"#123456",map:c});m.userData.surface=n;const f=new r(new o,a);await l(f,{color:"#e7e7e7",materialId:"replacement"},async()=>m,void 0,{textureFlipY:!1});const d=f.material;t(d).not.toBe(m),t(d.userData.surface).toBe(n),t(d.userData.surface).toBeInstanceOf(e)}),n("infers glTF texture orientation for older converted FBX asset metadata",()=>{t(c({fileFormat:"glb",originalFileKey:"models/tree.FBX"})).toBe(!1),t(c({fileFormat:"glb",originalFileKey:"models/tree.fbx",mesh:{uvConversion:{source:"fbx2gltf",flipV:!1}}})).toBeUndefined()})});/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,4 @@
1
- import{describe as e,expect as s,it as t,vi as a}from"vitest";import{Scene as i}from"three";import{Subject as n}from"rxjs";a.hoisted(()=>{if("undefined"==typeof HTMLCanvasElement)return;const e=new Proxy({},{get:(e,s)=>(s in e||(e[s]=("string"!=typeof s||!s.startsWith("is"))&&a.fn()),e[s]),set:(e,s,t)=>(e[s]=t,!0)});Object.defineProperty(HTMLCanvasElement.prototype,"getContext",{configurable:!0,value:()=>e}),"undefined"==typeof AudioBuffer&&Object.defineProperty(globalThis,"AudioBuffer",{configurable:!0,value:class{}})}),a.mock("../gameplay/actors/builtin/index.js",()=>({default:{}})),a.mock("../effects/vfx/vfx-actor.js",()=>({VfxActor:class{}})),a.mock("../effects/vfx/vfx-param.js",()=>({VisualEffect:class{}})),a.mock("../rendering.js",()=>({RenderingView:class{},setRenderingPaused:a.fn()}));import{SceneMaterializer as r}from"../scene/materializer.js";import{DetailTier as d}from"../scene/model.js";function o(e){return{name:e.id,...e}}function m(e,s){return{id:e,name:e,type:"mesh",fileKey:`${e}.glb`,fileFormat:"glb",mesh:s}}e("SceneMaterializer asset prefetch",()=>{t("prefetches unique materialized asset meshes with the same options used by createFromAsset",async()=>{const e=m("mesh-a"),t=m("mesh-b"),f=m("mesh-c"),c=m("mesh-disabled"),l=m("mesh-high",{detailTier:d.high}),p=function(e,s){return{id:e,name:e,type:"prefab",prefab:{objects:s}}}("prefab-a",[o({id:"prefab-mesh-c",type:"asset_mesh",assetId:f.id}),o({id:"prefab-duplicate-mesh-a",type:"asset_mesh",assetId:e.id}),o({id:"prefab-cycle",type:"prefab",assetId:"prefab-a"})]),h=new Map([e,t,f,c,l,p].map(e=>[e.id,e])),u=[o({id:"root",type:"group",children:[o({id:"mesh-a-1",type:"asset_mesh",assetId:e.id}),o({id:"mesh-a-2",type:"asset_mesh",assetId:e.id}),o({id:"disabled-group",type:"group",enabled:!1,children:[o({id:"disabled-mesh",type:"asset_mesh",assetId:c.id})]}),o({id:"prefab-instance",type:"prefab",assetId:p.id}),o({id:"high-detail-mesh",type:"asset_mesh",assetId:l.id})]}),o({id:"mesh-b",type:"asset_mesh",assetId:t.id})],{materializer:y,getMesh:b}=function(e,s){const t=a.fn(async(e,s)=>({scene:{},animations:[]})),d={getObjects:()=>e,onCreate:()=>{},onUpdate:()=>{},onRemove:()=>{}},o={onCreate:new n,onDelete:new n,onUpdate:new n,getAsset:a.fn(async e=>s.get(e)??null),getAssets:a.fn(async()=>Array.from(s.values()))},m=new r(new i,d,o,{getMesh:t},null,[],[],{create:async()=>null,initActor:async()=>{}});return{materializer:m,getMesh:t}}(u,h);y.detailTier=d.low,await y.preInit(),await y.prefetchAssets(),s(b).toHaveBeenCalledTimes(3),s(new Set(b.mock.calls.map(([e])=>e.id))).toEqual(new Set([e.id,t.id,f.id])),s(b.mock.calls.every(([,e])=>!0===e?.mergeGeomtries)).toBe(!0)})});/*
1
+ import{describe as e,expect as t,it as a,vi as s}from"vitest";import{Scene as i,Texture as r}from"three";import{Subject as n}from"rxjs";s.hoisted(()=>{if("undefined"==typeof HTMLCanvasElement)return;const e=new Proxy({},{get:(e,t)=>(t in e||(e[t]=("string"!=typeof t||!t.startsWith("is"))&&s.fn()),e[t]),set:(e,t,a)=>(e[t]=a,!0)});Object.defineProperty(HTMLCanvasElement.prototype,"getContext",{configurable:!0,value:()=>e}),"undefined"==typeof AudioBuffer&&Object.defineProperty(globalThis,"AudioBuffer",{configurable:!0,value:class{}})}),s.mock("../gameplay/actors/builtin/index.js",()=>({default:{}})),s.mock("../effects/vfx/vfx-actor.js",()=>({VfxActor:class{}})),s.mock("../effects/vfx/vfx-param.js",()=>({VisualEffect:class{}})),s.mock("../rendering.js",()=>({RenderingView:class{},setRenderingPaused:s.fn()}));import{SceneMaterializer as d}from"../scene/materializer.js";import{DetailTier as p,SerializedParamType as o}from"../scene/model.js";function m(e,t){const a=s.fn(async(e,t)=>({scene:{},animations:[]})),p=s.fn(async e=>new r),o=s.fn(async e=>({texture:new r,layerIndex:0})),m=s.fn(),f={getObjects:()=>e,onCreate:()=>{},onUpdate:()=>{},onRemove:()=>{}},l={onCreate:new n,onDelete:new n,onUpdate:new n,getAsset:s.fn(async e=>t.get(e)??null),getAssets:s.fn(async()=>Array.from(t.values()))};return{materializer:new d(new i,f,l,{getMesh:a,getTexture:p,getTextureArray:o},{renderer:{initTexture:m},onLoop:s.fn()},[],[],{create:async()=>null,initActor:async()=>{}}),getMesh:a,getTexture:p,getTextureArray:o,initTexture:m}}function f(e){return{name:e.id,...e}}function l(e,t){return{id:e,name:e,type:"mesh",fileKey:`${e}.glb`,fileFormat:"glb",mesh:t}}function c(e,t){return{id:e,name:e,type:"prefab",prefab:{objects:t}}}function u(e,t){return{id:e,name:e,type:"material",material:{type:"shader",side:0,params:{},shaderParams:{map:{type:o.Texture,value:t}}}}}function h(e){return{id:e,name:e,type:"texture",fileKey:`${e}.png`,fileFormat:"png"}}function y(e){return{color:"#ffffff",materialId:e}}e("SceneMaterializer asset prefetch",()=>{a("prefetches unique materialized asset meshes with the same options used by createFromAsset",async()=>{const e=l("mesh-a"),a=l("mesh-b"),s=l("mesh-c"),i=l("mesh-disabled"),r=l("mesh-high",{detailTier:p.high}),n=c("prefab-a",[f({id:"prefab-mesh-c",type:"asset_mesh",assetId:s.id}),f({id:"prefab-duplicate-mesh-a",type:"asset_mesh",assetId:e.id}),f({id:"prefab-cycle",type:"prefab",assetId:"prefab-a"})]),d=new Map([e,a,s,i,r,n].map(e=>[e.id,e])),o=[f({id:"root",type:"group",children:[f({id:"mesh-a-1",type:"asset_mesh",assetId:e.id}),f({id:"mesh-a-2",type:"asset_mesh",assetId:e.id}),f({id:"disabled-group",type:"group",enabled:!1,children:[f({id:"disabled-mesh",type:"asset_mesh",assetId:i.id})]}),f({id:"prefab-instance",type:"prefab",assetId:n.id}),f({id:"high-detail-mesh",type:"asset_mesh",assetId:r.id})]}),f({id:"mesh-b",type:"asset_mesh",assetId:a.id})],{materializer:u,getMesh:h}=m(o,d);u.detailTier=p.low,await u.preInit(),await u.prefetchAssets(),t(h).toHaveBeenCalledTimes(3),t(new Set(h.mock.calls.map(([e])=>e.id))).toEqual(new Set([e.id,a.id,s.id])),t(h.mock.calls.every(([,e])=>!0===e?.mergeGeomtries)).toBe(!0)}),a("initializes textures from nested groups and prefab assets",async()=>{const e=h("texture-root"),a=h("texture-group"),s=h("texture-prefab"),i=h("texture-skipped"),r=u("material-root",e.id),n=u("material-group",a.id),d=u("material-prefab",s.id),p=u("material-skipped",i.id),o=c("prefab-a",[f({id:"prefab-group",type:"group",children:[f({id:"prefab-shape",type:"shape_mesh",materialAssignments:[y(d.id)]})]}),f({id:"prefab-cycle",type:"prefab",assetId:"prefab-a"})]),l=new Map([e,a,s,i,r,n,d,p,o].map(e=>[e.id,e])),g=[f({id:"root-group",type:"group",children:[f({id:"nested-mesh",type:"asset_mesh",materialAssignments:[y(n.id)]}),f({id:"disabled-group",type:"group",enabled:!1,children:[f({id:"skipped-mesh",type:"asset_mesh",materialAssignments:[y(p.id)]})]}),f({id:"prefab-instance",type:"prefab",assetId:o.id})]}),f({id:"root-shape",type:"shape_mesh",materialAssignments:[y(r.id)]})],{materializer:b,getTexture:x,initTexture:w}=m(g,l);await b.preInit(),await b.initTextures(),t(x).toHaveBeenCalledTimes(3),t(new Set(x.mock.calls.map(([e])=>e.id))).toEqual(new Set([e.id,a.id,s.id])),t(w).toHaveBeenCalledTimes(3)})});/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hology/core",
3
- "version": "0.0.208",
3
+ "version": "0.0.210",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",