@fonsecabarreto/genesis-gl-core 0.1.3 → 0.1.33

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 (37) hide show
  1. package/dist/Core/classes/Material.d.ts +1 -1
  2. package/dist/Core/classes/Material.js +1 -1
  3. package/dist/Core/classes/Model.d.ts +2 -2
  4. package/dist/Core/classes/Renderer.d.ts +4 -2
  5. package/dist/Core/classes/Renderer.js +4 -4
  6. package/dist/Core/classes/Scene.d.ts +3 -3
  7. package/dist/Core/classes/Scene.js +1 -1
  8. package/dist/Core/classes/Viewport.d.ts +4 -1
  9. package/dist/Core/classes/Viewport.js +1 -1
  10. package/dist/Core/index.d.ts +73 -3
  11. package/dist/Core/index.js +13 -7
  12. package/dist/Core/utils/load-glb.d.ts +2 -2
  13. package/dist/Core/utils/load-glb.js +4 -4
  14. package/dist/Core/utils/parse-obj.d.ts +2 -2
  15. package/dist/Core/utils/parse-obj.js +4 -4
  16. package/dist/Game/controls/KeyboardInput.d.ts +3 -3
  17. package/dist/Game/index.d.ts +4 -4
  18. package/dist/Game/index.js +5 -5
  19. package/dist/{KeyboardInput-1xOAabI0.d.ts → KeyboardInput-RJ0mbuWM.d.ts} +1 -1
  20. package/dist/{Material-DhwSRbP2.d.ts → Material-A-7kKes_.d.ts} +2 -0
  21. package/dist/{Model-BBZHnUp1.d.ts → Model-efZcQkOK.d.ts} +2 -2
  22. package/dist/{chunk-ZCJ3MJZD.js → chunk-4M3XFPH3.js} +17 -3
  23. package/dist/chunk-4M3XFPH3.js.map +1 -0
  24. package/dist/chunk-IOAANJZG.js +159 -0
  25. package/dist/chunk-IOAANJZG.js.map +1 -0
  26. package/dist/{chunk-XMW2MS66.js → chunk-WHOIVV44.js} +19 -12
  27. package/dist/chunk-WHOIVV44.js.map +1 -0
  28. package/dist/{chunk-3ULETMWF.js → chunk-WKSDPPXS.js} +4 -3
  29. package/dist/{chunk-3ULETMWF.js.map → chunk-WKSDPPXS.js.map} +1 -1
  30. package/dist/{chunk-L66K4AZU.js → chunk-XCYJCLHB.js} +3 -1
  31. package/dist/chunk-XCYJCLHB.js.map +1 -0
  32. package/package.json +1 -1
  33. package/dist/chunk-L66K4AZU.js.map +0 -1
  34. package/dist/chunk-SUNYSY45.js +0 -81
  35. package/dist/chunk-SUNYSY45.js.map +0 -1
  36. package/dist/chunk-XMW2MS66.js.map +0 -1
  37. package/dist/chunk-ZCJ3MJZD.js.map +0 -1
@@ -1,3 +1,3 @@
1
1
  import '../domain/interfaces/Vectors.js';
2
- export { M as MAX_LIGHTS, b as Material } from '../../Material-DhwSRbP2.js';
2
+ export { M as MAX_LIGHTS, b as Material } from '../../Material-A-7kKes_.js';
3
3
  import '../../WebGLCore-DR7ZHJB0.js';
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  MAX_LIGHTS,
3
3
  Material
4
- } from "../../chunk-L66K4AZU.js";
4
+ } from "../../chunk-XCYJCLHB.js";
5
5
  export {
6
6
  MAX_LIGHTS,
7
7
  Material
@@ -1,5 +1,5 @@
1
1
  import 'gl-matrix';
2
- export { i as Model } from '../../Model-BBZHnUp1.js';
2
+ export { i as Model } from '../../Model-efZcQkOK.js';
3
3
  import '../domain/interfaces/Vectors.js';
4
4
  import '../../WebGLCore-DR7ZHJB0.js';
5
- import '../../Material-DhwSRbP2.js';
5
+ import '../../Material-A-7kKes_.js';
@@ -1,8 +1,8 @@
1
1
  import { W as WebGLCore } from '../../WebGLCore-DR7ZHJB0.js';
2
2
  import { Scene } from './Scene.js';
3
- import { i as Model } from '../../Model-BBZHnUp1.js';
3
+ import { i as Model } from '../../Model-efZcQkOK.js';
4
4
  import { Viewport } from './Viewport.js';
5
- import '../../Material-DhwSRbP2.js';
5
+ import '../../Material-A-7kKes_.js';
6
6
  import '../domain/interfaces/Vectors.js';
7
7
  import 'gl-matrix';
8
8
  import '../../Camera-CJVYy9fH.js';
@@ -12,6 +12,8 @@ declare class Renderer {
12
12
  viewport: Viewport;
13
13
  /** Set to `true` to render wireframe bounding boxes for debugging. */
14
14
  debug: boolean;
15
+ /** RGBA clear color used at the start of each frame. */
16
+ clearColor: [number, number, number, number];
15
17
  private _modelHitboxMaterial;
16
18
  private _meshHitboxMaterial;
17
19
  private readonly _modelWireBoxCache;
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  Renderer
3
- } from "../../chunk-ZCJ3MJZD.js";
4
- import "../../chunk-L66K4AZU.js";
3
+ } from "../../chunk-4M3XFPH3.js";
4
+ import "../../chunk-XCYJCLHB.js";
5
5
  import "../../chunk-QOAQVTAB.js";
6
- import "../../chunk-3ULETMWF.js";
7
- import "../../chunk-XMW2MS66.js";
6
+ import "../../chunk-WKSDPPXS.js";
7
+ import "../../chunk-WHOIVV44.js";
8
8
  export {
9
9
  Renderer
10
10
  };
@@ -1,5 +1,5 @@
1
- import { L as Light } from '../../Material-DhwSRbP2.js';
2
- import { i as Model } from '../../Model-BBZHnUp1.js';
1
+ import { L as Light } from '../../Material-A-7kKes_.js';
2
+ import { i as Model } from '../../Model-efZcQkOK.js';
3
3
  import { W as WebGLCore } from '../../WebGLCore-DR7ZHJB0.js';
4
4
  import '../domain/interfaces/Vectors.js';
5
5
  import 'gl-matrix';
@@ -21,7 +21,7 @@ declare class Scene {
21
21
  /** Register a light source in the scene. */
22
22
  addLight(id: string, light: Light): void;
23
23
  /** Add a model to the scene with a unique key. */
24
- add(id: string, model: Model): void;
24
+ add(id: string, model: Model, prepend?: boolean): void;
25
25
  /** Remove a model from the scene by key. */
26
26
  remove(key: string): void;
27
27
  getModels(): Model[];
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Scene
3
- } from "../../chunk-3ULETMWF.js";
3
+ } from "../../chunk-WKSDPPXS.js";
4
4
  export {
5
5
  Scene
6
6
  };
@@ -24,11 +24,14 @@ declare class Viewport {
24
24
  * GL context is reused for viewport resize instead of
25
25
  * requesting a new one.
26
26
  */
27
- constructor(canvasOrId: string | HTMLCanvasElement, width: number, height: number, webglCore?: WebGLCore);
27
+ constructor(canvasOrId: string | HTMLCanvasElement, width: number, height: number, webglCore?: WebGLCore, options?: {
28
+ pointerLock?: boolean;
29
+ });
28
30
  private setupControls;
29
31
  isDraggingCamera(): boolean;
30
32
  private resizeCanvas;
31
33
  getCanvas(): HTMLCanvasElement;
34
+ getWebGLCore(): WebGLCore | null;
32
35
  getScale(): number;
33
36
  /** Release event listeners. Call when the viewport is no longer needed. */
34
37
  dispose(): void;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Viewport
3
- } from "../../chunk-XMW2MS66.js";
3
+ } from "../../chunk-WHOIVV44.js";
4
4
  export {
5
5
  Viewport
6
6
  };
@@ -1,10 +1,80 @@
1
- export { A as AnimationChannel, a as AnimationClip, b as AnimationPath, c as AnimationSampler, G as GL_LINES, d as GL_TRIANGLES, I as INITIAL_BOUNDING_BOX, e as InterpolationMode, J as Joint, f as JointPose, M as MAX_JOINTS, g as Mesh, h as MeshBuffers, i as Model, S as Skeleton } from '../Model-BBZHnUp1.js';
2
- export { R as RenderCallback, W as WebGLCore } from '../WebGLCore-DR7ZHJB0.js';
1
+ import { M as Mesh } from '../Model-efZcQkOK.js';
2
+ export { A as AnimationChannel, a as AnimationClip, b as AnimationPath, c as AnimationSampler, G as GL_LINES, d as GL_TRIANGLES, I as INITIAL_BOUNDING_BOX, e as InterpolationMode, J as Joint, f as JointPose, g as MAX_JOINTS, h as MeshBuffers, i as Model, S as Skeleton } from '../Model-efZcQkOK.js';
3
+ import { W as WebGLCore } from '../WebGLCore-DR7ZHJB0.js';
4
+ export { R as RenderCallback } from '../WebGLCore-DR7ZHJB0.js';
3
5
  export { C as Camera } from '../Camera-CJVYy9fH.js';
