@hology/core 0.0.197 → 0.0.199
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-data.d.ts +32 -3
- package/dist/effects/sequence/sequence-data.js +1 -1
- package/dist/effects/sequence/sequence-definitions.d.ts +1 -1
- 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 +7 -0
- package/dist/effects/sequence/sequence-player.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/index.d.ts +1 -0
- package/dist/gameplay/index.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/render.d.ts +33 -1
- 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 +10 -0
- 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/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/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/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.js +1 -1
- package/package.json +2 -2
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -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
|
+
*/
|
|
@@ -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
|
+
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{describe as e,expect as a,it as t,vi as o}from"vitest";import*as
|
|
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
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.
|
|
3
|
+
"version": "0.0.199",
|
|
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.48",
|
|
181
181
|
"three-stdlib": "2.34.0",
|
|
182
182
|
"ts-key-enum": "^2.0.12",
|
|
183
183
|
"typedi": "^0.10.0"
|