@fonsecabarreto/genesis-gl-core 0.1.0
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/LICENSE +21 -0
- package/README.md +33 -0
- package/dist/Camera-DY_8gx3C.d.ts +45 -0
- package/dist/Core/classes/Material.d.ts +3 -0
- package/dist/Core/classes/Material.js +9 -0
- package/dist/Core/classes/Material.js.map +1 -0
- package/dist/Core/classes/Model.d.ts +5 -0
- package/dist/Core/classes/Model.js +7 -0
- package/dist/Core/classes/Model.js.map +1 -0
- package/dist/Core/classes/Renderer.d.ts +30 -0
- package/dist/Core/classes/Renderer.js +11 -0
- package/dist/Core/classes/Renderer.js.map +1 -0
- package/dist/Core/classes/Scene.d.ts +37 -0
- package/dist/Core/classes/Scene.js +7 -0
- package/dist/Core/classes/Scene.js.map +1 -0
- package/dist/Core/classes/Viewport.d.ts +37 -0
- package/dist/Core/classes/Viewport.js +7 -0
- package/dist/Core/classes/Viewport.js.map +1 -0
- package/dist/Core/domain/interfaces/Vectors.d.ts +4 -0
- package/dist/Core/domain/interfaces/Vectors.js +1 -0
- package/dist/Core/domain/interfaces/Vectors.js.map +1 -0
- package/dist/Core/index.d.ts +10 -0
- package/dist/Core/index.js +51 -0
- package/dist/Core/index.js.map +1 -0
- package/dist/Core/utils/get-overlap.d.ts +3 -0
- package/dist/Core/utils/get-overlap.js +11 -0
- package/dist/Core/utils/get-overlap.js.map +1 -0
- package/dist/Core/utils/load-glb.d.ts +101 -0
- package/dist/Core/utils/load-glb.js +697 -0
- package/dist/Core/utils/load-glb.js.map +1 -0
- package/dist/Core/utils/parse-obj.d.ts +10 -0
- package/dist/Core/utils/parse-obj.js +183 -0
- package/dist/Core/utils/parse-obj.js.map +1 -0
- package/dist/Editor/index.d.ts +364 -0
- package/dist/Editor/index.js +1737 -0
- package/dist/Editor/index.js.map +1 -0
- package/dist/Game/controls/KeyboardInput.d.ts +8 -0
- package/dist/Game/controls/KeyboardInput.js +7 -0
- package/dist/Game/controls/KeyboardInput.js.map +1 -0
- package/dist/Game/index.d.ts +45 -0
- package/dist/Game/index.js +353 -0
- package/dist/Game/index.js.map +1 -0
- package/dist/KeyboardControl-5w7Vm0J0.d.ts +18 -0
- package/dist/KeyboardInput-DTsfj3tE.d.ts +166 -0
- package/dist/Material-BGLkldxv.d.ts +74 -0
- package/dist/Model-CQvDXd-b.d.ts +302 -0
- package/dist/WebGLCore-DR7ZHJB0.d.ts +22 -0
- package/dist/chunk-3ULETMWF.js +144 -0
- package/dist/chunk-3ULETMWF.js.map +1 -0
- package/dist/chunk-5TAAXI6S.js +330 -0
- package/dist/chunk-5TAAXI6S.js.map +1 -0
- package/dist/chunk-6LS6AO5H.js +296 -0
- package/dist/chunk-6LS6AO5H.js.map +1 -0
- package/dist/chunk-JK2HEZAT.js +317 -0
- package/dist/chunk-JK2HEZAT.js.map +1 -0
- package/dist/chunk-P7QOKDLY.js +57 -0
- package/dist/chunk-P7QOKDLY.js.map +1 -0
- package/dist/chunk-QCQVJCSR.js +968 -0
- package/dist/chunk-QCQVJCSR.js.map +1 -0
- package/dist/chunk-SUNYSY45.js +81 -0
- package/dist/chunk-SUNYSY45.js.map +1 -0
- package/package.json +83 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Lucas Fonseca Barreto
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# GenesisGL
|
|
2
|
+
|
|
3
|
+
GenesisGL is a lightweight browser-side WebGL 3D engine written in TypeScript.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @fonsecabarreto/genesis-gl-core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { WebGLCore, Scene, Renderer, Viewport } from '@fonsecabarreto/genesis-gl-core';
|
|
15
|
+
|
|
16
|
+
const canvas = document.getElementById('glcanvas') as HTMLCanvasElement;
|
|
17
|
+
const webglCore = new WebGLCore(canvas);
|
|
18
|
+
const viewport = new Viewport(canvas, window.innerWidth, window.innerHeight, webglCore);
|
|
19
|
+
const renderer = new Renderer(webglCore, viewport);
|
|
20
|
+
const scene = Scene.withDefaultLights(webglCore);
|
|
21
|
+
|
|
22
|
+
// Add models and render loop...
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Build
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
yarn build
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## License
|
|
32
|
+
|
|
33
|
+
MIT
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { vec3, mat4 } from 'gl-matrix';
|
|
2
|
+
import { Vector3 } from './Core/domain/interfaces/Vectors.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Perspective camera with orbit (yaw/pitch), zoom, and viewport controls.
|
|
6
|
+
*/
|
|
7
|
+
declare class Camera {
|
|
8
|
+
viewportWidth: number;
|
|
9
|
+
viewportHeight: number;
|
|
10
|
+
target: Vector3;
|
|
11
|
+
position: Vector3;
|
|
12
|
+
zoom: number;
|
|
13
|
+
minZoom: number;
|
|
14
|
+
maxZoom: number;
|
|
15
|
+
zoomSpeed: number;
|
|
16
|
+
yaw: number;
|
|
17
|
+
pitch: number;
|
|
18
|
+
near: number;
|
|
19
|
+
far: number;
|
|
20
|
+
lastViewMatrix?: Float32Array;
|
|
21
|
+
lastProjectionMatrix?: Float32Array;
|
|
22
|
+
constructor(viewportWidth: number, viewportHeight: number);
|
|
23
|
+
/** Translate the camera by a delta. */
|
|
24
|
+
move(dx: number, dy: number, dz?: number): void;
|
|
25
|
+
/** Clamp-set the zoom level. */
|
|
26
|
+
setZoom(zoom: number): void;
|
|
27
|
+
/** Zoom by a signed delta (positive = zoom in). */
|
|
28
|
+
zoomBy(delta: number): void;
|
|
29
|
+
worldToNDC(x: number, y: number): [number, number];
|
|
30
|
+
worldScale(scale: [number, number]): [number, number];
|
|
31
|
+
setViewport(width: number, height: number): void;
|
|
32
|
+
/** Compute the eye position from yaw/pitch/distance to target. */
|
|
33
|
+
getComputedPosition(): vec3;
|
|
34
|
+
/** Build the view matrix (lookAt). */
|
|
35
|
+
getViewMatrix(): mat4;
|
|
36
|
+
/** Build the perspective projection matrix. */
|
|
37
|
+
getProjectionMatrix(): mat4;
|
|
38
|
+
worldToNDC3D(x: number, y: number, z?: number): [number, number, number];
|
|
39
|
+
worldScale3D(scale: [number, number, number]): [number, number, number];
|
|
40
|
+
minPitch: number;
|
|
41
|
+
maxPitch: number;
|
|
42
|
+
rotate(deltaYaw: number, deltaPitch: number): void;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { Camera as C };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { mat4 } from 'gl-matrix';
|
|
2
|
+
import { W as WebGLCore } from '../../WebGLCore-DR7ZHJB0.js';
|
|
3
|
+
import { Scene } from './Scene.js';
|
|
4
|
+
import { i as Model } from '../../Model-CQvDXd-b.js';
|
|
5
|
+
import { Viewport } from './Viewport.js';
|
|
6
|
+
import '../../Material-BGLkldxv.js';
|
|
7
|
+
import '../domain/interfaces/Vectors.js';
|
|
8
|
+
import '../../Camera-DY_8gx3C.js';
|
|
9
|
+
|
|
10
|
+
declare class Renderer {
|
|
11
|
+
private webglCore;
|
|
12
|
+
viewport: Viewport;
|
|
13
|
+
/** Set to `true` to render wireframe bounding boxes for debugging. */
|
|
14
|
+
debug: boolean;
|
|
15
|
+
private _modelHitboxMaterial;
|
|
16
|
+
private _meshHitboxMaterial;
|
|
17
|
+
constructor(webglCore: WebGLCore, viewport: Viewport);
|
|
18
|
+
/** Lazily-created material for model-level hitboxes (red). */
|
|
19
|
+
private get modelHitboxMaterial();
|
|
20
|
+
/** Lazily-created material for mesh-level hitboxes (green). */
|
|
21
|
+
private get meshHitboxMaterial();
|
|
22
|
+
clearFrame(color?: [number, number, number, number]): void;
|
|
23
|
+
render(scene: Scene): void;
|
|
24
|
+
private drawModel;
|
|
25
|
+
private drawMesh;
|
|
26
|
+
drawHitBox(model: Model, modelMatrix: mat4, activeProgram: WebGLProgram | null): void;
|
|
27
|
+
private drawHitBoxForMesh;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { Renderer };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Renderer
|
|
3
|
+
} from "../../chunk-QCQVJCSR.js";
|
|
4
|
+
import "../../chunk-6LS6AO5H.js";
|
|
5
|
+
import "../../chunk-JK2HEZAT.js";
|
|
6
|
+
import "../../chunk-3ULETMWF.js";
|
|
7
|
+
import "../../chunk-5TAAXI6S.js";
|
|
8
|
+
export {
|
|
9
|
+
Renderer
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=Renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { L as Light } from '../../Material-BGLkldxv.js';
|
|
2
|
+
import { i as Model } from '../../Model-CQvDXd-b.js';
|
|
3
|
+
import { W as WebGLCore } from '../../WebGLCore-DR7ZHJB0.js';
|
|
4
|
+
import '../domain/interfaces/Vectors.js';
|
|
5
|
+
import 'gl-matrix';
|
|
6
|
+
|
|
7
|
+
declare class Scene {
|
|
8
|
+
private webglCore;
|
|
9
|
+
private models;
|
|
10
|
+
private modelsMap;
|
|
11
|
+
lights: Light[];
|
|
12
|
+
constructor(webglCore: WebGLCore);
|
|
13
|
+
/**
|
|
14
|
+
* Create a Scene pre-loaded with a classic **3-point lighting** rig
|
|
15
|
+
* (ambient + key + fill + back).
|
|
16
|
+
*
|
|
17
|
+
* Use this for quick prototyping; for production, create a plain Scene and
|
|
18
|
+
* add your own lights.
|
|
19
|
+
*/
|
|
20
|
+
static withDefaultLights(webglCore: WebGLCore): Scene;
|
|
21
|
+
/** Register a light source in the scene. */
|
|
22
|
+
addLight(id: string, light: Light): void;
|
|
23
|
+
/** Add a model to the scene with a unique key. */
|
|
24
|
+
add(id: string, model: Model): void;
|
|
25
|
+
/** Remove a model from the scene by key. */
|
|
26
|
+
remove(key: string): void;
|
|
27
|
+
getModels(): Model[];
|
|
28
|
+
getLights(): Light[];
|
|
29
|
+
/** Retrieve a model by its key. */
|
|
30
|
+
getModel(key: string): Model | undefined;
|
|
31
|
+
hasMesh(key: string): boolean;
|
|
32
|
+
/** Returns all [id, model] pairs — useful for debug/inspector tools. */
|
|
33
|
+
getEntries(): [string, Model][];
|
|
34
|
+
dispose(webglCore: WebGLCore): void;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { Scene };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { C as Camera } from '../../Camera-DY_8gx3C.js';
|
|
2
|
+
import { W as WebGLCore } from '../../WebGLCore-DR7ZHJB0.js';
|
|
3
|
+
import 'gl-matrix';
|
|
4
|
+
import '../domain/interfaces/Vectors.js';
|
|
5
|
+
|
|
6
|
+
declare class Viewport {
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
private static zoomInterval;
|
|
10
|
+
private wheelControl;
|
|
11
|
+
private dragControl;
|
|
12
|
+
private moveControl;
|
|
13
|
+
private lastZoomTime;
|
|
14
|
+
private canvas;
|
|
15
|
+
private scale;
|
|
16
|
+
private webglCore;
|
|
17
|
+
private resizeHandler;
|
|
18
|
+
camera: Camera;
|
|
19
|
+
/**
|
|
20
|
+
* @param canvasOrId - An HTMLCanvasElement or the `id` attribute of one.
|
|
21
|
+
* @param width - Logical viewport width.
|
|
22
|
+
* @param height - Logical viewport height.
|
|
23
|
+
* @param webglCore - Optional WebGLCore instance. When provided, the existing
|
|
24
|
+
* GL context is reused for viewport resize instead of
|
|
25
|
+
* requesting a new one.
|
|
26
|
+
*/
|
|
27
|
+
constructor(canvasOrId: string | HTMLCanvasElement, width: number, height: number, webglCore?: WebGLCore);
|
|
28
|
+
private setupControls;
|
|
29
|
+
isDraggingCamera(): boolean;
|
|
30
|
+
private resizeCanvas;
|
|
31
|
+
getCanvas(): HTMLCanvasElement;
|
|
32
|
+
getScale(): number;
|
|
33
|
+
/** Release event listeners. Call when the viewport is no longer needed. */
|
|
34
|
+
dispose(): void;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { Viewport };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=Vectors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,10 @@
|
|
|
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-CQvDXd-b.js';
|
|
2
|
+
export { R as RenderCallback, W as WebGLCore } from '../WebGLCore-DR7ZHJB0.js';
|
|
3
|
+
export { C as Camera } from '../Camera-DY_8gx3C.js';
|
|
4
|
+
export { L as Light, a as LightType, M as MAX_LIGHTS, b as Material } from '../Material-BGLkldxv.js';
|
|
5
|
+
export { Renderer } from './classes/Renderer.js';
|
|
6
|
+
export { Scene } from './classes/Scene.js';
|
|
7
|
+
export { Viewport } from './classes/Viewport.js';
|
|
8
|
+
export { K as KeyboardControl } from '../KeyboardControl-5w7Vm0J0.js';
|
|
9
|
+
import './domain/interfaces/Vectors.js';
|
|
10
|
+
import 'gl-matrix';
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import {
|
|
2
|
+
KeyboardControl
|
|
3
|
+
} from "../chunk-SUNYSY45.js";
|
|
4
|
+
import {
|
|
5
|
+
AnimationClip,
|
|
6
|
+
GL_LINES,
|
|
7
|
+
GL_TRIANGLES,
|
|
8
|
+
INITIAL_BOUNDING_BOX,
|
|
9
|
+
MAX_JOINTS,
|
|
10
|
+
Mesh,
|
|
11
|
+
MeshBuffers,
|
|
12
|
+
Renderer,
|
|
13
|
+
Skeleton,
|
|
14
|
+
WebGLCore
|
|
15
|
+
} from "../chunk-QCQVJCSR.js";
|
|
16
|
+
import {
|
|
17
|
+
MAX_LIGHTS,
|
|
18
|
+
Material
|
|
19
|
+
} from "../chunk-6LS6AO5H.js";
|
|
20
|
+
import {
|
|
21
|
+
Model
|
|
22
|
+
} from "../chunk-JK2HEZAT.js";
|
|
23
|
+
import {
|
|
24
|
+
Light,
|
|
25
|
+
Scene
|
|
26
|
+
} from "../chunk-3ULETMWF.js";
|
|
27
|
+
import {
|
|
28
|
+
Camera,
|
|
29
|
+
Viewport
|
|
30
|
+
} from "../chunk-5TAAXI6S.js";
|
|
31
|
+
export {
|
|
32
|
+
AnimationClip,
|
|
33
|
+
Camera,
|
|
34
|
+
GL_LINES,
|
|
35
|
+
GL_TRIANGLES,
|
|
36
|
+
INITIAL_BOUNDING_BOX,
|
|
37
|
+
KeyboardControl,
|
|
38
|
+
Light,
|
|
39
|
+
MAX_JOINTS,
|
|
40
|
+
MAX_LIGHTS,
|
|
41
|
+
Material,
|
|
42
|
+
Mesh,
|
|
43
|
+
MeshBuffers,
|
|
44
|
+
Model,
|
|
45
|
+
Renderer,
|
|
46
|
+
Scene,
|
|
47
|
+
Skeleton,
|
|
48
|
+
Viewport,
|
|
49
|
+
WebGLCore
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// src/Core/utils/get-overlap.ts
|
|
2
|
+
function getOverlap(min1, max1, min2, max2) {
|
|
3
|
+
if (max1 <= min2 || max2 <= min1) return 0;
|
|
4
|
+
const dist1 = max2 - min1;
|
|
5
|
+
const dist2 = min2 - max1;
|
|
6
|
+
return Math.abs(dist1) < Math.abs(dist2) ? dist1 : dist2;
|
|
7
|
+
}
|
|
8
|
+
export {
|
|
9
|
+
getOverlap
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=get-overlap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/Core/utils/get-overlap.ts"],"sourcesContent":["export function getOverlap(\n min1: number,\n max1: number,\n min2: number,\n max2: number,\n): number {\n // No overlap (they are separated)\n if (max1 <= min2 || max2 <= min1) return 0;\n\n // Calculate the distance from mesh1's minimum to mesh2's maximum\n const dist1 = max2 - min1;\n // Calculate the distance from mesh2's minimum to mesh1's maximum\n const dist2 = min2 - max1;\n\n // Return the overlap that requires the smallest movement (smallest absolute value)\n // The sign indicates the direction of movement.\n return Math.abs(dist1) < Math.abs(dist2) ? dist1 : dist2;\n}\n"],"mappings":";AAAO,SAAS,WACd,MACA,MACA,MACA,MACQ;AAER,MAAI,QAAQ,QAAQ,QAAQ,KAAM,QAAO;AAGzC,QAAM,QAAQ,OAAO;AAErB,QAAM,QAAQ,OAAO;AAIrB,SAAO,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ;AACrD;","names":[]}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { W as WebGLCore } from '../../WebGLCore-DR7ZHJB0.js';
|
|
2
|
+
import { i as Model, S as Skeleton, a as AnimationClip } from '../../Model-CQvDXd-b.js';
|
|
3
|
+
import '../domain/interfaces/Vectors.js';
|
|
4
|
+
import '../../Material-BGLkldxv.js';
|
|
5
|
+
import 'gl-matrix';
|
|
6
|
+
|
|
7
|
+
/** Everything parsed from a GLB file. */
|
|
8
|
+
interface GLBLoadResult {
|
|
9
|
+
/** The composed model with all meshes. */
|
|
10
|
+
model: Model;
|
|
11
|
+
/** Skeleton (if the GLB contains a skin). */
|
|
12
|
+
skeleton: Skeleton | null;
|
|
13
|
+
/** Named animation clips (if the GLB contains animations). */
|
|
14
|
+
animations: Map<string, AnimationClip>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Professional GLB (binary glTF 2.0) loader for the GenesisGL engine.
|
|
18
|
+
*
|
|
19
|
+
* Handles:
|
|
20
|
+
* - Strongly-typed glTF JSON parsing (no `any`)
|
|
21
|
+
* - Full PBR material extraction (base colour, textures, alpha, double-sided)
|
|
22
|
+
* - Embedded texture decoding from binary chunk
|
|
23
|
+
* - Complete node hierarchy traversal
|
|
24
|
+
* - Skeletal mesh data (JOINTS_0 / WEIGHTS_0)
|
|
25
|
+
* - Skin parsing (inverse bind matrices + joint hierarchy)
|
|
26
|
+
* - Animation parsing (TRS channels with LINEAR/STEP interpolation)
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* const loader = new GLBLoader(core);
|
|
31
|
+
* const { model, skeleton, animations } = await loader.load('/models/character.glb', 'hero');
|
|
32
|
+
* if (skeleton) model.skeleton = skeleton;
|
|
33
|
+
* for (const [name, clip] of animations) model.animations.set(name, clip);
|
|
34
|
+
* scene.add(model);
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
declare class GLBLoader {
|
|
38
|
+
private gl;
|
|
39
|
+
private core;
|
|
40
|
+
constructor(core: WebGLCore);
|
|
41
|
+
/**
|
|
42
|
+
* Fetch and parse a `.glb` file.
|
|
43
|
+
*
|
|
44
|
+
* @param url - URL to the GLB resource.
|
|
45
|
+
* @param name - Logical name assigned to the resulting {@link Model}.
|
|
46
|
+
* @returns Parsed model, optional skeleton, and animation clips.
|
|
47
|
+
*/
|
|
48
|
+
load(url: string, name?: string): Promise<GLBLoadResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Parse a raw GLB `ArrayBuffer` that was already loaded (e.g. from drag-and-drop).
|
|
51
|
+
*/
|
|
52
|
+
parse(arrayBuffer: ArrayBuffer, name?: string): Promise<GLBLoadResult>;
|
|
53
|
+
private parseGlbHeader;
|
|
54
|
+
/**
|
|
55
|
+
* Walk the active scene's node tree and return all renderable meshes.
|
|
56
|
+
*
|
|
57
|
+
* Each scene node that references a mesh is visited in hierarchy order.
|
|
58
|
+
* Non-skinned mesh nodes that are children of joint nodes (e.g. eyes /
|
|
59
|
+
* hair parented to the Head bone in Blender) are automatically handled:
|
|
60
|
+
* their vertex data is pre-transformed into skin-space and synthetic
|
|
61
|
+
* single-joint weights are generated so they deform with the parent bone.
|
|
62
|
+
*
|
|
63
|
+
* @param skeleton – already-parsed skin for this model (or null).
|
|
64
|
+
*/
|
|
65
|
+
private parseMeshes;
|
|
66
|
+
/**
|
|
67
|
+
* Pre-transform a bone-parented non-skinned mesh into skin coordinate space
|
|
68
|
+
* and synthesise single-joint weights so it deforms with its parent bone.
|
|
69
|
+
*
|
|
70
|
+
* The transform applied to each vertex is:
|
|
71
|
+
* T = inv(IBM_parentJoint) × nodeLocalTransform
|
|
72
|
+
*
|
|
73
|
+
* After this call `mesh.isSkinned` returns `true`.
|
|
74
|
+
*/
|
|
75
|
+
private applyBoneParenting;
|
|
76
|
+
private parsePrimitive;
|
|
77
|
+
private parseMaterial;
|
|
78
|
+
/**
|
|
79
|
+
* Decode a texture embedded in the GLB binary chunk and upload to GPU.
|
|
80
|
+
*/
|
|
81
|
+
private loadEmbeddedTexture;
|
|
82
|
+
private createTextureFromUrl;
|
|
83
|
+
private parseSkin;
|
|
84
|
+
/**
|
|
85
|
+
* Compute the accumulated global transform of all non-joint ancestor
|
|
86
|
+
* nodes above the skeleton's root joint(s).
|
|
87
|
+
*/
|
|
88
|
+
private computeSkinRootTransform;
|
|
89
|
+
private parseAnimation;
|
|
90
|
+
/**
|
|
91
|
+
* Extract a typed array from a glTF accessor + bufferView.
|
|
92
|
+
* Handles byte-stride (interleaved buffers) and all glTF component types.
|
|
93
|
+
*/
|
|
94
|
+
private getAccessorData;
|
|
95
|
+
/** Compute the local transform matrix from a glTF node's TRS or matrix. */
|
|
96
|
+
private getNodeLocalMatrix;
|
|
97
|
+
/** Generate flat face-normals when the mesh doesn't include them. */
|
|
98
|
+
private generateFlatNormals;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export { type GLBLoadResult, GLBLoader };
|