4
- export { L as Light, a as LightType, M as MAX_LIGHTS, b as Material } from '../Material-DhwSRbP2.js';
6
+ export { L as Light, a as LightType, M as MAX_LIGHTS, b as Material } from '../Material-A-7kKes_.js';
5
7
  export { Renderer } from './classes/Renderer.js';
6
8
  export { Scene } from './classes/Scene.js';
7
9
  export { Viewport } from './classes/Viewport.js';
8
10
  export { K as KeyboardControl } from '../KeyboardControl-5w7Vm0J0.js';
9
11
  import 'gl-matrix';
10
12
  import './domain/interfaces/Vectors.js';
13
+
14
+ interface IMouseControl {
15
+ enable(): void;
16
+ disable(): void;
17
+ }
18
+
19
+ type DragListener = (dx: number, dy: number, button: number) => void;
20
+ declare class MouseDragControl implements IMouseControl {
21
+ private element;
22
+ private listeners;
23
+ isDragging: boolean;
24
+ private dragButton;
25
+ private lastX;
26
+ private lastY;
27
+ constructor(element: HTMLElement);
28
+ enable(): void;
29
+ disable(): void;
30
+ onChange(listener: DragListener): void;
31
+ /** Remove a previously registered listener. */
32
+ removeListener(listener: DragListener): void;
33
+ private onMouseDown;
34
+ private onMouseUp;
35
+ private onMouseMove;
36
+ }
37
+
38
+ type MoveListener = (dx: number, dy: number) => void;
39
+ /**
40
+ * Captures mouse movement using the Pointer Lock API.
41
+ * Ideal for camera-like controls where the cursor should not hit screen edges.
42
+ */
43
+ declare class MousePointerLockControl implements IMouseControl {
44
+ private element;
45
+ private sensitivity;
46
+ private listeners;
47
+ private isEnabled;
48
+ private isPointerLocked;
49
+ constructor(element: HTMLElement, sensitivity?: number);
50
+ enable(): void;
51
+ disable(): void;
52
+ onChange(listener: MoveListener): void;
53
+ /** Remove a previously registered listener. */
54
+ removeListener(listener: MoveListener): void;
55
+ setSensitivity(value: number): void;
56
+ private requestPointerLock;
57
+ private onPointerLockChange;
58
+ private onMouseMove;
59
+ }
60
+
61
+ interface GroundShadowOptions {
62
+ /** World Y position of the shadow plane. Default 0. */
63
+ y?: number;
64
+ /** Half-size of the shadow quad in world units. Default 1.5. */
65
+ radius?: number;
66
+ /** Peak shadow opacity at center, 0–1. Default 0.55. */
67
+ opacity?: number;
68
+ /** Shadow color as [r, g, b]. Default [0, 0, 0]. */
69
+ color?: [number, number, number];
70
+ /** How tight the falloff is. 0 = linear, higher = softer edges. Default 0.5. */
71
+ falloff?: number;
72
+ }
73
+ /**
74
+ * Creates a flat quad lying on the XZ plane with a soft radial-gradient shadow
75
+ * texture. The gradient fades from dark at the center to transparent at the edge,
76
+ * approximating a contact shadow beneath a model.
77
+ */
78
+ declare function createGroundShadow(webglCore: WebGLCore, options?: GroundShadowOptions): Mesh;
79
+
80
+ export { type GroundShadowOptions, Mesh, MouseDragControl, MousePointerLockControl, WebGLCore, createGroundShadow };
@@ -1,6 +1,7 @@
1
1
  import {
2
- KeyboardControl
3
- } from "../chunk-SUNYSY45.js";
2
+ KeyboardControl,
3
+ createGroundShadow
4
+ } from "../chunk-IOAANJZG.js";
4
5
  import {
5
6
  AnimationClip,
6
7
  GL_LINES,
@@ -12,22 +13,24 @@ import {
12
13
  Renderer,
13
14
  Skeleton,
14
15
  WebGLCore
15
- } from "../chunk-ZCJ3MJZD.js";
16
+ } from "../chunk-4M3XFPH3.js";
16
17
  import {
17
18
  MAX_LIGHTS,
18
19
  Material
19
- } from "../chunk-L66K4AZU.js";
20
+ } from "../chunk-XCYJCLHB.js";
20
21
  import {
21
22
  Model
22
23
  } from "../chunk-QOAQVTAB.js";
23
24
  import {
24
25
  Light,
25
26
  Scene
26
- } from "../chunk-3ULETMWF.js";
27
+ } from "../chunk-WKSDPPXS.js";
27
28
  import {
28
29
  Camera,
30
+ MouseDragControl,
31
+ MousePointerLockControl,
29
32
  Viewport
30
- } from "../chunk-XMW2MS66.js";
33
+ } from "../chunk-WHOIVV44.js";
31
34
  export {
32
35
  AnimationClip,
33
36
  Camera,
@@ -42,10 +45,13 @@ export {
42
45
  Mesh,
43
46
  MeshBuffers,
44
47
  Model,
48
+ MouseDragControl,
49
+ MousePointerLockControl,
45
50
  Renderer,
46
51
  Scene,
47
52
  Skeleton,
48
53
  Viewport,
49
- WebGLCore
54
+ WebGLCore,
55
+ createGroundShadow
50
56
  };
51
57
  //# sourceMappingURL=index.js.map
@@ -1,8 +1,8 @@
1
1
  import { W as WebGLCore } from '../../WebGLCore-DR7ZHJB0.js';
2
- import { i as Model, S as Skeleton, a as AnimationClip } from '../../Model-BBZHnUp1.js';
2
+ import { i as Model, S as Skeleton, a as AnimationClip } from '../../Model-efZcQkOK.js';
3
3
  import 'gl-matrix';
4
4
  import '../domain/interfaces/Vectors.js';
5
- import '../../Material-DhwSRbP2.js';
5
+ import '../../Material-A-7kKes_.js';
6
6
 
7
7
  /** Everything parsed from a GLB file. */
8
8
  interface GLBLoadResult {
@@ -3,15 +3,15 @@ import {
3
3
  GL_TRIANGLES,
4
4
  Mesh,
5
5
  Skeleton
6
- } from "../../chunk-ZCJ3MJZD.js";
6
+ } from "../../chunk-4M3XFPH3.js";
7
7
  import {
8
8
  Material
9
- } from "../../chunk-L66K4AZU.js";
9
+ } from "../../chunk-XCYJCLHB.js";
10
10
  import {
11
11
  Model
12
12
  } from "../../chunk-QOAQVTAB.js";
13
- import "../../chunk-3ULETMWF.js";
14
- import "../../chunk-XMW2MS66.js";
13
+ import "../../chunk-WKSDPPXS.js";
14
+ import "../../chunk-WHOIVV44.js";
15
15
 
16
16
  // src/Core/utils/load-glb.ts
17
17
  import { mat4, quat, vec3 } from "gl-matrix";
@@ -1,7 +1,7 @@
1
1
  import { W as WebGLCore } from '../../WebGLCore-DR7ZHJB0.js';
2
- import { b as Material } from '../../Material-DhwSRbP2.js';
2
+ import { b as Material } from '../../Material-A-7kKes_.js';
3
3
  import { Vector3 } from '../domain/interfaces/Vectors.js';
4
- import { i as Model } from '../../Model-BBZHnUp1.js';
4
+ import { i as Model } from '../../Model-efZcQkOK.js';
5
5
  import 'gl-matrix';
6
6
 
7
7
  declare function loadMTL(url: string, webglCore: WebGLCore): Promise<Record<string, Material>>;
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  Mesh
3
- } from "../../chunk-ZCJ3MJZD.js";
3
+ } from "../../chunk-4M3XFPH3.js";
4
4
  import {
5
5
  Material
6
- } from "../../chunk-L66K4AZU.js";
6
+ } from "../../chunk-XCYJCLHB.js";
7
7
  import {
8
8
  Model
9
9
  } from "../../chunk-QOAQVTAB.js";
10
- import "../../chunk-3ULETMWF.js";
11
- import "../../chunk-XMW2MS66.js";
10
+ import "../../chunk-WKSDPPXS.js";
11
+ import "../../chunk-WHOIVV44.js";
12
12
 
13
13
  // src/Core/utils/parse-obj.ts
