@hology/core 0.0.196 → 0.0.198
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/dist/effects/sequence/sequence-action.d.ts +8 -1
- package/dist/effects/sequence/sequence-actor.d.ts +14 -2
- package/dist/effects/sequence/sequence-actor.js +1 -1
- package/dist/effects/sequence/sequence-data.d.ts +98 -4
- package/dist/effects/sequence/sequence-data.js +1 -1
- package/dist/effects/sequence/sequence-definitions.d.ts +12 -8
- package/dist/effects/sequence/sequence-definitions.js +1 -1
- package/dist/effects/sequence/sequence-ops.js +1 -1
- package/dist/effects/sequence/sequence-player.d.ts +66 -2
- package/dist/effects/sequence/sequence-player.js +1 -1
- package/dist/effects/sequence/sequence-value-lane.d.ts +1 -0
- package/dist/effects/sequence/sequence-value-lane.js +1 -1
- package/dist/gameplay/actors/builtin/components/character/character-animation.d.ts +2 -0
- package/dist/gameplay/actors/builtin/components/character/character-animation.js +1 -1
- package/dist/gameplay/actors/builtin/navmesh-actor.js +1 -1
- package/dist/gameplay/actors/builtin/post-process-volume-actor.js +1 -1
- package/dist/gameplay/index.d.ts +1 -0
- package/dist/gameplay/index.js +1 -1
- package/dist/gameplay/initiate.d.ts +1 -0
- package/dist/gameplay/initiate.js +1 -1
- package/dist/gameplay/services/camera-shake.d.ts +28 -0
- package/dist/gameplay/services/camera-shake.js +4 -0
- package/dist/gameplay/services/physics/physics-system.js +1 -1
- package/dist/gameplay/services/render.d.ts +47 -2
- package/dist/gameplay/services/render.js +1 -1
- package/dist/rendering/post-process-effect.d.ts +63 -0
- package/dist/rendering/post-process-effect.js +4 -0
- package/dist/rendering.d.ts +15 -1
- package/dist/rendering.js +1 -1
- package/dist/scene/asset-resource-loader.d.ts +3 -1
- package/dist/scene/asset-resource-loader.js +1 -1
- package/dist/scene/collision/collision-shape-import.js +1 -1
- package/dist/scene/collision/collision-shape.js +1 -1
- package/dist/scene/materializer.d.ts +20 -2
- package/dist/scene/materializer.js +1 -1
- package/dist/scene/scatter/surface-scatter-manager.d.ts +44 -0
- package/dist/scene/scatter/surface-scatter-manager.js +4 -0
- package/dist/scene/storage/storage.d.ts +2 -0
- package/dist/scene/storage/storage.js +1 -1
- package/dist/shader/builtin/landscape-composite-shader.js +1 -1
- package/dist/shader/builtin/standard-shader.d.ts +2 -0
- package/dist/shader/builtin/standard-shader.js +1 -1
- package/dist/shader/builtin/unlit-shader.d.ts +2 -1
- package/dist/shader/builtin/unlit-shader.js +1 -1
- package/dist/shader/index.d.ts +1 -0
- package/dist/shader/index.js +1 -1
- package/dist/shader/post-process-shader.d.ts +14 -0
- package/dist/shader/post-process-shader.js +4 -0
- package/dist/shader/uv-nodes.d.ts +4 -0
- package/dist/shader/uv-nodes.js +4 -0
- package/dist/shader-nodes/index.d.ts +1 -1
- package/dist/shader-nodes/index.js +1 -1
- package/dist/test/authored-collision-rescale.test.d.ts +2 -0
- package/dist/test/authored-collision-rescale.test.js +4 -0
- package/dist/test/camera-shake.test.d.ts +2 -0
- package/dist/test/camera-shake.test.js +4 -0
- package/dist/test/collision-shape-import.test.js +1 -1
- package/dist/test/post-process-effect.test.d.ts +2 -0
- package/dist/test/post-process-effect.test.js +4 -0
- package/dist/test/sequence-camera-control.test.d.ts +2 -0
- package/dist/test/sequence-camera-control.test.js +4 -0
- package/dist/test/sequence-property-parameters.test.d.ts +2 -0
- package/dist/test/sequence-property-parameters.test.js +4 -0
- package/dist/test/storage-case-collision.test.d.ts +2 -0
- package/dist/test/storage-case-collision.test.js +4 -0
- package/package.json +2 -2
- 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 o}from"../shader.js";import{Parameter as s}from"../parameter.js";import{removeObjectUndefined as p}from"../../utils/collections.js";import*as d from"three";const l=new r;export class StandardShader extends o{constructor(){super(...arguments),this.color=new t("#FFFFFF"),this.opacity=1,this.roughness=1,this.metalness=0,this.normalScale=new i(1,1),this.sheen=0,this.sheenColor=new t("#FFFFFF"),this.sheenRoughness=.5,this.anisotropy=0,this.heightMap=l,this.vertexColor=!1}build(){const e=this.sheen>0,a=this.anisotropy>0,t=a||e,r=(null!=this.map||null!=this.normalMap)&&null!=this.heightMap&&this.heightMap!=l&&0!==this.heightScale,i=r?ParallaxStandardMaterial:t?d.MeshPhysicalMaterial:n;this.map,null!=this.normalMap&&(this.normalMap.colorSpace=d.LinearSRGBColorSpace),null!=this.metalnessMap&&(this.metalnessMap.colorSpace=d.LinearSRGBColorSpace),null!=this.roughnessMap&&(this.roughnessMap.colorSpace=d.LinearSRGBColorSpace),null!=this.aoMap&&(this.aoMap.colorSpace=d.LinearSRGBColorSpace),null!=this.heightMap&&(this.heightMap.colorSpace=d.NoColorSpace),this.emissiveMap,null!=this.alphaMap&&(this.alphaMap.colorSpace=d.LinearSRGBColorSpace),null!=this.lightMap&&(this.lightMap.colorSpace=d.LinearSRGBColorSpace);return new i(p({color:this.color,vertexColors:this.vertexColor,opacity:this.opacity,roughness:this.roughness,metalness:this.metalness,map:this.map,lightMap:this.lightMap,lightMapIntensity:this.lightMapIntensity,aoMap:this.aoMap,aoMapIntensity:this.aoMapIntensity,emissive:this.emissive,emissiveIntensity:this.emissiveIntensity,emissiveMap:this.emissiveMap,normalMap:this.normalMap,normalScale:this.normalScale,sheen:e?this.sheen:void 0,sheenColor:e?this.sheenColor:void 0,sheenColorMap:e?this.sheenColorMap:void 0,sheenRoughness:e?this.sheenRoughness:void 0,sheenRoughnessMap:e?this.sheenRoughnessMap:void 0,anisotropy:a?this.anisotropy:void 0,anisotropyMap:a?this.anisotropyMap:void 0,anisotropyRotation:a?this.anisotropyRotation:void 0,roughnessMap:this.roughnessMap,metalnessMap:this.metalnessMap,alphaMap:this.alphaMap,envMap:this.envMap,envMapIntensity:this.envMapIntensity,...r?{heightMap:this.heightMap,heightScale:this.heightScale}:{}}))}}e([s(),a("design:type",t)],StandardShader.prototype,"color",void 0),e([s({label:"Color Map"}),a("design:type",r)],StandardShader.prototype,"map",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"opacity",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"alphaMap",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"roughness",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"roughnessMap",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"metalness",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"metalnessMap",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"lightMap",void 0),e([s(),a("design:type",Number)],StandardShader.prototype,"lightMapIntensity",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"aoMap",void 0),e([s(),a("design:type",Number)],StandardShader.prototype,"aoMapIntensity",void 0),e([s(),a("design:type",t)],StandardShader.prototype,"emissive",void 0),e([s({range:[0,10]}),a("design:type",Number)],StandardShader.prototype,"emissiveIntensity",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"emissiveMap",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"normalMap",void 0),e([s(),a("design:type",i)],StandardShader.prototype,"normalScale",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"sheen",void 0),e([s(),a("design:type",t)],StandardShader.prototype,"sheenColor",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"sheenColorMap",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"sheenRoughness",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"sheenRoughnessMap",void 0),e([s(),a("design:type",Number)],StandardShader.prototype,"anisotropyRotation",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"anisotropyMap",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"anisotropy",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"envMap",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"envMapIntensity",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"heightMap",void 0),e([s(),a("design:type",Number)],StandardShader.prototype,"heightScale",void 0),e([s(),a("design:type",Boolean)],StandardShader.prototype,"vertexColor",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}}/*
|
|
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 o}from"../shader.js";import{Parameter as s}from"../parameter.js";import{removeObjectUndefined as p}from"../../utils/collections.js";import*as l from"three";const d=new r;export class StandardShader extends o{constructor(){super(...arguments),this.color=new t("#FFFFFF"),this.opacity=1,this.roughness=1,this.metalness=0,this.normalScale=new i(1,1),this.sheen=0,this.sheenColor=new t("#FFFFFF"),this.sheenRoughness=.5,this.anisotropy=0,this.heightMap=d,this.vertexColor=!1,this.uvScale=new i(1,1)}build(){const e=this.sheen>0,a=this.anisotropy>0,t=a||e,r=(null!=this.map||null!=this.normalMap)&&null!=this.heightMap&&this.heightMap!=d&&0!==this.heightScale,i=r?ParallaxStandardMaterial:t?l.MeshPhysicalMaterial:n;null!=this.map&&(this.map.colorSpace=l.SRGBColorSpace),null!=this.normalMap&&(this.normalMap.colorSpace=l.LinearSRGBColorSpace),null!=this.metalnessMap&&(this.metalnessMap.colorSpace=l.LinearSRGBColorSpace),null!=this.roughnessMap&&(this.roughnessMap.colorSpace=l.LinearSRGBColorSpace),null!=this.aoMap&&(this.aoMap.colorSpace=l.LinearSRGBColorSpace),null!=this.heightMap&&(this.heightMap.colorSpace=l.NoColorSpace),null!=this.emissiveMap&&(this.emissiveMap.colorSpace=l.SRGBColorSpace),null!=this.alphaMap&&(this.alphaMap.colorSpace=l.LinearSRGBColorSpace),null!=this.lightMap&&(this.lightMap.colorSpace=l.LinearSRGBColorSpace);return new i(p({color:this.color,vertexColors:this.vertexColor,opacity:this.opacity,roughness:this.roughness,metalness:this.metalness,map:applyTiling(this.map,this.uvScale),lightMap:this.lightMap,lightMapIntensity:this.lightMapIntensity,aoMap:applyTiling(this.aoMap,this.uvScale),aoMapIntensity:this.aoMapIntensity,emissive:this.emissive,emissiveIntensity:this.emissiveIntensity,emissiveMap:applyTiling(this.emissiveMap,this.uvScale),normalMap:applyTiling(this.normalMap,this.uvScale),normalScale:this.normalScale,sheen:e?this.sheen:void 0,sheenColor:e?this.sheenColor:void 0,sheenColorMap:e?this.sheenColorMap:void 0,sheenRoughness:e?this.sheenRoughness:void 0,sheenRoughnessMap:e?this.sheenRoughnessMap:void 0,anisotropy:a?this.anisotropy:void 0,anisotropyMap:a?this.anisotropyMap:void 0,anisotropyRotation:a?this.anisotropyRotation:void 0,roughnessMap:applyTiling(this.roughnessMap,this.uvScale),metalnessMap:applyTiling(this.metalnessMap,this.uvScale),alphaMap:applyTiling(this.alphaMap,this.uvScale),envMap:this.envMap,envMapIntensity:this.envMapIntensity,...r?{heightMap:this.heightMap,heightScale:this.heightScale}:{}}))}}e([s(),a("design:type",t)],StandardShader.prototype,"color",void 0),e([s({label:"Color Map"}),a("design:type",r)],StandardShader.prototype,"map",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"opacity",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"alphaMap",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"roughness",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"roughnessMap",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"metalness",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"metalnessMap",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"lightMap",void 0),e([s(),a("design:type",Number)],StandardShader.prototype,"lightMapIntensity",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"aoMap",void 0),e([s(),a("design:type",Number)],StandardShader.prototype,"aoMapIntensity",void 0),e([s(),a("design:type",t)],StandardShader.prototype,"emissive",void 0),e([s({range:[0,10]}),a("design:type",Number)],StandardShader.prototype,"emissiveIntensity",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"emissiveMap",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"normalMap",void 0),e([s(),a("design:type",i)],StandardShader.prototype,"normalScale",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"sheen",void 0),e([s(),a("design:type",t)],StandardShader.prototype,"sheenColor",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"sheenColorMap",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"sheenRoughness",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"sheenRoughnessMap",void 0),e([s(),a("design:type",Number)],StandardShader.prototype,"anisotropyRotation",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"anisotropyMap",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"anisotropy",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"envMap",void 0),e([s({range:[0,1]}),a("design:type",Number)],StandardShader.prototype,"envMapIntensity",void 0),e([s(),a("design:type",r)],StandardShader.prototype,"heightMap",void 0),e([s(),a("design:type",Number)],StandardShader.prototype,"heightScale",void 0),e([s(),a("design:type",Boolean)],StandardShader.prototype,"vertexColor",void 0),e([s(),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
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Color, Material, Texture } from 'three';
|
|
1
|
+
import { Color, Material, Texture, Vector2 } from 'three';
|
|
2
2
|
import { Shader } from '../shader.js';
|
|
3
3
|
export declare class UnlitShader extends Shader {
|
|
4
4
|
color: Color;
|
|
@@ -12,6 +12,7 @@ export declare class UnlitShader extends Shader {
|
|
|
12
12
|
alphaMap?: Texture;
|
|
13
13
|
envMap?: Texture;
|
|
14
14
|
vertexColor?: boolean;
|
|
15
|
+
uvScale: Vector2;
|
|
15
16
|
build(): Material;
|
|
16
17
|
}
|
|
17
18
|
//# sourceMappingURL=unlit-shader.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{__decorate as t,__metadata as e}from"tslib";import{Color as i,MeshBasicMaterial as o,Texture as p}from"three";import{Shader as
|
|
1
|
+
import{__decorate as t,__metadata as e}from"tslib";import{Color as i,MeshBasicMaterial as o,Texture as p,Vector2 as r}from"three";import{Shader as a}from"../shader.js";import{Parameter as s}from"../parameter.js";import{removeObjectUndefined as n}from"../../utils/collections.js";import{applyTiling as l}from"./standard-shader.js";export class UnlitShader extends a{constructor(){super(...arguments),this.color=new i("#FFFFFF"),this.opacity=1,this.intensity=1,this.vertexColor=!1,this.uvScale=new r(1,1)}build(){return new o(n({color:this.color.multiplyScalar(this.intensity),emissive:this.color.multiplyScalar(this.intensity),opacity:this.opacity,map:l(this.map,this.uvScale),lightMap:this.lightMap,lightMapIntensity:this.lightMapIntensity,aoMap:this.aoMap,aoMapIntensity:this.aoMapIntensity,alphaMap:l(this.alphaMap,this.uvScale),envMap:this.envMap,vertexColors:this.vertexColor}))}}t([s(),e("design:type",i)],UnlitShader.prototype,"color",void 0),t([s({range:[0,1]}),e("design:type",Number)],UnlitShader.prototype,"opacity",void 0),t([s({range:[0,10]}),e("design:type",Number)],UnlitShader.prototype,"intensity",void 0),t([s(),e("design:type",p)],UnlitShader.prototype,"map",void 0),t([s(),e("design:type",p)],UnlitShader.prototype,"lightMap",void 0),t([s(),e("design:type",Number)],UnlitShader.prototype,"lightMapIntensity",void 0),t([s(),e("design:type",p)],UnlitShader.prototype,"aoMap",void 0),t([s(),e("design:type",Number)],UnlitShader.prototype,"aoMapIntensity",void 0),t([s(),e("design:type",p)],UnlitShader.prototype,"alphaMap",void 0),t([s(),e("design:type",p)],UnlitShader.prototype,"envMap",void 0),t([s(),e("design:type",Boolean)],UnlitShader.prototype,"vertexColor",void 0),t([s(),e("design:type",r)],UnlitShader.prototype,"uvScale",void 0);/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
package/dist/shader/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export * from './parameter.js';
|
|
|
2
2
|
export * from './builtin/index.js';
|
|
3
3
|
export * from './shader.js';
|
|
4
4
|
export * from './decal-shader.js';
|
|
5
|
+
export * from './post-process-shader.js';
|
|
5
6
|
export * from './sprite-shader.js';
|
|
6
7
|
export * from './trail-shader.js';
|
|
7
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/shader/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export*from"./parameter.js";export*from"./builtin/index.js";export*from"./shader.js";export*from"./decal-shader.js";export*from"./sprite-shader.js";export*from"./trail-shader.js";/*
|
|
1
|
+
export*from"./parameter.js";export*from"./builtin/index.js";export*from"./shader.js";export*from"./decal-shader.js";export*from"./post-process-shader.js";export*from"./sprite-shader.js";export*from"./trail-shader.js";/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ShaderMaterial } from 'three';
|
|
2
|
+
import { FloatNode, NodeShaderMaterial, Vec2Node, Vec3Node, Vec4Node } from '../shader-nodes/index.js';
|
|
3
|
+
export type PostProcessShaderOutput = Vec4Node | Vec3Node | Vec2Node | FloatNode;
|
|
4
|
+
export interface PostProcessMaterialBuilder {
|
|
5
|
+
build(): ShaderMaterial;
|
|
6
|
+
}
|
|
7
|
+
export type PostProcessMaterialSource = ShaderMaterial | PostProcessMaterialBuilder | PostProcessShaderOutput;
|
|
8
|
+
export declare function createPostProcessMaterial(color: PostProcessShaderOutput): NodeShaderMaterial;
|
|
9
|
+
export declare abstract class PostProcessShader implements PostProcessMaterialBuilder {
|
|
10
|
+
build(): ShaderMaterial;
|
|
11
|
+
abstract output(): PostProcessShaderOutput;
|
|
12
|
+
}
|
|
13
|
+
export declare function resolvePostProcessMaterial(source: PostProcessMaterialSource): ShaderMaterial;
|
|
14
|
+
//# sourceMappingURL=post-process-shader.d.ts.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{ShaderMaterial as e}from"three";import{BaseNode as t,NodeShaderMaterial as r}from"../shader-nodes/index.js";export function createPostProcessMaterial(e){const t=new r({color:e,transparent:!1,fog:!1,lights:!1,outputEncoding:!1});return t.depthWrite=!1,t.depthTest=!1,t.toneMapped=!1,t}export class PostProcessShader{build(){return createPostProcessMaterial(this.output())}}export function resolvePostProcessMaterial(r){return r instanceof t?createPostProcessMaterial(r):r instanceof e?r:r.build()}/*
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
|
+
* See the LICENSE.md file for details.
|
|
4
|
+
*/
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{vec2 as r}from"three-shader-graph";export function applyUvTiling(t,e){if(null==e)return t;const l=e.repeat;return null==l||1===l.x&&1===l.y?t:t.multiply(r(l))}/*
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
|
+
* See the LICENSE.md file for details.
|
|
4
|
+
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * from 'three-shader-graph';
|
|
2
|
-
export { linearEyeDepth, fragmentLinearEyeDepth, depthSampler, resolution,
|
|
2
|
+
export { linearEyeDepth, fragmentLinearEyeDepth, depthNormal, depthSampler, depthWorldPosition, resolution, sceneNormal, screenUV } from './depth.js';
|
|
3
3
|
export { timeUniforms } from './time.js';
|
|
4
4
|
export { particleUniforms } from './particle.js';
|
|
5
5
|
export * from './layers.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export*from"three-shader-graph";export{linearEyeDepth,fragmentLinearEyeDepth,depthSampler,resolution,screenUV
|
|
1
|
+
export*from"three-shader-graph";export{linearEyeDepth,fragmentLinearEyeDepth,depthNormal,depthSampler,depthWorldPosition,resolution,sceneNormal,screenUV}from"./depth.js";export{timeUniforms}from"./time.js";export{particleUniforms}from"./particle.js";export*from"./layers.js";export*from"./landscape.js";export*from"./shapes.js";export*from"./voronoi.js";export*from"./effects.js";export*from"./math.js";export*from"./bulge.js";export*from"./texture-sequence.js";export*from"./decal.js";export*from"./scene-sample.js";export*from"./curve-sample.js";export*from"./dither.js";/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{expect as e,test as o}from"vitest";import{Vector3 as s}from"three";import{createAuthoredCollisionShapes as t}from"../scene/asset-resource-loader.js";import{BoxCollisionShape as i,CapsuleCollisionShape as n,CylinderCollisionShape as l,SphereCollisionShape as r}from"../scene/collision/collision-shape.js";function a(o,s,t=1e-5){e(o.distanceTo(s)).toBeLessThan(t)}o("authored colliders are converted back to asset-local units when the asset is rescaled",()=>{const[o,d,c,p]=t([{id:"box",name:"Box Collider",type:"box",position:[.5,-1,2],size:[1,2,3]},{id:"sphere",name:"Sphere Collider",type:"sphere",position:[1,2,3],radius:.25},{id:"capsule",name:"Capsule Collider",type:"capsule",position:[-2,.5,4],radius:.2,length:1.5},{id:"cylinder",name:"Cylinder Collider",type:"cylinder",position:[3,-4,5],radius:.4,height:2.5}],.01);e(o).toBeInstanceOf(i),a(o.dimensions,new s(100,200,300)),a(o.offset,new s(50,-100,200)),e(d).toBeInstanceOf(r),e(d.radius).toBeCloseTo(25),a(d.offset,new s(100,200,300)),e(c).toBeInstanceOf(n),e(c.radius).toBeCloseTo(20),e(c.length).toBeCloseTo(150),a(c.offset,new s(-200,50,400)),e(p).toBeInstanceOf(l),e(p.radiusTop).toBeCloseTo(40),e(p.radiusBottom).toBeCloseTo(40),e(p.height).toBeCloseTo(250),a(p.offset,new s(300,-400,500))}),o("authored colliders keep their values when no asset rescale is applied",()=>{const[o]=t([{id:"box",name:"Box Collider",type:"box",position:[1,2,3],size:[4,5,6]}]);e(o).toBeInstanceOf(i),a(o.dimensions,new s(4,5,6)),a(o.offset,new s(1,2,3))});/*
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
|
+
* See the LICENSE.md file for details.
|
|
4
|
+
*/
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{describe as e,expect as t,it as a,vi as o}from"vitest";import*as i from"three";import{sampleCameraShake as n}from"../gameplay/services/camera-shake.js";async function r(e){let t=null;const{ViewController:a}=await import("../gameplay/services/render.js");return{viewController:new a({camera:e,running:!1,paused:!1,simulationTimeScale:1,onLoop(e){t=e},setCamera(e){this.camera=e},stop:o.fn()}),stepFrame(e){t?.(e)}}}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,a)=>(e[t]=a,!0)});Object.defineProperty(HTMLCanvasElement.prototype,"getContext",{configurable:!0,value:()=>e});class t{constructor(){this.currentTime=0,this.destination={},this.listener={positionX:{linearRampToValueAtTime:o.fn(),setValueAtTime:o.fn()},positionY:{linearRampToValueAtTime:o.fn(),setValueAtTime:o.fn()},positionZ:{linearRampToValueAtTime:o.fn(),setValueAtTime:o.fn()},forwardX:{linearRampToValueAtTime:o.fn(),setValueAtTime:o.fn()},forwardY:{linearRampToValueAtTime:o.fn(),setValueAtTime:o.fn()},forwardZ:{linearRampToValueAtTime:o.fn(),setValueAtTime:o.fn()},upX:{linearRampToValueAtTime:o.fn(),setValueAtTime:o.fn()},upY:{linearRampToValueAtTime:o.fn(),setValueAtTime:o.fn()},upZ:{linearRampToValueAtTime:o.fn(),setValueAtTime:o.fn()}}}createGain(){return{connect:o.fn(),disconnect:o.fn(),gain:{value:1,setValueAtTime:o.fn()}}}}Object.defineProperty(window,"AudioContext",{configurable:!0,value:t}),Object.defineProperty(window,"webkitAudioContext",{configurable:!0,value:t})}),e("view controller camera shake",()=>{a("applies gameplay-authored shake to the base camera without mutating the source camera",async()=>{const e=new i.PerspectiveCamera;e.position.set(2,0,0);const{viewController:a,stepFrame:o}=await r(e),s={duration:1,frequency:6,attack:0,decay:0,positionAmplitude:[1,0,0],rotationAmplitude:[0,0,0],seed:11};a.applyCameraShake(s),o(.25);const m=n(s,.25);t(a.getSourceCamera()).toBe(e),t(a.getCamera()).not.toBe(e),t(a.getCamera().position.x).toBeCloseTo(2+(m?.position[0]??0)),t(e.position.x).toBeCloseTo(2)}),a("applies gameplay-authored shake on top of an active camera override",async()=>{const e=new i.PerspectiveCamera;e.position.set(1,0,0);const a=new i.PerspectiveCamera;a.position.set(5,0,0);const{viewController:o,stepFrame:s}=await r(e),m={duration:1,frequency:8,attack:0,decay:0,positionAmplitude:[.5,0,0],rotationAmplitude:[0,0,0],seed:21},p=o.pushCameraOverride(a,{});o.applyCameraShake(m),s(.25);const l=n(m,.25);t(o.getSourceCamera()).toBe(a),t(o.getCamera().position.x).toBeCloseTo(5+(l?.position[0]??0)),p.release(),t(o.getSourceCamera()).toBe(e),t(o.getCamera().position.x).toBeCloseTo(1+(l?.position[0]??0))}),a("stacks overlapping shakes and restores the source camera when they expire",async()=>{const e=new i.PerspectiveCamera,{viewController:a,stepFrame:o}=await r(e),s={duration:.5,frequency:5,attack:0,decay:0,positionAmplitude:[.75,0,0],rotationAmplitude:[0,0,0],seed:31},m={duration:1,frequency:7,attack:0,decay:0,positionAmplitude:[.25,0,0],rotationAmplitude:[0,0,0],seed:47};a.applyCameraShake(s),a.applyCameraShake(m),o(.25);const p=(n(s,.25)?.position[0]??0)+(n(m,.25)?.position[0]??0);t(a.getCamera().position.x).toBeCloseTo(p),o(.4);const l=n(m,.65)?.position[0]??0;t(a.getCamera().position.x).toBeCloseTo(l),o(.5),t(a.getCamera()).toBe(e),t(a.getSourceCamera()).toBe(e)})});/*
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
|
+
* See the LICENSE.md file for details.
|
|
4
|
+
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{expect as e,test as
|
|
1
|
+
import{expect as e,test as n}from"vitest";import{BoxGeometry as t,Euler as o,Group as s,Mesh as i,MeshBasicMaterial as a,Quaternion as r,Vector3 as c}from"three";import{importCollisionShapes as l}from"../scene/collision/collision-shape-import.js";import{BoxCollisionShape as m,CollisionShapeSource as d,toInstancedCollisionShape as p}from"../scene/collision/collision-shape.js";import{calculateOBB as w}from"../utils/obb-utils.js";function u(n,t,o=1e-5){e(n.distanceTo(t)).toBeLessThan(o)}function f(n,t,o=1e-5){e(n.angleTo(t)).toBeLessThan(o)}n("box import keeps a stable local-axis box and composes only the mesh transform",()=>{const n=new s,o=new t(4,1,2);o.rotateX(.2),o.rotateY(.65),o.translate(.4,-.15,.3);const p=new i(o,new a);p.position.set(3,-2,1),p.rotation.set(.35,1.1,-.45),p.scale.set(1.5,1,.75),n.add(p),n.updateMatrixWorld(!0);o.computeBoundingBox();const w=o.boundingBox,h=w.getCenter(new c),x=w.getSize(new c),b=x.clone().multiply(p.scale),[y]=l(n,{mesh:{collisions:{shapeType:"box"}}}),B=y,E=h.clone().multiply(p.scale).applyQuaternion(p.quaternion).add(p.position);e(B).toBeInstanceOf(m),e(B.source).toBe(d.rendered),u(B.dimensions,b),u(B.offset,E),f((new r).setFromEuler(B.rotation),p.quaternion),u(B.instancedDimensions,x),u(B.instancedOffset,h),f((new r).setFromEuler(B.instancedRotation),new r)}),n("box import bakes scaled parent transforms into dimensions",()=>{const e=new s,n=new s,o=new i(new t(100,50,2),new a);n.scale.set(.01,.02,.5),n.add(o),e.add(n),e.updateMatrixWorld(!0);const[r]=l(e,{mesh:{collisions:{shapeType:"box"}}}),m=r;u(m.dimensions,new c(1,1,1)),u(m.instancedDimensions,new c(100,50,2))}),n("obb import composes the mesh transform with the local OBB transform",()=>{const n=new s,o=new t(4,1,2);o.rotateX(.2),o.rotateY(.65),o.translate(.4,-.15,.3);const c=new i(o,new a);c.position.set(3,-2,1),c.rotation.set(.35,1.1,-.45),c.scale.set(1.5,1,.75),n.add(c),n.updateMatrixWorld(!0);const[p]=l(n,{mesh:{collisions:{shapeType:"obb"}}}),h=p,x=w(o),b=x.center.clone().multiply(c.scale).applyQuaternion(c.quaternion).add(c.position),y=c.quaternion.clone().multiply((new r).setFromEuler(x.rotation));e(h).toBeInstanceOf(m),e(h.source).toBe(d.rendered),u(h.offset,b),f((new r).setFromEuler(h.rotation),y),u(h.instancedOffset,x.center),f((new r).setFromEuler(h.instancedRotation),(new r).setFromEuler(x.rotation))}),n("convex import keeps a rotated child mesh transform exactly once",()=>{const e=new s,n=new s,o=new i(new t(1,2,3),new a);o.rotation.set(-Math.PI/2,0,0),n.add(o),e.add(n),e.updateMatrixWorld(!0);const[c]=l(e,{mesh:{collisions:{shapeType:"convex"}}});f((new r).setFromEuler(c.rotation),o.quaternion)}),n("instanced collision shapes use the mesh-local transform without mutating the cached shape",()=>{const n=new m(new c(1,2,3));n.source=d.rendered,n.offset.set(10,11,12),n.rotation.set(.4,.5,.6),n.instancedOffset=new c(1,2,3),n.instancedRotation=new o(.1,.2,.3),n.instancedDimensions=new c(.25,.5,.75);const t=p(n);e(t).not.toBe(n),u(t.dimensions,n.instancedDimensions),u(t.offset,n.instancedOffset),f((new r).setFromEuler(t.rotation),(new r).setFromEuler(n.instancedRotation)),u(n.offset,new c(10,11,12)),u(n.dimensions,new c(1,2,3)),f((new r).setFromEuler(n.rotation),(new r).setFromEuler(new o(.4,.5,.6)))});/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{describe as e,expect as t,it as o,vi as r}from"vitest";import*as n from"three";import{float as a,NodeShaderMaterial as s}from"../shader-nodes/index.js";import{depthUniformName as i,farUniformName as u,nearUniformName as l,resolutionUniformName as f,sceneNormalUniformName as m}from"../shader-nodes/depth.js";import{aoMapUniformName as d}from"../shader-nodes/scene-sample.js";import{elapsedTimeUniformName as p}from"../shader-nodes/time.js";import{applyPostProcessEffectUniformState as c,defaultPostProcessEffectStage as T,postProcessEffectStages as A}from"../rendering/post-process-effect.js";import{createPostProcessMaterial as b,PostProcessShader as h}from"../shader/post-process-shader.js";r.hoisted(()=>{if("undefined"!=typeof window){if("undefined"!=typeof HTMLCanvasElement){const e=new Proxy({},{get:(e,t)=>(t in e||(e[t]=("string"!=typeof t||!t.startsWith("is"))&&r.fn()),e[t]),set:(e,t,o)=>(e[t]=o,!0)});Object.defineProperty(HTMLCanvasElement.prototype,"getContext",{configurable:!0,value:()=>e})}class e{constructor(){this.currentTime=0,this.destination={},this.listener={positionX:{linearRampToValueAtTime:r.fn(),setValueAtTime:r.fn()},positionY:{linearRampToValueAtTime:r.fn(),setValueAtTime:r.fn()},positionZ:{linearRampToValueAtTime:r.fn(),setValueAtTime:r.fn()},forwardX:{linearRampToValueAtTime:r.fn(),setValueAtTime:r.fn()},forwardY:{linearRampToValueAtTime:r.fn(),setValueAtTime:r.fn()},forwardZ:{linearRampToValueAtTime:r.fn(),setValueAtTime:r.fn()},upX:{linearRampToValueAtTime:r.fn(),setValueAtTime:r.fn()},upY:{linearRampToValueAtTime:r.fn(),setValueAtTime:r.fn()},upZ:{linearRampToValueAtTime:r.fn(),setValueAtTime:r.fn()}}}createGain(){return{connect:r.fn(),disconnect:r.fn(),gain:{value:1,setValueAtTime:r.fn()}}}}Object.defineProperty(window,"AudioContext",{configurable:!0,value:e}),Object.defineProperty(window,"webkitAudioContext",{configurable:!0,value:e})}});class v extends h{output(){return a(1)}}e("post-process effect",()=>{o("exports stable stage names with a default late-stage slot",()=>{t(A).toEqual(["beforeFog","beforeDepthOfField","beforeColorAdjustment","beforeOutline","beforeAntiAliasing","beforeLut","beforeOutput"]),t(T).toBe("beforeOutput")}),o("builds post-process shaders with fullscreen-safe defaults",()=>{const e=(new v).build();t(e).toBeInstanceOf(s),t(e.depthWrite).toBe(!1),t(e.depthTest).toBe(!1),t(e.toneMapped).toBe(!1)}),o("updates shared renderer uniforms on post-process effect materials",()=>{const e=b(a(1));e.uniforms[f]={value:new n.Vector2},e.uniforms[i]={value:null},e.uniforms[m]={value:null},e.uniforms[l]={value:0},e.uniforms[u]={value:0},e.uniforms[p]={value:0},e.uniforms[d]={value:null};const o=new n.Texture,r=new n.Texture,s=new n.Texture,T=new n.Vector2(640,360);c(e,{aoEnabled:!0,aoTexture:s,cameraFar:500,cameraNear:.25,depthTexture:o,normalTexture:r,resolution:T,simulationTime:12.5}),t(e.uniforms[f].value.toArray()).toEqual([640,360]),t(e.uniforms[i].value).toBe(o),t(e.uniforms[m].value).toBe(r),t(e.uniforms[l].value).toBe(.25),t(e.uniforms[u].value).toBe(500),t(e.uniforms[p].value).toBe(12.5),t(e.uniforms[d].value).toBe(s),t(e.defines.USE_SSAO_MAP).toBe(""),c(e,{aoEnabled:!1,aoTexture:null,cameraFar:500,cameraNear:.25,depthTexture:o,normalTexture:r,resolution:T,simulationTime:13}),t(e.uniforms[d].value).toBeNull(),t(e.defines.USE_SSAO_MAP).toBeUndefined()}),o("exposes post-process effect registration through ViewController",async()=>{const e=b(a(1)),o={material:e,enabled:!1,priority:4,stage:"beforeColorAdjustment",dispose:r.fn()},s=r.fn().mockReturnValue(o),{ViewController:i}=await import("../gameplay/services/render.js"),u=new i({camera:new n.PerspectiveCamera,running:!1,paused:!1,onLoop:r.fn(),setCamera(e){this.camera=e},stop:r.fn(),addPostProcessEffect:s,addPostProcessVolume:r.fn(),removePostProcessVolume:r.fn()}).addPostProcessEffect(e,{enabled:!1,priority:4,stage:"beforeColorAdjustment"});t(s).toHaveBeenCalledWith(e,{enabled:!1,priority:4,stage:"beforeColorAdjustment"}),t(u).toBe(o)})});/*
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
|
+
* See the LICENSE.md file for details.
|
|
4
|
+
*/
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{describe as e,expect as a,it as t,vi as o}from"vitest";import*as n from"three";import{createCameraClipInstance as s,createCameraShakeClipInstance as r,createCameraShakeTrack as i,createCameraTrack as c,createSequenceData as l,createTransformKeyframe as m,createTransformSubTrack as p,SequenceRole as u}from"../effects/sequence/sequence-data.js";import{BaseActor as f}from"../gameplay/actors/actor.js";import{sampleCameraShake as d}from"../gameplay/services/camera-shake.js";async function C(e){const{SequencePlayer:a}=await import("../effects/sequence/sequence-player.js"),t=new a;return t.setWorld({scene:new n.Scene}),t.setViewController(e),t}async function w(e){const{ViewController:a}=await import("../gameplay/services/render.js");return new a({camera:e,running:!1,paused:!1,onLoop:o.fn(),setCamera(e){this.camera=e},stop:o.fn()})}function y(e,a,t){const o=c(),n=s(a,t);n.blendInDuration=0,n.blendOutDuration=0,o.clips.push(n);const r=p(),i=m(a);return i.position=e,r.keyframes.push(i),o.subTracks.push(r),o}function T(e,a,t){const o=i(),n=r(e,a);return n.attack=0,n.decay=0,n.frequency=8,n.positionAmplitude=t,n.rotationAmplitude=[0,0,0],n.seed=17,o.clips.push(n),o}o.mock("../gameplay/actors/builtin/index.js",()=>({builtInActors:{},default:{}})),o.mock("../gameplay/actors/index.js",()=>({CharacterAnimationComponent:class{},CharacterMovementComponent:class{}})),o.mock("../effects/vfx/vfx-actor.js",()=>({VfxActor:class{}})),o.mock("../effects/vfx/vfx-param.js",()=>({VisualEffect:class{}})),o.mock("../effects/vfx/vfx-service.js",()=>({VfxService:class{}})),o.hoisted(()=>{if("undefined"==typeof HTMLCanvasElement)return;const e=new Proxy({},{get:(e,a)=>(a in e||(e[a]=("string"!=typeof a||!a.startsWith("is"))&&o.fn()),e[a]),set:(e,a,t)=>(e[a]=t,!0)});Object.defineProperty(HTMLCanvasElement.prototype,"getContext",{configurable:!0,value:()=>e});class a{constructor(){this.currentTime=0,this.destination={},this.listener={positionX:{linearRampToValueAtTime:o.fn(),setValueAtTime:o.fn()},positionY:{linearRampToValueAtTime:o.fn(),setValueAtTime:o.fn()},positionZ:{linearRampToValueAtTime:o.fn(),setValueAtTime:o.fn()},forwardX:{linearRampToValueAtTime:o.fn(),setValueAtTime:o.fn()},forwardY:{linearRampToValueAtTime:o.fn(),setValueAtTime:o.fn()},forwardZ:{linearRampToValueAtTime:o.fn(),setValueAtTime:o.fn()},upX:{linearRampToValueAtTime:o.fn(),setValueAtTime:o.fn()},upY:{linearRampToValueAtTime:o.fn(),setValueAtTime:o.fn()},upZ:{linearRampToValueAtTime:o.fn(),setValueAtTime:o.fn()}}}createGain(){return{connect:o.fn(),disconnect:o.fn(),gain:{value:1,setValueAtTime:o.fn()}}}}Object.defineProperty(window,"AudioContext",{configurable:!0,value:a}),Object.defineProperty(window,"webkitAudioContext",{configurable:!0,value:a})}),e("sequencer camera control",()=>{t("keeps setCamera as the base camera while an override lease is active",async()=>{const e=new n.PerspectiveCamera,t=new n.PerspectiveCamera,o=new n.PerspectiveCamera,s=await w(e),r=s.pushCameraOverride(t,{});a(s.getCamera()).toBe(t),s.setCamera(o),a(s.getBaseCamera()).toBe(o),a(s.getCamera()).toBe(t),r.release(),a(s.getCamera()).toBe(o)}),t("does not take over the local camera unless camera control is enabled",async()=>{const e=new n.PerspectiveCamera,t=await w(e),o=await C(t),s=y([5,0,0],0,1);o.load({...l(),duration:1,tracks:[s]}),o.play(),a(t.getCamera()).toBe(e)}),t("activates an opted-in camera shot and releases it after the clip",async()=>{const e=new n.PerspectiveCamera,t=await w(e),o=await C(t),s=y([5,2,1],0,1);o.cameraControlEnabled=!0,o.load({...l(),duration:2,tracks:[s]}),o.play(),a(t.getCamera()).not.toBe(e),a(t.getCamera().position.toArray()).toEqual([5,2,1]),o.seek(1.1),a(t.getCamera()).toBe(e)}),t("uses the later camera track when shots overlap",async()=>{const e=new n.PerspectiveCamera,t=await w(e),o=await C(t),s=y([1,0,0],0,1),r=y([7,0,0],0,1);o.cameraControlEnabled=!0,o.load({...l(),duration:1,tracks:[s,r]}),o.play(),a(t.getCamera().position.x).toBeCloseTo(7)}),t("blends into the camera shot using the clip blend settings",async()=>{const e=new n.PerspectiveCamera;e.position.set(0,0,0);const t=await w(e),o=await C(t),s=y([10,0,0],0,2);s.clips[0].blendInDuration=1,s.clips[0].blendInterpolation="linear",o.cameraControlEnabled=!0,o.load({...l(),duration:2,tracks:[s]}),o.play(),o.seek(.5),a(t.getCamera().position.x).toBeCloseTo(5)}),t("anchors camera tracks to bound roles",async()=>{const e=new n.PerspectiveCamera,t=await w(e),o=await C(t),s=new h;s.object.position.set(10,0,0);const r=y([1,0,0],0,1);r.parentRole=u.Self,o.cameraControlEnabled=!0,o.bindRole(u.Self,s),o.load({...l(),duration:1,tracks:[r]}),o.play(),a(t.getCamera().position.x).toBeCloseTo(11)}),t("applies camera shake tracks without taking over the local camera",async()=>{const e=new n.PerspectiveCamera,t=await w(e),o=await C(t),s=T(0,1,[.8,0,0]);o.load({...l(),duration:1,tracks:[s]}),o.play(),o.seek(.2);const r=d(s.clips[0],.2);a(t.getSourceCamera()).toBe(e),a(t.getCamera()).not.toBe(e),a(t.getCamera().position.x).toBeCloseTo(e.position.x+(r?.position[0]??0))}),t("layers camera shake on top of a controlled camera shot",async()=>{const e=new n.PerspectiveCamera,t=await w(e),o=await C(t),s=y([10,0,0],0,1),r=T(0,1,[.6,0,0]);o.cameraControlEnabled=!0,o.load({...l(),duration:1,tracks:[s,r]}),o.play(),o.seek(.2);const i=d(r.clips[0],.2);a(t.getSourceCamera().position.x).toBeCloseTo(10),a(t.getCamera().position.x).toBeCloseTo(10+(i?.position[0]??0))}),t("blends camera shots from the unshaken source camera when shake is already active",async()=>{const e=new n.PerspectiveCamera,t=await w(e),o=await C(t),s=y([10,0,0],.5,1);s.clips[0].blendInDuration=1,s.clips[0].blendInterpolation="linear";const r=T(0,2,[.6,0,0]);o.cameraControlEnabled=!0,o.load({...l(),duration:2,tracks:[s,r]}),o.play(),o.seek(.25),o.seek(.75);const i=d(r.clips[0],.75);a(t.getSourceCamera().position.x).toBeCloseTo(2.5),a(t.getCamera().position.x).toBeCloseTo(2.5+(i?.position[0]??0))}),t("clears sequence-owned camera shake when stopped",async()=>{const e=new n.PerspectiveCamera,t=await w(e),o=await C(t),s=T(0,1,[.8,0,0]);o.load({...l(),duration:1,tracks:[s]}),o.play(),o.seek(.2),a(t.getCamera()).not.toBe(e),o.stop(),a(t.getCamera()).toBe(e)})});class h extends f{}/*
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
|
+
* See the LICENSE.md file for details.
|
|
4
|
+
*/
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{describe as e,expect as t,it as o}from"vitest";import{Color as r,Euler as a,Vector3 as l}from"three";import{canTrackAddSubTrack as s,createPropertyKeyframe as n,createPropertySubTrack as p,createSpawnTrack as i,evaluateCustomParamValueKeyframes as u,SequencePlayer as y}from"../effects/sequence/index.js";import{SerializedParamType as g}from"../scene/model.js";e("sequence property parameter tracks",()=>{o("allows multiple property sub-tracks on spawn tracks but rejects duplicate property paths",()=>{const e=i(),o=p({propertyPath:"settings.globalGain",propertyType:g.Vector3});t(s(e,"property",{propertyPath:"settings.globalGain"})).toBe(!0),e.subTracks.push(o),t(s(e,"property",{propertyPath:"settings.globalGain"})).toBe(!1),t(s(e,"property",{propertyPath:"settings.globalGamma"})).toBe(!0)}),o("interpolates number, vector, color, and Euler property keyframes",()=>{const e=u([n(0,{type:g.Number,value:0}),n(1,{type:g.Number,value:10})],.5);t(e?.value).toBeCloseTo(5);const o=u([n(0,{type:g.Vector3,value:[0,0,0]}),n(1,{type:g.Vector3,value:[2,4,6]})],.5,{min:0,max:3});t(o?.value).toEqual([1,2,3]);const a=u([n(0,{type:g.Color,value:"#000000"}),n(1,{type:g.Color,value:"#ffffff"})],.5);t(a?.value).toBe(`#${new r("#000000").lerp(new r("#ffffff"),.5).getHexString()}`);const l=u([n(0,{type:g.Euler,value:[0,0,0,"XYZ"]}),n(1,{type:g.Euler,value:[1,2,3,"XYZ"]})],.5);t(l?.value).toEqual([.5,1,1.5,"XYZ"])}),o("uses step evaluation for booleans and options-backed values",()=>{const e=u([n(0,{type:g.Boolean,value:!1}),n(1,{type:g.Boolean,value:!0})],.5,{stepOnly:!0});t(e?.value).toBe(!1);const o=u([n(0,{type:g.Number,value:1}),n(1,{type:g.Number,value:2})],.5,{stepOnly:!0});t(o?.value).toBe(1)}),o("applies nested property paths and restores an original undefined value",()=>{const e={settings:{globalGain:void 0}},o=p({propertyPath:"settings.globalGain",propertyType:g.Vector3}),r=new y;r.applyResolvedPropertyValue(o,e,{type:g.Vector3,value:[1,2,3]}),t(e.settings.globalGain).toBeInstanceOf(l),t(e.settings.globalGain?.toArray()).toEqual([1,2,3]),r.stop(),t(Object.prototype.hasOwnProperty.call(e.settings,"globalGain")).toBe(!0),t(e.settings.globalGain).toBeUndefined()}),o("mutates existing mutable values and restores their original value",()=>{const e=new l(9,8,7),o=new r("#112233"),s=new a(.1,.2,.3,"XYZ"),n={settings:{globalGain:e,colorTint:o,rotation:s}},i=new y;i.applyResolvedPropertyValue(p({propertyPath:"settings.globalGain",propertyType:g.Vector3}),n,{type:g.Vector3,value:[1,2,3]}),i.applyResolvedPropertyValue(p({propertyPath:"settings.colorTint",propertyType:g.Color}),n,{type:g.Color,value:"#ffffff"}),i.applyResolvedPropertyValue(p({propertyPath:"settings.rotation",propertyType:g.Euler}),n,{type:g.Euler,value:[1,2,3,"XYZ"]}),t(n.settings.globalGain).toBe(e),t(n.settings.globalGain.toArray()).toEqual([1,2,3]),t(n.settings.colorTint).toBe(o),t(n.settings.colorTint.getHexString()).toBe("ffffff"),t(n.settings.rotation).toBe(s),t(n.settings.rotation.toArray()).toEqual([1,2,3,"XYZ"]),i.stop(),t(n.settings.globalGain).toBe(e),t(n.settings.globalGain.toArray()).toEqual([9,8,7]),t(n.settings.colorTint).toBe(o),t(n.settings.colorTint.getHexString()).toBe("112233"),t(n.settings.rotation).toBe(s),t(n.settings.rotation.toArray()).toEqual([.1,.2,.3,"XYZ"])})});/*
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
|
+
* See the LICENSE.md file for details.
|
|
4
|
+
*/
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{afterEach as e,beforeEach as t,describe as a,expect as r,it as o,vi as i}from"vitest";import{createRequire as s}from"node:module";import*as n from"node:fs/promises";import*as c from"node:os";import*as d from"node:path";const w=s(import.meta.url);let l,f,m;async function p(){const{ObjectStorage:e}=await import("../scene/storage/storage.js"),t=new e("asset");return t.setBasePath("data"),t}a("ObjectStorage case-insensitive file collisions",()=>{t(async()=>{i.resetModules(),f=window.require,m=window.process,l=await n.mkdtemp(d.join(c.tmpdir(),"hology-storage-")),await n.writeFile(d.join(l,"vite.config.ts"),"hologyBuild()"),Object.defineProperty(window,"require",{configurable:!0,value:e=>"chokidar"===e?{watch:()=>({on:()=>{},close:()=>{}})}:w(e)}),Object.defineProperty(window,"process",{configurable:!0,value:{argv:[`--path=${l}`]}})}),e(async()=>{await n.rm(l,{recursive:!0,force:!0}),Object.defineProperty(window,"require",{configurable:!0,value:f}),Object.defineProperty(window,"process",{configurable:!0,value:m})}),o("rejects create names that only differ by case",async()=>{const e=await p();await e.create({name:"dirt"}),await r(e.create({name:"Dirt"})).rejects.toThrow(/differs beyond letter casing/),await r(e.getAll()).resolves.toHaveLength(1)}),o("rejects prepared saves that only differ by case",async()=>{const e=await p();await e.create({name:"dirt"});const t=e.prepareCreate({name:"Dirt"});await r(e.save(t)).rejects.toThrow(/differs beyond letter casing/),await r(e.getAll()).resolves.toHaveLength(1)}),o("rejects renames that only differ by case from another object",async()=>{const e=await p();await e.create({name:"dirt"});const t=await e.create({name:"sand"});await r(e.rename(t,"Dirt")).rejects.toThrow(/differs beyond letter casing/),await r(e.get(t.id)).resolves.toMatchObject({name:"sand"})})});/*
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
|
+
* See the LICENSE.md file for details.
|
|
4
|
+
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hology/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.198",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -177,7 +177,7 @@
|
|
|
177
177
|
"recast-navigation": "0.39.0",
|
|
178
178
|
"rxjs": "7.8.1",
|
|
179
179
|
"three-mesh-bvh": "^0.7.5",
|
|
180
|
-
"three-shader-graph": "^0.2.
|
|
180
|
+
"three-shader-graph": "^0.2.47",
|
|
181
181
|
"three-stdlib": "2.34.0",
|
|
182
182
|
"ts-key-enum": "^2.0.12",
|
|
183
183
|
"typedi": "^0.10.0"
|