14
14
  function computeNormal(p1, p2, p3) {
@@ -1,8 +1,8 @@
1
1
  import '../../Camera-CJVYy9fH.js';
2
2
  import '../../KeyboardControl-5w7Vm0J0.js';
3
- export { K as KeyboardInput } from '../../KeyboardInput-1xOAabI0.js';
3
+ export { K as KeyboardInput } from '../../KeyboardInput-RJ0mbuWM.js';
4
4
  import 'gl-matrix';
5
5
  import '../../Core/domain/interfaces/Vectors.js';
6
- import '../../Model-BBZHnUp1.js';
6
+ import '../../Model-efZcQkOK.js';
7
7
  import '../../WebGLCore-DR7ZHJB0.js';
8
- import '../../Material-DhwSRbP2.js';
8
+ import '../../Material-A-7kKes_.js';
@@ -1,7 +1,7 @@
1
- import { P as PhysicsBody } from '../KeyboardInput-1xOAabI0.js';
2
- export { A as AnimationController, a as AnimationState, b as AnimationTransition, C as Character, K as KeyboardInput, T as TransitionCondition } from '../KeyboardInput-1xOAabI0.js';
3
- import { g as Mesh, i as Model, S as Skeleton } from '../Model-BBZHnUp1.js';
4
- import { b as Material } from '../Material-DhwSRbP2.js';
1
+ import { P as PhysicsBody } from '../KeyboardInput-RJ0mbuWM.js';
2
+ export { A as AnimationController, a as AnimationState, b as AnimationTransition, C as Character, K as KeyboardInput, T as TransitionCondition } from '../KeyboardInput-RJ0mbuWM.js';
3
+ import { M as Mesh, i as Model, S as Skeleton } from '../Model-efZcQkOK.js';
4
+ import { b as Material } from '../Material-A-7kKes_.js';
5
5
  import { Vector3 } from '../Core/domain/interfaces/Vectors.js';
6
6
  import { W as WebGLCore } from '../WebGLCore-DR7ZHJB0.js';
7
7
  import { Scene } from '../Core/classes/Scene.js';
@@ -1,24 +1,24 @@
1
1
  import {
2
2
  KeyboardInput
3
3
  } from "../chunk-P7QOKDLY.js";
4
- import "../chunk-SUNYSY45.js";
4
+ import "../chunk-IOAANJZG.js";
5
5
  import {
6
6
  Mesh,
7
7
  Renderer,
8
8
  WebGLCore
9
- } from "../chunk-ZCJ3MJZD.js";
9
+ } from "../chunk-4M3XFPH3.js";
10
10
  import {
11
11
  Material
12
- } from "../chunk-L66K4AZU.js";
12
+ } from "../chunk-XCYJCLHB.js";
13
13
  import {
14
14
  Model
15
15
  } from "../chunk-QOAQVTAB.js";
16
16
  import {
17
17
  Scene
18
- } from "../chunk-3ULETMWF.js";
18
+ } from "../chunk-WKSDPPXS.js";
19
19
  import {
20
20
  Viewport
21
- } from "../chunk-XMW2MS66.js";
21
+ } from "../chunk-WHOIVV44.js";
22
22
 
23
23
  // src/Game/classes/AnimationController.ts
24
24
  var AnimationController = class {
@@ -1,6 +1,6 @@
1
1
  import { C as Camera } from './Camera-CJVYy9fH.js';
2
2
  import { K as KeyboardControl } from './KeyboardControl-5w7Vm0J0.js';
3
- import { a as AnimationClip, i as Model, g as Mesh, S as Skeleton } from './Model-BBZHnUp1.js';
3
+ import { a as AnimationClip, i as Model, M as Mesh, S as Skeleton } from './Model-efZcQkOK.js';
4
4
  import { Vector3 } from './Core/domain/interfaces/Vectors.js';
5
5
 
6
6
  /** A named state that maps to one animation clip. */
@@ -50,6 +50,8 @@ declare class Material {
50
50
  specular: Vector3;
51
51
  shininess: number;
52
52
  doubleSided: boolean;
53
+ /** When true, the renderer enables alpha blending for this mesh. */
54
+ transparent: boolean;
53
55
  ambientColor: Vector3;
54
56
  dissolve: number;
55
57
  diffuse: Vector3;
@@ -1,7 +1,7 @@
1
1
  import { vec3, quat, mat4 } from 'gl-matrix';
2
2
  import { Vector3 } from './Core/domain/interfaces/Vectors.js';
3
3
  import { W as WebGLCore } from './WebGLCore-DR7ZHJB0.js';
4
- import { b as Material } from './Material-DhwSRbP2.js';
4
+ import { b as Material } from './Material-A-7kKes_.js';
5
5
 
6
6
  interface AABB {
7
7
  min: Vector3;
@@ -315,4 +315,4 @@ declare class Model {
315
315
  update(deltaTime: number): void;
316
316
  }
317
317
 
318
- export { type AnimationChannel as A, GL_LINES as G, INITIAL_BOUNDING_BOX as I, type Joint as J, MAX_JOINTS as M, Skeleton as S, AnimationClip as a, type AnimationPath as b, type AnimationSampler as c, GL_TRIANGLES as d, type InterpolationMode as e, type JointPose as f, Mesh as g, MeshBuffers as h, Model as i };
318
+ export { type AnimationChannel as A, GL_LINES as G, INITIAL_BOUNDING_BOX as I, type Joint as J, Mesh as M, Skeleton as S, AnimationClip as a, type AnimationPath as b, type AnimationSampler as c, GL_TRIANGLES as d, type InterpolationMode as e, type JointPose as f, MAX_JOINTS as g, MeshBuffers as h, Model as i };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Material
3
- } from "./chunk-L66K4AZU.js";
3
+ } from "./chunk-XCYJCLHB.js";
4
4
 
5
5
  // src/Core/classes/Renderer.ts
6
6
  import { mat4 as mat42 } from "gl-matrix";
@@ -772,6 +772,8 @@ var Renderer = class {
772
772
  viewport;
773
773
  /** Set to `true` to render wireframe bounding boxes for debugging. */
774
774
  debug = false;
775
+ /** RGBA clear color used at the start of each frame. */
776
+ clearColor = [0.2, 0.5, 0.95, 1];
775
777
  // Cached debug materials to avoid per-frame GPU allocations
776
778
  _modelHitboxMaterial = null;
777
779
  _meshHitboxMaterial = null;
@@ -813,7 +815,9 @@ var Renderer = class {
813
815
  const lights = scene.getLights();
814
816
  const camera = this.viewport.camera;
815
817
  const viewPosition = camera.getComputedPosition();
816
- this.clearFrame();
818
+ this.clearFrame(this.clearColor);
819
+ gl.disable(gl.BLEND);
820
+ gl.depthMask(true);
817
821
  const viewMatrix = camera.getViewMatrix();
818
822
  const projMatrix = camera.getProjectionMatrix();
819
823
  let activeProgram = null;
@@ -909,6 +913,12 @@ var Renderer = class {
909
913
  gl.vertexAttribPointer(aJointWeights, 4, gl.FLOAT, false, 0, 0);
910
914
  }
911
915
  }
916
+ const isTransparent = mesh.material.transparent;
917
+ if (isTransparent) {
918
+ gl.enable(gl.BLEND);
919
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
920
+ gl.depthMask(false);
921
+ }
912
922
  mesh.material.apply(gl, lights, viewPosition);
913
923
  const uUseSkinning = uniformLocations["uUseSkinning"];
914
924
  const skeleton = skinnedModel?.skeleton ?? null;
@@ -930,6 +940,10 @@ var Renderer = class {
930
940
  } else {
931
941
  gl.drawArrays(mesh.mode, 0, mesh.vertices.length / 3);
932
942
  }
943
+ if (isTransparent) {
944
+ gl.disable(gl.BLEND);
945
+ gl.depthMask(true);
946
+ }
933
947
  if (isWebGL2 && mesh.buffers?.vao) {
934
948
  gl.bindVertexArray(null);
935
949
  } else {
@@ -1001,4 +1015,4 @@ export {
1001
1015
  Skeleton,
1002
1016
  AnimationClip
1003
1017
  };
1004
- //# sourceMappingURL=chunk-ZCJ3MJZD.js.map
1018
+ //# sourceMappingURL=chunk-4M3XFPH3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/Core/classes/Renderer.ts","../src/Core/utils/compute-bounds.ts","../src/Core/classes/Mesh.ts","../src/Core/shaders/index.ts","../src/Core/classes/WebGLCore.ts","../src/Core/classes/Skeleton.ts","../src/Core/classes/AnimationClip.ts","../src/Core/utils/create-wire-box.ts"],"sourcesContent":["import { mat4, vec3 } from 'gl-matrix';\nimport { Material, Mesh, Scene, WebGLCore } from '.';\nimport { Viewport } from './Viewport';\nimport { Light } from './Light';\nimport { Vector3 } from '../domain/interfaces/Vectors';\nimport { Model } from './Model';\nimport { Skeleton } from './Skeleton';\nimport { createWireBox } from '../utils/create-wire-box';\n\nexport class Renderer {\n /** Set to `true` to render wireframe bounding boxes for debugging. */\n public debug = false;\n\n /** RGBA clear color used at the start of each frame. */\n public clearColor: [number, number, number, number] = [0.2, 0.5, 0.95, 1];\n\n // Cached debug materials to avoid per-frame GPU allocations\n private _modelHitboxMaterial: Material | null = null;\n private _meshHitboxMaterial: Material | null = null;\n\n // Cache wire-box debug meshes: recreated only when the bounding box changes.\n private readonly _modelWireBoxCache = new WeakMap<Model, { mesh: Mesh; key: string }>();\n private readonly _meshWireBoxCache = new WeakMap<Mesh, { mesh: Mesh; key: string }>();\n\n /** Pre-allocated identity matrix for world-space hitbox draws. */\n private readonly _identity: mat4 = mat4.create();\n\n /** Cached `gl instanceof WebGL2RenderingContext` — computed once at construction. */\n private readonly _isWebGL2: boolean;\n\n constructor(\n private webglCore: WebGLCore,\n public viewport: Viewport,\n ) {\n const gl = webglCore.getRenderingContext();\n this._isWebGL2 = gl instanceof WebGL2RenderingContext;\n if (gl) gl.enable(gl.DEPTH_TEST);\n }\n\n /** Lazily-created material for model-level hitboxes (red). */\n private get modelHitboxMaterial(): Material {\n if (!this._modelHitboxMaterial) {\n this._modelHitboxMaterial = new Material(this.webglCore);\n this._modelHitboxMaterial.setColorHex('#ff0404ff');\n this._modelHitboxMaterial.unlit = true;\n }\n return this._modelHitboxMaterial;\n }\n\n /** Lazily-created material for mesh-level hitboxes (green). */\n private get meshHitboxMaterial(): Material {\n if (!this._meshHitboxMaterial) {\n this._meshHitboxMaterial = new Material(this.webglCore);\n this._meshHitboxMaterial.setColorHex('#04ff0cff');\n this._meshHitboxMaterial.unlit = true;\n }\n return this._meshHitboxMaterial;\n }\n\n public clearFrame(\n color: [number, number, number, number] = [0.2, 0.5, 0.95, 1],\n ) {\n const gl = this.webglCore.getRenderingContext();\n if (!gl) return;\n\n gl.clearColor(...color);\n gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n }\n\n public render(scene: Scene) {\n const gl = this.webglCore.getRenderingContext();\n if (!gl) return;\n\n const models = scene.getModels();\n const lights = scene.getLights();\n const camera = this.viewport.camera;\n\n const viewPosition: vec3 = camera.getComputedPosition();\n this.clearFrame(this.clearColor);\n\n // Ensure clean GL state at the start of every frame\n gl.disable(gl.BLEND);\n gl.depthMask(true);\n\n const viewMatrix = camera.getViewMatrix() as Float32Array;\n const projMatrix = camera.getProjectionMatrix() as Float32Array;\n\n let activeProgram: WebGLProgram | null = null;\n\n for (const model of models) {\n activeProgram = this.drawModel(\n gl,\n model,\n lights,\n viewPosition,\n viewMatrix,\n projMatrix,\n activeProgram,\n );\n }\n }\n\n private drawModel(\n gl: WebGLRenderingContext,\n model: Model,\n lights: Light[],\n viewPosition: vec3,\n viewMatrix: Float32Array,\n projMatrix: Float32Array,\n activeProgram: WebGLProgram | null,\n ): WebGLProgram | null {\n const modelMatrix = model.getModelMatrix();\n const hasSkeleton = model.skeleton !== null;\n\n for (const mesh of model.meshes) {\n activeProgram = this.drawMesh(\n mesh,\n lights,\n viewPosition,\n modelMatrix,\n viewMatrix,\n projMatrix,\n activeProgram,\n hasSkeleton && mesh.isSkinned ? model : null,\n );\n\n if (this.debug) {\n this.drawHitBoxForMesh(\n mesh,\n modelMatrix,\n viewMatrix,\n projMatrix,\n activeProgram,\n );\n }\n }\n\n // Debug wireframe\n if (this.debug) {\n this.drawHitBox(model, activeProgram);\n }\n\n return activeProgram;\n }\n\n private drawMesh(\n mesh: Mesh,\n lights: Light[],\n viewPosition: vec3,\n modelMatrix: mat4,\n viewMatrix: Float32Array,\n projMatrix: Float32Array,\n activeProgram: WebGLProgram | null,\n skinnedModel: Model | null = null,\n ): WebGLProgram | null {\n const gl = this.webglCore.getRenderingContext();\n if (!gl) return activeProgram;\n if (!mesh.material) return activeProgram;\n\n mesh.initBuffer(this.webglCore);\n\n const { program, uniformLocations } = mesh.material;\n\n if (program !== activeProgram) {\n gl.useProgram(program);\n activeProgram = program;\n\n if (uniformLocations['uView'])\n gl.uniformMatrix4fv(uniformLocations['uView'], false, viewMatrix);\n if (uniformLocations['uProjection'])\n gl.uniformMatrix4fv(uniformLocations['uProjection'], false, projMatrix);\n }\n\n // Use cached WebGL2 check\n const isWebGL2 = this._isWebGL2;\n\n // --- Bind VAO if available ---\n if (isWebGL2 && mesh.buffers?.vao) {\n (gl as unknown as WebGL2RenderingContext).bindVertexArray(\n mesh.buffers.vao,\n );\n } else {\n // --- WebGL1 Fallback ---\n const aPosition = mesh.material.attribLocations['aPosition'];\n if (aPosition !== -1 && mesh.buffers?.vertexBuffer) {\n gl.bindBuffer(gl.ARRAY_BUFFER, mesh.buffers.vertexBuffer);\n gl.enableVertexAttribArray(aPosition);\n gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, 0, 0);\n }\n\n const aNormal = mesh.material.attribLocations['aNormal'];\n if (aNormal !== -1 && mesh.buffers?.normalBuffer) {\n gl.bindBuffer(gl.ARRAY_BUFFER, mesh.buffers.normalBuffer);\n gl.enableVertexAttribArray(aNormal);\n gl.vertexAttribPointer(aNormal, 3, gl.FLOAT, false, 0, 0);\n }\n\n const aTexCoord = mesh.material.attribLocations['aTexCoord'];\n if (aTexCoord !== -1 && mesh.buffers?.texCoordBuffer) {\n gl.bindBuffer(gl.ARRAY_BUFFER, mesh.buffers.texCoordBuffer);\n gl.enableVertexAttribArray(aTexCoord);\n gl.vertexAttribPointer(aTexCoord, 2, gl.FLOAT, false, 0, 0);\n }\n\n // Skinning attributes (joint indices + weights)\n const aJointIndices = mesh.material.attribLocations['aJointIndices'];\n if (aJointIndices !== -1 && mesh.buffers?.jointIndexBuffer) {\n gl.bindBuffer(gl.ARRAY_BUFFER, mesh.buffers.jointIndexBuffer);\n gl.enableVertexAttribArray(aJointIndices);\n gl.vertexAttribPointer(aJointIndices, 4, gl.FLOAT, false, 0, 0);\n }\n\n const aJointWeights = mesh.material.attribLocations['aJointWeights'];\n if (aJointWeights !== -1 && mesh.buffers?.jointWeightBuffer) {\n gl.bindBuffer(gl.ARRAY_BUFFER, mesh.buffers.jointWeightBuffer);\n gl.enableVertexAttribArray(aJointWeights);\n gl.vertexAttribPointer(aJointWeights, 4, gl.FLOAT, false, 0, 0);\n }\n }\n\n // Alpha blending for transparent materials\n const isTransparent = mesh.material.transparent;\n if (isTransparent) {\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n gl.depthMask(false);\n }\n\n // Material uniforms\n mesh.material.apply(gl, lights, viewPosition as Vector3);\n\n // ── Skinning uniforms ─────────────────────────────────────\n const uUseSkinning = uniformLocations['uUseSkinning'];\n const skeleton: Skeleton | null =\n (skinnedModel?.skeleton as Skeleton | undefined) ?? null;\n if (skeleton && mesh.isSkinned) {\n if (uUseSkinning) gl.uniform1i(uUseSkinning, 1);\n const uJointMatrices = uniformLocations['uJointMatrices[0]'];\n if (uJointMatrices) {\n gl.uniformMatrix4fv(uJointMatrices, false, skeleton.jointMatrices);\n }\n } else {\n if (uUseSkinning) gl.uniform1i(uUseSkinning, 0);\n }\n\n // Model transform\n const uModel = mesh.material.uniformLocations['uModel'];\n if (uModel) gl.uniformMatrix4fv(uModel, false, modelMatrix as Float32Array);\n\n // Draw\n if (mesh.buffers?.indexBuffer && mesh.indices) {\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh.buffers.indexBuffer);\n const type =\n mesh.indices instanceof Uint32Array\n ? gl.UNSIGNED_INT\n : gl.UNSIGNED_SHORT;\n gl.drawElements(mesh.mode, mesh.indices.length, type, 0);\n } else {\n gl.drawArrays(mesh.mode, 0, mesh.vertices.length / 3);\n }\n\n // Restore blending state\n if (isTransparent) {\n gl.disable(gl.BLEND);\n gl.depthMask(true);\n }\n\n // Cleanup\n if (isWebGL2 && mesh.buffers?.vao) {\n (gl as unknown as WebGL2RenderingContext).bindVertexArray(null);\n } else {\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);\n }\n\n return activeProgram;\n }\n\n public drawHitBox(\n model: Model,\n activeProgram: WebGLProgram | null,\n ) {\n const bbox = model.boundingBox;\n const key = `${bbox.min[0]},${bbox.min[1]},${bbox.min[2]},${bbox.max[0]},${bbox.max[1]},${bbox.max[2]}`;\n const cached = this._modelWireBoxCache.get(model);\n let hitboxMesh: Mesh;\n if (!cached || cached.key !== key) {\n hitboxMesh = createWireBox(bbox.min, bbox.max, this.modelHitboxMaterial);\n hitboxMesh.isCollidable = false;\n this._modelWireBoxCache.set(model, { mesh: hitboxMesh, key });\n } else {\n hitboxMesh = cached.mesh;\n }\n\n const camera = this.viewport.camera;\n const viewMatrix = camera.getViewMatrix() as Float32Array;\n const projMatrix = camera.getProjectionMatrix() as Float32Array;\n\n this.drawMesh(\n hitboxMesh,\n [],\n camera.position,\n this._identity,\n viewMatrix,\n projMatrix,\n activeProgram,\n );\n }\n\n private drawHitBoxForMesh(\n mesh: Mesh,\n modelMatrix: mat4,\n viewMatrix: Float32Array,\n projMatrix: Float32Array,\n activeProgram: WebGLProgram | null,\n ) {\n if (!mesh.boundingBox) return;\n\n const { min, max } = mesh.boundingBox;\n const key = `${min[0]},${min[1]},${min[2]},${max[0]},${max[1]},${max[2]}`;\n const cached = this._meshWireBoxCache.get(mesh);\n let wireBox: Mesh;\n if (!cached || cached.key !== key) {\n wireBox = createWireBox(min, max, this.meshHitboxMaterial);\n wireBox.isCollidable = false;\n this._meshWireBoxCache.set(mesh, { mesh: wireBox, key });\n } else {\n wireBox = cached.mesh;\n }\n\n const camera = this.viewport.camera;\n this.drawMesh(\n wireBox,\n [],\n camera.position,\n modelMatrix,\n viewMatrix,\n projMatrix,\n activeProgram,\n );\n }\n}\n","import { AABB } from '../domain/value-objects/Collider';\n\n/**\n * Compute the axis-aligned bounding box (AABB) from a flat Float32Array of vertices.\n * Each vertex is expected to be 3 consecutive floats: [x, y, z, ...].\n */\nexport function computeVertexBounds(vertices: Float32Array): AABB {\n if (!vertices || vertices.length === 0) {\n return { min: [0, 0, 0], max: [0, 0, 0] };\n }\n\n let minX = Infinity,\n minY = Infinity,\n minZ = Infinity;\n let maxX = -Infinity,\n maxY = -Infinity,\n maxZ = -Infinity;\n\n for (let i = 0; i < vertices.length; i += 3) {\n const x = vertices[i];\n const y = vertices[i + 1];\n const z = vertices[i + 2];\n\n if (x < minX) minX = x;\n if (y < minY) minY = y;\n if (z < minZ) minZ = z;\n\n if (x > maxX) maxX = x;\n if (y > maxY) maxY = y;\n if (z > maxZ) maxZ = z;\n }\n\n return {\n min: [minX, minY, minZ],\n max: [maxX, maxY, maxZ],\n };\n}\n","import WebGLCore from './WebGLCore';\nimport { Material } from './Material';\nimport { AABB } from '../domain/value-objects/Collider';\nimport { computeVertexBounds } from '../utils/compute-bounds';\n\n/** WebGL draw-mode constants. */\nexport const GL_LINES = 0x0001;\nexport const GL_TRIANGLES = 0x0004;\n\nexport const INITIAL_BOUNDING_BOX: AABB = { min: [0, 0, 0], max: [0, 0, 0] };\n\n/**\n * A single renderable mesh: vertex data, normals, indices, a material, and an\n * optional bounding box used for collision detection.\n *\n * For skinned meshes, set {@link jointIndices} and {@link jointWeights} to\n * enable GPU skeletal animation.\n */\nexport class Mesh {\n name: string;\n\n vertices: Float32Array;\n\n normals: Float32Array;\n\n texCoords: Float32Array;\n\n indices: Uint16Array | Uint32Array | null;\n\n mode: number;\n\n material: Material;\n\n // ── Skinning data (optional) ─────────────────────────────────\n /** Per-vertex joint indices (vec4 per vertex, 4 influences). */\n jointIndices: Float32Array | null = null;\n\n /** Per-vertex joint weights (vec4 per vertex, 4 influences). */\n jointWeights: Float32Array | null = null;\n\n // WebGL buffers aggregate\n buffers: MeshBuffers | null = null;\n\n boundingBox: AABB = INITIAL_BOUNDING_BOX;\n\n isCollidable = true;\n\n isInitialized = false;\n\n constructor(\n name: string,\n vertices: Float32Array,\n normals: Float32Array,\n material: Material,\n texCoords: Float32Array = new Float32Array(),\n indices: Uint16Array | Uint32Array | null = null,\n ) {\n this.mode = GL_TRIANGLES;\n this.name = name;\n this.normals = normals;\n this.indices = indices;\n this.vertices = vertices;\n this.texCoords = texCoords;\n this.material = material;\n\n this.computeBounds();\n }\n\n setMode(newMode: number) {\n this.mode = newMode;\n }\n\n /** Whether this mesh has skinning data for skeletal animation. */\n get isSkinned(): boolean {\n return this.jointIndices !== null && this.jointWeights !== null;\n }\n\n computeBounds() {\n this.boundingBox = computeVertexBounds(this.vertices);\n }\n\n clone(): Mesh {\n const clonedMesh = new Mesh(\n this.name,\n new Float32Array(this.vertices),\n new Float32Array(this.normals),\n this.material, // shallow ref — call Material.clone() if independent material is needed\n new Float32Array(this.texCoords),\n this.indices\n ? this.indices instanceof Uint16Array\n ? new Uint16Array(this.indices)\n : new Uint32Array(this.indices)\n : null,\n );\n clonedMesh.setMode(this.mode);\n clonedMesh.isCollidable = this.isCollidable;\n if (this.jointIndices)\n clonedMesh.jointIndices = new Float32Array(this.jointIndices);\n if (this.jointWeights)\n clonedMesh.jointWeights = new Float32Array(this.jointWeights);\n return clonedMesh;\n }\n\n /** Initialize GPU buffers safely */\n public initBuffer(webglCore: WebGLCore) {\n const gl = webglCore.getRenderingContext();\n\n if (!gl) {\n console.warn(\n `[Mesh:${this.name}] GL context not available, skipping buffer init.`,\n );\n return;\n }\n if (this.isInitialized) return;\n\n this.buffers = new MeshBuffers();\n this.buffers.init(gl as WebGL2RenderingContext, this);\n this.isInitialized = true;\n }\n\n /** Dispose of GPU buffers safely */\n public dispose(webglCore: WebGLCore) {\n const gl = webglCore.getRenderingContext();\n if (!gl || !this.buffers) return;\n\n this.buffers.dispose(gl as WebGL2RenderingContext);\n this.buffers = null;\n this.isInitialized = false;\n }\n}\n\nexport class MeshBuffers {\n vao: WebGLVertexArrayObject | null = null;\n vertexBuffer: WebGLBuffer | null = null;\n normalBuffer: WebGLBuffer | null = null;\n texCoordBuffer: WebGLBuffer | null = null;\n indexBuffer: WebGLBuffer | null = null;\n jointIndexBuffer: WebGLBuffer | null = null;\n jointWeightBuffer: WebGLBuffer | null = null;\n\n public init(gl: WebGLRenderingContext, mesh: Mesh) {\n if (!gl) throw new Error('Cannot init MeshBuffers: invalid GL context');\n\n const isWebGL2 = gl instanceof WebGL2RenderingContext;\n const gl2 = isWebGL2 ? (gl as unknown as WebGL2RenderingContext) : null;\n\n if (gl2) {\n this.vao = gl2.createVertexArray();\n gl2.bindVertexArray(this.vao);\n }\n\n // --- Attribute layout ---\n // Attribute locations must match the shader (aPosition=0, aNormal=1, aTexCoord=2).\n // Look them up from the mesh's material program so the VAO captures the bindings.\n const program = mesh.material?.program;\n const aPosition = program ? gl.getAttribLocation(program, 'aPosition') : 0;\n const aNormal = program ? gl.getAttribLocation(program, 'aNormal') : 1;\n const aTexCoord = program ? gl.getAttribLocation(program, 'aTexCoord') : 2;\n\n // Vertex buffer\n this.vertexBuffer = gl.createBuffer();\n if (!this.vertexBuffer) throw new Error('Failed to create vertex buffer');\n gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);\n gl.bufferData(gl.ARRAY_BUFFER, mesh.vertices, gl.STATIC_DRAW);\n if (aPosition !== -1) {\n gl.enableVertexAttribArray(aPosition);\n gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, 0, 0);\n }\n\n // Normal buffer\n this.normalBuffer = gl.createBuffer();\n if (!this.normalBuffer) throw new Error('Failed to create normal buffer');\n gl.bindBuffer(gl.ARRAY_BUFFER, this.normalBuffer);\n gl.bufferData(gl.ARRAY_BUFFER, mesh.normals, gl.STATIC_DRAW);\n if (aNormal !== -1) {\n gl.enableVertexAttribArray(aNormal);\n gl.vertexAttribPointer(aNormal, 3, gl.FLOAT, false, 0, 0);\n }\n\n // TexCoord buffer\n if (mesh.texCoords.length > 0) {\n this.texCoordBuffer = gl.createBuffer();\n if (!this.texCoordBuffer)\n throw new Error('Failed to create texCoord buffer');\n gl.bindBuffer(gl.ARRAY_BUFFER, this.texCoordBuffer);\n gl.bufferData(gl.ARRAY_BUFFER, mesh.texCoords, gl.STATIC_DRAW);\n if (aTexCoord !== -1) {\n gl.enableVertexAttribArray(aTexCoord);\n gl.vertexAttribPointer(aTexCoord, 2, gl.FLOAT, false, 0, 0);\n }\n }\n\n // Index buffer\n if (mesh.indices && mesh.indices.length > 0) {\n this.indexBuffer = gl.createBuffer();\n if (!this.indexBuffer) throw new Error('Failed to create index buffer');\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, mesh.indices, gl.STATIC_DRAW);\n }\n\n // Joint indices buffer (skinning)\n const aJointIndices = program\n ? gl.getAttribLocation(program, 'aJointIndices')\n : -1;\n if (\n mesh.jointIndices &&\n mesh.jointIndices.length > 0 &&\n aJointIndices !== -1\n ) {\n this.jointIndexBuffer = gl.createBuffer();\n if (!this.jointIndexBuffer)\n throw new Error('Failed to create joint index buffer');\n gl.bindBuffer(gl.ARRAY_BUFFER, this.jointIndexBuffer);\n gl.bufferData(gl.ARRAY_BUFFER, mesh.jointIndices, gl.STATIC_DRAW);\n gl.enableVertexAttribArray(aJointIndices);\n gl.vertexAttribPointer(aJointIndices, 4, gl.FLOAT, false, 0, 0);\n }\n\n // Joint weights buffer (skinning)\n const aJointWeights = program\n ? gl.getAttribLocation(program, 'aJointWeights')\n : -1;\n if (\n mesh.jointWeights &&\n mesh.jointWeights.length > 0 &&\n aJointWeights !== -1\n ) {\n this.jointWeightBuffer = gl.createBuffer();\n if (!this.jointWeightBuffer)\n throw new Error('Failed to create joint weight buffer');\n gl.bindBuffer(gl.ARRAY_BUFFER, this.jointWeightBuffer);\n gl.bufferData(gl.ARRAY_BUFFER, mesh.jointWeights, gl.STATIC_DRAW);\n gl.enableVertexAttribArray(aJointWeights);\n gl.vertexAttribPointer(aJointWeights, 4, gl.FLOAT, false, 0, 0);\n }\n\n if (gl2) {\n gl2.bindVertexArray(null);\n }\n }\n\n public dispose(gl: WebGL2RenderingContext) {\n if (!gl) {\n console.warn('Cannot dispose MeshBuffers: invalid GL context');\n return;\n }\n\n const isWebGL2 = gl instanceof WebGL2RenderingContext;\n\n if (this.vertexBuffer) gl.deleteBuffer(this.vertexBuffer);\n if (this.normalBuffer) gl.deleteBuffer(this.normalBuffer);\n if (this.texCoordBuffer) gl.deleteBuffer(this.texCoordBuffer);\n if (this.indexBuffer) gl.deleteBuffer(this.indexBuffer);\n if (this.jointIndexBuffer) gl.deleteBuffer(this.jointIndexBuffer);\n if (this.jointWeightBuffer) gl.deleteBuffer(this.jointWeightBuffer);\n\n if (isWebGL2 && this.vao) {\n (gl as unknown as WebGL2RenderingContext).deleteVertexArray(this.vao);\n }\n\n this.vertexBuffer =\n this.normalBuffer =\n this.texCoordBuffer =\n this.indexBuffer =\n this.jointIndexBuffer =\n this.jointWeightBuffer =\n this.vao =\n null;\n }\n}\n","// GLSL shader sources inlined as TypeScript strings so the package can\n// be built with tsup without requiring Vite's ?raw loader.\n\nexport const vsSource = /* glsl */ `\n#define MAX_JOINTS 128\n\nattribute vec3 aPosition;\nattribute vec3 aNormal;\nattribute vec2 aTexCoord;\n\n// ── Skinning attributes (vec4: up to 4 joint influences per vertex) ──\nattribute vec4 aJointIndices;\nattribute vec4 aJointWeights;\n\nuniform mat4 uModel;\nuniform mat4 uView;\nuniform mat4 uProjection;\n\n// ── Skinning uniforms ──\nuniform bool uUseSkinning;\nuniform mat4 uJointMatrices[MAX_JOINTS];\n\nvarying vec3 vNormal;\nvarying vec3 vPosition;\nvarying vec2 vTexCoord;\n\nvoid main() {\n vTexCoord = aTexCoord;\n\n vec4 pos = vec4(aPosition, 1.0);\n vec3 norm = aNormal;\n\n if (uUseSkinning) {\n mat4 skinMat =\n aJointWeights.x * uJointMatrices[int(aJointIndices.x)] +\n aJointWeights.y * uJointMatrices[int(aJointIndices.y)] +\n aJointWeights.z * uJointMatrices[int(aJointIndices.z)] +\n aJointWeights.w * uJointMatrices[int(aJointIndices.w)];\n pos = skinMat * pos;\n norm = mat3(skinMat) * norm;\n }\n\n vNormal = mat3(uModel) * norm;\n\n vec4 worldPosition = uModel * pos;\n vPosition = worldPosition.xyz;\n gl_Position = uProjection * uView * worldPosition;\n}\n`;\n\nexport const fsSource = /* glsl */ `\nprecision mediump float;\n\n#define MAX_LIGHTS 5\n\nvarying vec3 vNormal;\nvarying vec3 vPosition;\nvarying vec2 vTexCoord;\n\nuniform vec3 uLightDirection[MAX_LIGHTS];\nuniform vec3 uLightColor[MAX_LIGHTS];\nuniform float uLightIntensity[MAX_LIGHTS];\nuniform int uLightType[MAX_LIGHTS]; // 0=directional, 1=point, 2=ambient\nuniform int uLightCount;\nuniform vec3 uLightPosition[MAX_LIGHTS];\nuniform float uLightConstant[MAX_LIGHTS];\nuniform float uLightLinear[MAX_LIGHTS];\nuniform float uLightQuadratic[MAX_LIGHTS];\n\nuniform vec4 uColor;\nuniform bool uUnlit;\nuniform bool uUseTexture;\nuniform sampler2D uTexture;\n\nuniform vec3 uViewPosition;\nuniform float uShininess;\nuniform vec3 uSpecularColor;\n\nvoid main() {\n vec4 baseColor = uColor;\n if (uUseTexture) {\n baseColor *= texture2D(uTexture, vTexCoord);\n }\n\n if (uUnlit) {\n gl_FragColor = baseColor;\n return;\n }\n\n vec3 norm = normalize(vNormal);\n vec3 totalDiffuse = vec3(0.0);\n vec3 totalAmbient = vec3(0.0);\n vec3 totalSpecular = vec3(0.0);\n\n vec3 viewDir = normalize(uViewPosition - vPosition);\n\n for (int i = 0; i < MAX_LIGHTS; i++) {\n if (i >= uLightCount) break;\n\n if (uLightType[i] == 2) {\n totalAmbient += uLightColor[i] * uLightIntensity[i];\n } else {\n vec3 lightDir;\n float attenuation = 1.0;\n\n if (uLightType[i] == 0) {\n // Directional light\n lightDir = normalize(-uLightDirection[i]);\n } else {\n // Point light\n vec3 lightVec = uLightPosition[i] - vPosition;\n float distance = length(lightVec);\n lightDir = normalize(lightVec);\n attenuation = 1.0 / (\n uLightConstant[i] +\n uLightLinear[i] * distance +\n uLightQuadratic[i] * distance * distance\n );\n }\n\n // Diffuse\n float diff = max(dot(norm, lightDir), 0.0);\n totalDiffuse += diff * uLightColor[i] * uLightIntensity[i] * attenuation;\n\n // Specular (Blinn-Phong) — softer, more natural highlights\n vec3 halfDir = normalize(lightDir + viewDir);\n float spec = pow(max(dot(norm, halfDir), 0.0), uShininess);\n totalSpecular += spec * uSpecularColor * uLightIntensity[i] * attenuation;\n }\n }\n\n vec3 lightingResult =\n totalAmbient * baseColor.rgb +\n totalDiffuse * baseColor.rgb +\n totalSpecular;\n\n gl_FragColor = vec4(lightingResult, baseColor.a);\n}\n`;\n","/* eslint-disable @typescript-eslint/no-unsafe-argument */\nimport { vsSource, fsSource } from '../shaders/index';\n\nexport type RenderCallback = (\n gl: WebGLRenderingContext,\n program: WebGLProgram,\n) => void;\n\nexport class WebGLCore {\n public gl: WebGL2RenderingContext | WebGLRenderingContext;\n public program: WebGLProgram;\n public canvas: HTMLCanvasElement;\n public isWebGL2: boolean;\n\n /**\n * Initialise the WebGL rendering core.\n *\n * @param canvasOrId - An `HTMLCanvasElement` or the DOM `id` of one.\n * Defaults to `'glcanvas'`.\n */\n constructor(canvasOrId: string | HTMLCanvasElement = 'glcanvas') {\n const canvas =\n typeof canvasOrId === 'string'\n ? (document.getElementById(canvasOrId) as HTMLCanvasElement | null)\n : canvasOrId;\n if (!canvas) throw new Error('Canvas not found');\n this.canvas = canvas;\n\n canvas.width = window.innerWidth;\n canvas.height = window.innerHeight;\n\n this.gl = (canvas.getContext('webgl2') ?? canvas.getContext('webgl')) as\n | WebGL2RenderingContext\n | WebGLRenderingContext;\n\n if (!this.gl) throw new Error('WebGL not supported in this browser!');\n\n this.isWebGL2 = this.gl instanceof WebGL2RenderingContext;\n this.gl.viewport(0, 0, canvas.width, canvas.height);\n\n const program = this.createProgram(this.gl);\n if (!program) throw new Error('Failed to create program');\n this.program = program as unknown as WebGLProgram;\n }\n\n public getProgram(): WebGLProgram {\n return this.program;\n }\n\n public getRenderingContext(): WebGLRenderingContext {\n return this.gl;\n }\n\n private createProgram(gl: WebGLRenderingContext): WebGLProgram | null {\n const vertexShader = this.compileShader(gl, gl.VERTEX_SHADER, vsSource);\n const fragmentShader = this.compileShader(gl, gl.FRAGMENT_SHADER, fsSource);\n\n if (!vertexShader || !fragmentShader)\n throw new Error('Failed to create shaders');\n\n const program = gl.createProgram();\n if (!program) return null;\n\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n\n // Clean up shader objects\n gl.deleteShader(vertexShader);\n gl.deleteShader(fragmentShader);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n console.error(gl.getProgramInfoLog(program));\n throw new Error(gl.getProgramInfoLog(program) || 'Program link error');\n }\n\n return program;\n }\n\n private compileShader(\n gl: WebGLRenderingContext,\n type: number,\n source: string,\n ): WebGLShader | null {\n const shader = gl.createShader(type);\n if (!shader) return null;\n\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n console.error(gl.getShaderInfoLog(shader));\n gl.deleteShader(shader);\n throw new Error(gl.getShaderInfoLog(shader) || 'Shader compile error');\n }\n return shader;\n }\n\n public resize(width: number, height: number) {\n this.canvas.width = width;\n this.canvas.height = height;\n this.gl.viewport(0, 0, width, height);\n }\n\n dispose() {\n const { gl, program } = this;\n if (program) gl.deleteProgram(program);\n }\n}\n\nexport default WebGLCore;\n","import { mat4, quat, vec3 } from 'gl-matrix';\n\n/** Maximum number of joints supported per skeleton (must match shader). */\nexport const MAX_JOINTS = 128;\n\n/**\n * Describes a single joint (bone) inside a {@link Skeleton}.\n *\n * Each joint stores its default bind-pose transform (translation, rotation,\n * scale) and the inverse bind matrix used to transform vertices from model\n * space into joint-local space.\n */\nexport interface Joint {\n /** Human-readable name (e.g. \"Hips\", \"LeftArm\"). */\n name: string;\n /** Original glTF node index this joint references. */\n nodeIndex: number;\n /** Index of the parent joint in the skeleton's joint array (-1 = root). */\n parentIndex: number;\n /** Bind-pose translation. */\n localTranslation: vec3;\n /** Bind-pose rotation (quaternion). */\n localRotation: quat;\n /** Bind-pose scale. */\n localScale: vec3;\n /** Inverse bind matrix from the glTF skin. */\n inverseBindMatrix: mat4;\n}\n\n/**\n * Per-joint local transform produced by animation sampling.\n * Any undefined component falls back to the bind-pose value.\n */\nexport interface JointPose {\n t?: vec3;\n r?: quat;\n s?: vec3;\n}\n\n/**\n * A skeleton representing a hierarchy of {@link Joint}s.\n *\n * Call {@link computeJointMatrices} each frame with the current animation pose\n * to produce a flat `Float32Array` of `mat4`s ready for upload as a shader\n * uniform.\n */\nexport class Skeleton {\n /** Ordered joint list (parent always precedes child). */\n public readonly joints: Joint[];\n\n /**\n * Flat `Float32Array` of `joints.length` column-major `mat4` values.\n * Updated by {@link computeJointMatrices} — upload directly to\n * `uJointMatrices[0]`.\n */\n public readonly jointMatrices: Float32Array;\n\n /**\n * Global transform of the non-joint ancestor nodes above the skeleton\n * root. In many exported models the armature sits under a scene-root\n * node that carries scale / rotation (e.g. cm → m conversion). This\n * transform is pre-multiplied into root-joint globals so that\n * `global * inverseBindMatrix` evaluates to identity in the bind pose.\n */\n public readonly rootTransform: mat4;\n\n // ── Pre-allocated scratch buffers ──\n /** Per-joint global transform matrices, reused each frame (allocated once in constructor). */\n private readonly _globals: mat4[];\n private readonly _local: mat4 = mat4.create();\n private readonly _final: mat4 = mat4.create();\n\n constructor(joints: Joint[], rootTransform?: mat4) {\n if (joints.length > MAX_JOINTS) {\n console.warn(\n `[Skeleton] ${joints.length} joints exceeds MAX_JOINTS (${MAX_JOINTS}). ` +\n 'Extra joints will be ignored by the shader.',\n );\n }\n this.joints = joints;\n this.jointMatrices = new Float32Array(joints.length * 16);\n this.rootTransform = rootTransform ?? mat4.create();\n // Pre-allocate per-joint globals and scratch matrices — reused every frame.\n this._globals = Array.from({ length: joints.length }, () => mat4.create());\n }\n\n /** Number of joints in the skeleton. */\n get jointCount(): number {\n return this.joints.length;\n }\n\n /**\n * Walk the joint hierarchy, composing global transforms, then multiply by\n * each joint's inverse-bind matrix. The result is stored in\n * {@link jointMatrices} ready for shader upload.\n *\n * @param animatedPoses - Optional per-joint local transforms from an\n * {@link AnimationClip}. Map keys are **joint array indices** (not glTF\n * node indices).\n */\n computeJointMatrices(animatedPoses?: Map<number, JointPose>): void {\n const local = this._local;\n const final = this._final;\n const globals = this._globals;\n\n for (let i = 0; i < this.joints.length; i++) {\n const joint = this.joints[i];\n const pose = animatedPoses?.get(i);\n\n const t = pose?.t ?? joint.localTranslation;\n const r = pose?.r ?? joint.localRotation;\n const s = pose?.s ?? joint.localScale;\n\n mat4.fromRotationTranslationScale(local, r, t, s);\n\n if (joint.parentIndex >= 0) {\n mat4.multiply(globals[i], globals[joint.parentIndex], local);\n } else {\n // Root joint — include the non-joint ancestor transform\n mat4.multiply(globals[i], this.rootTransform, local);\n }\n\n // final = global * inverseBindMatrix\n mat4.multiply(final, globals[i], joint.inverseBindMatrix);\n this.jointMatrices.set(final as unknown as Float32Array, i * 16);\n }\n }\n\n /**\n * Create a deep clone of this skeleton (useful when instancing models).\n */\n clone(): Skeleton {\n const clonedJoints: Joint[] = this.joints.map((j) => ({\n name: j.name,\n nodeIndex: j.nodeIndex,\n parentIndex: j.parentIndex,\n localTranslation: vec3.clone(j.localTranslation),\n localRotation: quat.clone(j.localRotation),\n localScale: vec3.clone(j.localScale),\n inverseBindMatrix: mat4.clone(j.inverseBindMatrix),\n }));\n return new Skeleton(clonedJoints, mat4.clone(this.rootTransform));\n }\n}\n","import { quat, vec3 } from 'gl-matrix';\nimport type { JointPose } from './Skeleton';\n\n// ── Module-level scratch buffers ──\n// Reused across all AnimationClip.sample() calls. Safe because sample() is\n// synchronous and scratch values are copied into pose storage before reuse.\nconst _sv0Vec3 = vec3.create();\nconst _sv1Vec3 = vec3.create();\nconst _sOutVec3 = vec3.create();\nconst _sv0Quat = quat.create();\nconst _sv1Quat = quat.create();\nconst _sOutQuat = quat.create();\n\n// ─── Types ──────────────────────────────────────────────────────\n\n/** Interpolation mode as defined by glTF 2.0. */\nexport type InterpolationMode = 'STEP' | 'LINEAR' | 'CUBICSPLINE';\n\n/** Which transform component the channel drives. */\nexport type AnimationPath = 'translation' | 'rotation' | 'scale';\n\n/**\n * Stores the raw keyframe data for one animated property and performs\n * interpolation between keyframes.\n */\nexport interface AnimationSampler {\n /** Keyframe timestamps (seconds). */\n times: Float32Array;\n /** Flattened keyframe output values (3 or 4 components per key). */\n values: Float32Array;\n /** Interpolation mode (default `LINEAR`). */\n interpolation: InterpolationMode;\n}\n\n/**\n * Links a {@link AnimationSampler} to a specific joint property.\n */\nexport interface AnimationChannel {\n /** Index into the owning {@link Skeleton}'s joint array. */\n jointIndex: number;\n /** Transform component this channel drives. */\n path: AnimationPath;\n /** The sampler that holds keyframe data. */\n sampler: AnimationSampler;\n}\n\n// ─── AnimationClip ──────────────────────────────────────────────\n\n/**\n * A named animation clip containing one or more {@link AnimationChannel}s.\n *\n * Call {@link update} each frame to advance the playhead, then {@link sample}\n * to obtain per-joint local transforms that feed into\n * `Skeleton.computeJointMatrices()`.\n *\n * ```ts\n * clip.play();\n * // game loop:\n * clip.update(deltaTime);\n * const poses = clip.sample();\n * skeleton.computeJointMatrices(poses);\n * ```\n */\nexport class AnimationClip {\n /** Human-readable name (e.g. \"Walk\", \"Idle\"). */\n public readonly name: string;\n\n /** All channels in this clip. */\n public readonly channels: AnimationChannel[];\n\n /** Total duration in seconds (derived from the maximum keyframe time). */\n public readonly duration: number;\n\n /** Current playback time in seconds. */\n public currentTime = 0;\n\n /** Whether the clip loops when it reaches the end. */\n public loop = true;\n\n /** Playback speed multiplier (1 = normal, 2 = double, −1 = reverse). */\n public speed = 1;\n\n /** Whether the clip is currently advancing. */\n public playing = false;\n\n /**\n * Per-joint pose objects reused across frames to avoid per-frame allocations.\n * The vec3/quat inside each entry are also pre-allocated on first use.\n */\n private readonly _posePool = new Map<number, JointPose>();\n\n constructor(name: string, channels: AnimationChannel[], duration: number) {\n this.name = name;\n this.channels = channels;\n this.duration = duration;\n }\n\n /** Start / resume playback. */\n play(): void {\n this.playing = true;\n }\n\n /** Pause playback (keeps current time). */\n pause(): void {\n this.playing = false;\n }\n\n /** Stop and rewind to the beginning. */\n stop(): void {\n this.playing = false;\n this.currentTime = 0;\n }\n\n /** Rewind to the beginning without changing play state. */\n reset(): void {\n this.currentTime = 0;\n }\n\n /**\n * Advance the playhead by `deltaTime` seconds (respects {@link speed}).\n * Automatically loops or clamps depending on {@link loop}.\n */\n update(deltaTime: number): void {\n if (!this.playing || this.duration <= 0) return;\n\n this.currentTime += deltaTime * this.speed;\n\n if (this.loop) {\n this.currentTime =\n ((this.currentTime % this.duration) + this.duration) % this.duration;\n } else {\n if (this.currentTime >= this.duration) {\n this.currentTime = this.duration;\n this.playing = false;\n } else if (this.currentTime < 0) {\n this.currentTime = 0;\n this.playing = false;\n }\n }\n }\n\n /**\n * Sample every channel at the current playhead and write per-joint local\n * transforms into `out` (or a newly created map if none is provided).\n *\n * Pass a persistent `Map` to avoid allocating a new one every frame.\n */\n sample(out?: Map<number, JointPose>): Map<number, JointPose> {\n const result = out ?? new Map<number, JointPose>();\n if (out) out.clear();\n\n for (const channel of this.channels) {\n // Reuse the JointPose object for this joint from the pool.\n let entry = this._posePool.get(channel.jointIndex);\n if (!entry) {\n entry = {};\n this._posePool.set(channel.jointIndex, entry);\n }\n result.set(channel.jointIndex, entry);\n\n // sampleChannel writes into a module-level scratch buffer.\n // Copy the result into the pre-allocated fields of the pose entry.\n const value = sampleChannel(channel, this.currentTime);\n switch (channel.path) {\n case 'translation':\n if (!entry.t) entry.t = vec3.create();\n vec3.copy(entry.t, value as vec3);\n break;\n case 'rotation':\n if (!entry.r) entry.r = quat.create();\n quat.copy(entry.r, value as quat);\n break;\n case 'scale':\n if (!entry.s) entry.s = vec3.create();\n vec3.copy(entry.s, value as vec3);\n break;\n }\n }\n\n return result;\n }\n\n /**\n * Create an independent copy of this clip (shares the underlying sampler\n * data but has its own playback state).\n */\n clone(): AnimationClip {\n const copy = new AnimationClip(this.name, this.channels, this.duration);\n copy.loop = this.loop;\n copy.speed = this.speed;\n return copy;\n }\n}\n\n// ── Sampling helpers ───────────────────────────────────────────────\n\n/** Write `numComponents` floats from `values` at `index * numComponents` into `out`. */\nfunction readValueInto(\n values: Float32Array,\n index: number,\n numComponents: number,\n out: vec3 | quat,\n): void {\n const off = index * numComponents;\n out[0] = values[off];\n out[1] = values[off + 1];\n out[2] = values[off + 2];\n if (numComponents === 4) out[3] = values[off + 3];\n}\n\n/**\n * Sample a single channel at the given time. Writes the result into a\n * module-level scratch buffer and returns a reference to it.\n * The caller must copy the value before the next sampleChannel invocation.\n */\nfunction sampleChannel(channel: AnimationChannel, time: number): vec3 | quat {\n const { sampler, path } = channel;\n const { times, values, interpolation } = sampler;\n const numComponents = path === 'rotation' ? 4 : 3;\n const outScratch: vec3 | quat = numComponents === 4 ? _sOutQuat : _sOutVec3;\n\n // Edge cases — clamp to first / last keyframe\n if (times.length === 0) {\n if (numComponents === 4) quat.identity(outScratch as quat);\n else vec3.set(outScratch as vec3, 0, 0, 0);\n return outScratch;\n }\n if (time <= times[0]) {\n readValueInto(values, 0, numComponents, outScratch);\n return outScratch;\n }\n if (time >= times[times.length - 1]) {\n readValueInto(values, times.length - 1, numComponents, outScratch);\n return outScratch;\n }\n\n // Binary search for the surrounding keyframe pair\n let lo = 0;\n let hi = times.length - 1;\n while (lo < hi - 1) {\n const mid = (lo + hi) >>> 1;\n if (times[mid] <= time) {\n lo = mid;\n } else {\n hi = mid;\n }\n }\n\n const t0 = times[lo];\n const t1 = times[hi];\n const factor = (time - t0) / (t1 - t0);\n\n const v0Scratch: vec3 | quat = numComponents === 4 ? _sv0Quat : _sv0Vec3;\n const v1Scratch: vec3 | quat = numComponents === 4 ? _sv1Quat : _sv1Vec3;\n readValueInto(values, lo, numComponents, v0Scratch);\n readValueInto(values, hi, numComponents, v1Scratch);\n\n if (interpolation === 'STEP') {\n // STEP: return v0 unchanged\n readValueInto(values, lo, numComponents, outScratch);\n return outScratch;\n }\n\n // LINEAR (or fallback for CUBICSPLINE — true cubic not yet implemented)\n if (path === 'rotation') {\n quat.slerp(outScratch as quat, v0Scratch as quat, v1Scratch as quat, factor);\n return outScratch;\n }\n\n vec3.lerp(outScratch as vec3, v0Scratch as vec3, v1Scratch as vec3, factor);\n return outScratch;\n}\n","import { Material, Mesh } from '../classes';\nimport { GL_LINES } from '../classes/Mesh';\nimport { Vector3 } from '../domain/interfaces/Vectors';\n\nexport function createWireBox(\n min: Vector3,\n max: Vector3,\n material: Material,\n): Mesh {\n const [minX, minY, minZ] = min;\n const [maxX, maxY, maxZ] = max;\n\n // 8 corners of the box\n const vertices: number[] = [\n minX,\n minY,\n minZ,\n maxX,\n minY,\n minZ,\n maxX,\n maxY,\n minZ,\n minX,\n maxY,\n minZ,\n minX,\n minY,\n maxZ,\n maxX,\n minY,\n maxZ,\n maxX,\n maxY,\n maxZ,\n minX,\n maxY,\n maxZ,\n ];\n\n // edges as lines (pairs of indices)\n const indices: number[] = [\n 0,\n 1,\n 1,\n 2,\n 2,\n 3,\n 3,\n 0, // bottom face\n 4,\n 5,\n 5,\n 6,\n 6,\n 7,\n 7,\n 4, // top face\n 0,\n 4,\n 1,\n 5,\n 2,\n 6,\n 3,\n 7, // vertical edges\n ];\n\n // expand indices to vertices array (since WebGL uses gl.LINES)\n const lineVertices: number[] = [];\n for (let i = 0; i < indices.length; i++) {\n const idx = indices[i];\n lineVertices.push(\n vertices[idx * 3],\n vertices[idx * 3 + 1],\n vertices[idx * 3 + 2],\n );\n }\n\n // Normals can just be zero for wireframe\n const normals = new Float32Array(lineVertices.length);\n\n const mesh = new Mesh(\n 'hitbox',\n new Float32Array(lineVertices),\n normals,\n material,\n new Float32Array(),\n null,\n );\n mesh.setMode(GL_LINES);\n return mesh;\n}\n"],"mappings":"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","names":["mat4","quat","vec3","mat4"]}