three-text 0.1.1 → 0.2.1

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 (42) hide show
  1. package/README.md +166 -156
  2. package/dist/index.cjs +368 -82
  3. package/dist/index.d.ts +46 -17
  4. package/dist/index.js +367 -81
  5. package/dist/index.min.cjs +2 -2
  6. package/dist/index.min.js +2 -2
  7. package/dist/index.umd.js +372 -84
  8. package/dist/index.umd.min.js +2 -2
  9. package/dist/p5/index.cjs +33 -0
  10. package/dist/p5/index.d.ts +19 -0
  11. package/dist/p5/index.js +31 -0
  12. package/dist/three/index.cjs +50 -0
  13. package/dist/three/index.d.ts +29 -0
  14. package/dist/three/index.js +48 -0
  15. package/dist/{react/index.cjs → three/react.cjs} +14 -4
  16. package/dist/three/react.d.ts +346 -0
  17. package/dist/{react/index.js → three/react.js} +14 -4
  18. package/dist/types/core/Text.d.ts +1 -1
  19. package/dist/types/core/cache/GlyphCache.d.ts +4 -4
  20. package/dist/types/core/cache/GlyphContourCollector.d.ts +2 -2
  21. package/dist/types/core/cache/GlyphGeometryBuilder.d.ts +3 -2
  22. package/dist/types/core/geometry/BoundaryClusterer.d.ts +2 -2
  23. package/dist/types/core/geometry/Polygonizer.d.ts +3 -3
  24. package/dist/types/core/layout/TextLayout.d.ts +1 -2
  25. package/dist/types/core/shaping/TextShaper.d.ts +1 -2
  26. package/dist/types/core/types.d.ts +13 -16
  27. package/dist/types/core/vectors.d.ts +75 -0
  28. package/dist/types/p5/index.d.ts +17 -0
  29. package/dist/types/{react → three}/ThreeText.d.ts +2 -2
  30. package/dist/types/three/index.d.ts +21 -0
  31. package/dist/types/three/react.d.ts +10 -0
  32. package/dist/types/webgl/index.d.ts +48 -0
  33. package/dist/types/webgpu/index.d.ts +16 -0
  34. package/dist/webgl/index.cjs +88 -0
  35. package/dist/webgl/index.d.ts +51 -0
  36. package/dist/webgl/index.js +86 -0
  37. package/dist/webgpu/index.cjs +99 -0
  38. package/dist/webgpu/index.d.ts +19 -0
  39. package/dist/webgpu/index.js +97 -0
  40. package/package.json +22 -6
  41. package/dist/react/index.d.ts +0 -18
  42. package/dist/types/react/index.d.ts +0 -2
@@ -1,5 +1,4 @@
1
1
  import { LineInfo, TextAlign, LoadedFont, LayoutOptions } from '../types';
2
- import { BufferGeometry } from 'three';
3
2
  export interface TextLayoutOptions extends LayoutOptions {
4
3
  text: string;
5
4
  letterSpacing: number;
@@ -27,7 +26,7 @@ export declare class TextLayout {
27
26
  private loadedFont;
28
27
  constructor(loadedFont: LoadedFont);
29
28
  computeLines(options: TextLayoutOptions): LayoutResult;
30
- applyAlignment(geometry: BufferGeometry, options: AlignmentOptions): {
29
+ applyAlignment(vertices: Float32Array, options: AlignmentOptions): {
31
30
  offset: number;
32
31
  adjustedBounds: {
33
32
  min: {
@@ -1,8 +1,7 @@
1
- import { BufferGeometry } from 'three';
2
1
  import { LoadedFont, GlyphGeometryInfo, LineInfo, TextDirection, GlyphCluster, ColorOptions } from '../types';
3
2
  import { GlyphGeometryBuilder } from '../cache/GlyphGeometryBuilder';
4
3
  export interface ShapedResult {
5
- geometry: BufferGeometry;
4
+ geometry: any;
6
5
  glyphInfos: GlyphGeometryInfo[];
7
6
  planeBounds: {
8
7
  min: {
@@ -1,8 +1,8 @@
1
- import { Vector2, BufferGeometry, Vector3 } from 'three';
2
1
  import type { HyphenationTrieNode } from '../hyphenation';
2
+ import type { Vec2, Vec3, BoundingBox } from './vectors';
3
3
  export type { HyphenationTrieNode };
4
4
  export interface Path {
5
- points: Vector2[];
5
+ points: Vec2[];
6
6
  glyphIndex: number;
7
7
  bounds?: {
8
8
  minX: number;
@@ -26,7 +26,7 @@ export interface HarfBuzzGlyph {
26
26
  export interface GlyphCluster {
27
27
  text: string;
28
28
  glyphs: HarfBuzzGlyph[];
29
- position: Vector3;
29
+ position: Vec3;
30
30
  }
31
31
  export interface GlyphContours {
32
32
  glyphId: number;
@@ -206,20 +206,17 @@ export interface TextQueryOptions {
206
206
  }[];
207
207
  }
208
208
  export interface TextGeometryInfo {
209
- geometry: BufferGeometry;
210
- glyphs: GlyphGeometryInfo[];
211
- planeBounds: {
212
- min: {
213
- x: number;
214
- y: number;
215
- z: number;
216
- };
217
- max: {
218
- x: number;
219
- y: number;
220
- z: number;
221
- };
209
+ vertices: Float32Array;
210
+ normals: Float32Array;
211
+ indices: Uint32Array;
212
+ colors?: Float32Array;
213
+ glyphAttributes?: {
214
+ glyphCenter: Float32Array;
215
+ glyphIndex: Float32Array;
216
+ glyphLineIndex: Float32Array;
222
217
  };
218
+ glyphs: GlyphGeometryInfo[];
219
+ planeBounds: BoundingBox;
223
220
  stats: {
224
221
  trianglesGenerated: number;
225
222
  verticesGenerated: number;
@@ -0,0 +1,75 @@
1
+ export declare class Vec2 {
2
+ x: number;
3
+ y: number;
4
+ constructor(x?: number, y?: number);
5
+ set(x: number, y: number): Vec2;
6
+ clone(): Vec2;
7
+ copy(v: Vec2): Vec2;
8
+ add(v: Vec2): Vec2;
9
+ sub(v: Vec2): Vec2;
10
+ multiply(scalar: number): Vec2;
11
+ divide(scalar: number): Vec2;
12
+ length(): number;
13
+ lengthSq(): number;
14
+ normalize(): Vec2;
15
+ dot(v: Vec2): number;
16
+ distanceTo(v: Vec2): number;
17
+ distanceToSquared(v: Vec2): number;
18
+ equals(v: Vec2): boolean;
19
+ angle(): number;
20
+ }
21
+ export declare class Vec3 {
22
+ x: number;
23
+ y: number;
24
+ z: number;
25
+ constructor(x?: number, y?: number, z?: number);
26
+ set(x: number, y: number, z: number): Vec3;
27
+ clone(): Vec3;
28
+ copy(v: Vec3): Vec3;
29
+ add(v: Vec3): Vec3;
30
+ sub(v: Vec3): Vec3;
31
+ multiply(scalar: number): Vec3;
32
+ divide(scalar: number): Vec3;
33
+ length(): number;
34
+ lengthSq(): number;
35
+ normalize(): Vec3;
36
+ dot(v: Vec3): number;
37
+ cross(v: Vec3): Vec3;
38
+ distanceTo(v: Vec3): number;
39
+ distanceToSquared(v: Vec3): number;
40
+ equals(v: Vec3): boolean;
41
+ }
42
+ export declare class Box3 {
43
+ min: Vec3;
44
+ max: Vec3;
45
+ constructor(min?: Vec3, max?: Vec3);
46
+ set(min: Vec3, max: Vec3): Box3;
47
+ setFromPoints(points: Vec3[]): Box3;
48
+ makeEmpty(): Box3;
49
+ isEmpty(): boolean;
50
+ expandByPoint(point: Vec3): Box3;
51
+ expandByScalar(scalar: number): Box3;
52
+ containsPoint(point: Vec3): boolean;
53
+ containsBox(box: Box3): boolean;
54
+ intersectsBox(box: Box3): boolean;
55
+ getCenter(target?: Vec3): Vec3;
56
+ getSize(target?: Vec3): Vec3;
57
+ clone(): Box3;
58
+ copy(box: Box3): Box3;
59
+ union(box: Box3): Box3;
60
+ equals(box: Box3): boolean;
61
+ }
62
+ export interface BoundingBox {
63
+ min: {
64
+ x: number;
65
+ y: number;
66
+ z: number;
67
+ };
68
+ max: {
69
+ x: number;
70
+ y: number;
71
+ z: number;
72
+ };
73
+ }
74
+ export declare function box3ToBoundingBox(box: Box3): BoundingBox;
75
+ export declare function boundingBoxToBox3(bounds: BoundingBox): Box3;
@@ -0,0 +1,17 @@
1
+ import type { TextGeometryInfo } from '../core/types';
2
+ interface P5Vector {
3
+ x: number;
4
+ y: number;
5
+ z: number;
6
+ }
7
+ interface P5Geometry {
8
+ vertices: P5Vector[];
9
+ faces: number[][];
10
+ vertexNormals: P5Vector[];
11
+ }
12
+ interface P5Instance {
13
+ Geometry: new () => P5Geometry;
14
+ createVector(x: number, y: number, z: number): P5Vector;
15
+ }
16
+ export declare function createP5Geometry(p5Instance: P5Instance | any, textGeometry: TextGeometryInfo): P5Geometry;
17
+ export {};
@@ -1,5 +1,5 @@
1
1
  import * as THREE from "three";
2
- import type { TextOptions, TextGeometryInfo } from "../core/types";
2
+ import type { TextOptions, ThreeTextGeometryInfo as TextGeometryInfo } from "./index";
3
3
  export interface ThreeTextProps extends Omit<TextOptions, "text"> {
4
4
  children: string;
5
5
  font: string | ArrayBuffer;
@@ -11,4 +11,4 @@ export interface ThreeTextProps extends Omit<TextOptions, "text"> {
11
11
  onError?: (error: Error) => void;
12
12
  vertexColors?: boolean;
13
13
  }
14
- export declare const ThreeText: import("react").ForwardRefExoticComponent<ThreeTextProps & import("react").RefAttributes<THREE.Mesh<THREE.BufferGeometry<THREE.NormalBufferAttributes, THREE.BufferGeometryEventMap>, THREE.Material | THREE.Material[], THREE.Object3DEventMap>>>;
14
+ export declare const Text: import("react").ForwardRefExoticComponent<ThreeTextProps & import("react").RefAttributes<THREE.Mesh<THREE.BufferGeometry<THREE.NormalBufferAttributes, THREE.BufferGeometryEventMap>, THREE.Material | THREE.Material[], THREE.Object3DEventMap>>>;
@@ -0,0 +1,21 @@
1
+ import { BufferGeometry } from 'three';
2
+ import { Text as TextCore } from '../core/Text';
3
+ import type { TextOptions, TextGeometryInfo as CoreTextGeometryInfo, LoadedFont } from '../core/types';
4
+ import type { HyphenationTrieNode } from '../hyphenation';
5
+ export interface ThreeTextGeometryInfo extends Omit<CoreTextGeometryInfo, 'vertices' | 'normals' | 'indices' | 'colors' | 'glyphAttributes'> {
6
+ geometry: BufferGeometry;
7
+ getLoadedFont(): LoadedFont | undefined;
8
+ getCacheStatistics(): any;
9
+ clearCache(): void;
10
+ measureTextWidth(text: string, letterSpacing?: number): number;
11
+ }
12
+ export declare class Text {
13
+ static setHarfBuzzPath: typeof TextCore.setHarfBuzzPath;
14
+ static setHarfBuzzBuffer: typeof TextCore.setHarfBuzzBuffer;
15
+ static init: typeof TextCore.init;
16
+ static registerPattern: typeof TextCore.registerPattern;
17
+ static preloadPatterns: typeof TextCore.preloadPatterns;
18
+ static create(options: TextOptions): Promise<ThreeTextGeometryInfo>;
19
+ }
20
+ export type { TextOptions, ThreeTextGeometryInfo as TextGeometryInfo, LoadedFont };
21
+ export type { HyphenationTrieNode };
@@ -0,0 +1,10 @@
1
+ import { Text as ThreeTextCore } from './index';
2
+ export type { ThreeTextProps } from './ThreeText';
3
+ export declare const Text: import("react").ForwardRefExoticComponent<import("./ThreeText").ThreeTextProps & import("react").RefAttributes<import("three").Mesh<import("three").BufferGeometry<import("three").NormalBufferAttributes, import("three").BufferGeometryEventMap>, import("three").Material | import("three").Material[], import("three").Object3DEventMap>>> & {
4
+ setHarfBuzzPath: typeof import("..").Text.setHarfBuzzPath;
5
+ setHarfBuzzBuffer: typeof import("..").Text.setHarfBuzzBuffer;
6
+ init: typeof import("..").Text.init;
7
+ registerPattern: typeof import("..").Text.registerPattern;
8
+ preloadPatterns: typeof import("..").Text.preloadPatterns;
9
+ create: typeof ThreeTextCore.create;
10
+ };
@@ -0,0 +1,48 @@
1
+ import type { TextGeometryInfo } from '../core/types';
2
+ export interface WebGLBufferSet {
3
+ buffers: {
4
+ position: WebGLBuffer;
5
+ normal: WebGLBuffer;
6
+ color?: WebGLBuffer;
7
+ indices: WebGLBuffer;
8
+ glyphCenter?: WebGLBuffer;
9
+ glyphIndex?: WebGLBuffer;
10
+ glyphLineIndex?: WebGLBuffer;
11
+ };
12
+ attributes: {
13
+ position: {
14
+ size: number;
15
+ type: GLenum;
16
+ normalized: boolean;
17
+ };
18
+ normal: {
19
+ size: number;
20
+ type: GLenum;
21
+ normalized: boolean;
22
+ };
23
+ color?: {
24
+ size: number;
25
+ type: GLenum;
26
+ normalized: boolean;
27
+ };
28
+ glyphCenter?: {
29
+ size: number;
30
+ type: GLenum;
31
+ normalized: boolean;
32
+ };
33
+ glyphIndex?: {
34
+ size: number;
35
+ type: GLenum;
36
+ normalized: boolean;
37
+ };
38
+ glyphLineIndex?: {
39
+ size: number;
40
+ type: GLenum;
41
+ normalized: boolean;
42
+ };
43
+ };
44
+ drawCount: number;
45
+ mode: GLenum;
46
+ dispose(): void;
47
+ }
48
+ export declare function createWebGLBuffers(gl: WebGLRenderingContext | WebGL2RenderingContext, textGeometry: TextGeometryInfo): WebGLBufferSet;
@@ -0,0 +1,16 @@
1
+ import type { TextGeometryInfo } from '../core/types';
2
+ export interface WebGPUBufferSet {
3
+ buffers: {
4
+ vertex: GPUBuffer;
5
+ color?: GPUBuffer;
6
+ indices: GPUBuffer;
7
+ };
8
+ layout: {
9
+ vertex: GPUVertexBufferLayout;
10
+ color?: GPUVertexBufferLayout;
11
+ };
12
+ indexFormat: GPUIndexFormat;
13
+ vertexCount: number;
14
+ dispose(): void;
15
+ }
16
+ export declare function createWebGPUBuffers(device: GPUDevice, textGeometry: TextGeometryInfo): WebGPUBufferSet;
@@ -0,0 +1,88 @@
1
+ 'use strict';
2
+
3
+ // WebGL adapter - lightweight utility to create WebGL buffers from core geometry
4
+ function createWebGLBuffers(gl, textGeometry) {
5
+ const { vertices, normals, indices, colors, glyphAttributes } = textGeometry;
6
+ // Create position buffer
7
+ const positionBuffer = gl.createBuffer();
8
+ if (!positionBuffer)
9
+ throw new Error('Failed to create position buffer');
10
+ gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
11
+ gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
12
+ // Create normal buffer
13
+ const normalBuffer = gl.createBuffer();
14
+ if (!normalBuffer)
15
+ throw new Error('Failed to create normal buffer');
16
+ gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
17
+ gl.bufferData(gl.ARRAY_BUFFER, normals, gl.STATIC_DRAW);
18
+ // Create index buffer
19
+ const indexBuffer = gl.createBuffer();
20
+ if (!indexBuffer)
21
+ throw new Error('Failed to create index buffer');
22
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
23
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
24
+ const buffers = {
25
+ position: positionBuffer,
26
+ normal: normalBuffer,
27
+ indices: indexBuffer
28
+ };
29
+ const attributes = {
30
+ position: { size: 3, type: gl.FLOAT, normalized: false },
31
+ normal: { size: 3, type: gl.FLOAT, normalized: false }
32
+ };
33
+ // Optional color buffer
34
+ if (colors) {
35
+ const colorBuffer = gl.createBuffer();
36
+ if (!colorBuffer)
37
+ throw new Error('Failed to create color buffer');
38
+ gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
39
+ gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
40
+ buffers.color = colorBuffer;
41
+ attributes.color = { size: 3, type: gl.FLOAT, normalized: false };
42
+ }
43
+ // Optional glyph attribute buffers
44
+ if (glyphAttributes) {
45
+ const glyphCenterBuffer = gl.createBuffer();
46
+ if (!glyphCenterBuffer)
47
+ throw new Error('Failed to create glyphCenter buffer');
48
+ gl.bindBuffer(gl.ARRAY_BUFFER, glyphCenterBuffer);
49
+ gl.bufferData(gl.ARRAY_BUFFER, glyphAttributes.glyphCenter, gl.STATIC_DRAW);
50
+ buffers.glyphCenter = glyphCenterBuffer;
51
+ attributes.glyphCenter = { size: 3, type: gl.FLOAT, normalized: false };
52
+ const glyphIndexBuffer = gl.createBuffer();
53
+ if (!glyphIndexBuffer)
54
+ throw new Error('Failed to create glyphIndex buffer');
55
+ gl.bindBuffer(gl.ARRAY_BUFFER, glyphIndexBuffer);
56
+ gl.bufferData(gl.ARRAY_BUFFER, glyphAttributes.glyphIndex, gl.STATIC_DRAW);
57
+ buffers.glyphIndex = glyphIndexBuffer;
58
+ attributes.glyphIndex = { size: 1, type: gl.FLOAT, normalized: false };
59
+ const glyphLineIndexBuffer = gl.createBuffer();
60
+ if (!glyphLineIndexBuffer)
61
+ throw new Error('Failed to create glyphLineIndex buffer');
62
+ gl.bindBuffer(gl.ARRAY_BUFFER, glyphLineIndexBuffer);
63
+ gl.bufferData(gl.ARRAY_BUFFER, glyphAttributes.glyphLineIndex, gl.STATIC_DRAW);
64
+ buffers.glyphLineIndex = glyphLineIndexBuffer;
65
+ attributes.glyphLineIndex = { size: 1, type: gl.FLOAT, normalized: false };
66
+ }
67
+ return {
68
+ buffers,
69
+ attributes,
70
+ drawCount: indices.length,
71
+ mode: gl.TRIANGLES,
72
+ dispose() {
73
+ gl.deleteBuffer(positionBuffer);
74
+ gl.deleteBuffer(normalBuffer);
75
+ gl.deleteBuffer(indexBuffer);
76
+ if (buffers.color)
77
+ gl.deleteBuffer(buffers.color);
78
+ if (buffers.glyphCenter)
79
+ gl.deleteBuffer(buffers.glyphCenter);
80
+ if (buffers.glyphIndex)
81
+ gl.deleteBuffer(buffers.glyphIndex);
82
+ if (buffers.glyphLineIndex)
83
+ gl.deleteBuffer(buffers.glyphLineIndex);
84
+ }
85
+ };
86
+ }
87
+
88
+ exports.createWebGLBuffers = createWebGLBuffers;
@@ -0,0 +1,51 @@
1
+ import { TextGeometryInfo } from '../core/types';
2
+
3
+ interface WebGLBufferSet {
4
+ buffers: {
5
+ position: WebGLBuffer;
6
+ normal: WebGLBuffer;
7
+ color?: WebGLBuffer;
8
+ indices: WebGLBuffer;
9
+ glyphCenter?: WebGLBuffer;
10
+ glyphIndex?: WebGLBuffer;
11
+ glyphLineIndex?: WebGLBuffer;
12
+ };
13
+ attributes: {
14
+ position: {
15
+ size: number;
16
+ type: GLenum;
17
+ normalized: boolean;
18
+ };
19
+ normal: {
20
+ size: number;
21
+ type: GLenum;
22
+ normalized: boolean;
23
+ };
24
+ color?: {
25
+ size: number;
26
+ type: GLenum;
27
+ normalized: boolean;
28
+ };
29
+ glyphCenter?: {
30
+ size: number;
31
+ type: GLenum;
32
+ normalized: boolean;
33
+ };
34
+ glyphIndex?: {
35
+ size: number;
36
+ type: GLenum;
37
+ normalized: boolean;
38
+ };
39
+ glyphLineIndex?: {
40
+ size: number;
41
+ type: GLenum;
42
+ normalized: boolean;
43
+ };
44
+ };
45
+ drawCount: number;
46
+ mode: GLenum;
47
+ dispose(): void;
48
+ }
49
+ declare function createWebGLBuffers(gl: WebGLRenderingContext | WebGL2RenderingContext, textGeometry: TextGeometryInfo): WebGLBufferSet;
50
+
51
+ export { WebGLBufferSet, createWebGLBuffers };
@@ -0,0 +1,86 @@
1
+ // WebGL adapter - lightweight utility to create WebGL buffers from core geometry
2
+ function createWebGLBuffers(gl, textGeometry) {
3
+ const { vertices, normals, indices, colors, glyphAttributes } = textGeometry;
4
+ // Create position buffer
5
+ const positionBuffer = gl.createBuffer();
6
+ if (!positionBuffer)
7
+ throw new Error('Failed to create position buffer');
8
+ gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
9
+ gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
10
+ // Create normal buffer
11
+ const normalBuffer = gl.createBuffer();
12
+ if (!normalBuffer)
13
+ throw new Error('Failed to create normal buffer');
14
+ gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
15
+ gl.bufferData(gl.ARRAY_BUFFER, normals, gl.STATIC_DRAW);
16
+ // Create index buffer
17
+ const indexBuffer = gl.createBuffer();
18
+ if (!indexBuffer)
19
+ throw new Error('Failed to create index buffer');
20
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
21
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
22
+ const buffers = {
23
+ position: positionBuffer,
24
+ normal: normalBuffer,
25
+ indices: indexBuffer
26
+ };
27
+ const attributes = {
28
+ position: { size: 3, type: gl.FLOAT, normalized: false },
29
+ normal: { size: 3, type: gl.FLOAT, normalized: false }
30
+ };
31
+ // Optional color buffer
32
+ if (colors) {
33
+ const colorBuffer = gl.createBuffer();
34
+ if (!colorBuffer)
35
+ throw new Error('Failed to create color buffer');
36
+ gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
37
+ gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
38
+ buffers.color = colorBuffer;
39
+ attributes.color = { size: 3, type: gl.FLOAT, normalized: false };
40
+ }
41
+ // Optional glyph attribute buffers
42
+ if (glyphAttributes) {
43
+ const glyphCenterBuffer = gl.createBuffer();
44
+ if (!glyphCenterBuffer)
45
+ throw new Error('Failed to create glyphCenter buffer');
46
+ gl.bindBuffer(gl.ARRAY_BUFFER, glyphCenterBuffer);
47
+ gl.bufferData(gl.ARRAY_BUFFER, glyphAttributes.glyphCenter, gl.STATIC_DRAW);
48
+ buffers.glyphCenter = glyphCenterBuffer;
49
+ attributes.glyphCenter = { size: 3, type: gl.FLOAT, normalized: false };
50
+ const glyphIndexBuffer = gl.createBuffer();
51
+ if (!glyphIndexBuffer)
52
+ throw new Error('Failed to create glyphIndex buffer');
53
+ gl.bindBuffer(gl.ARRAY_BUFFER, glyphIndexBuffer);
54
+ gl.bufferData(gl.ARRAY_BUFFER, glyphAttributes.glyphIndex, gl.STATIC_DRAW);
55
+ buffers.glyphIndex = glyphIndexBuffer;
56
+ attributes.glyphIndex = { size: 1, type: gl.FLOAT, normalized: false };
57
+ const glyphLineIndexBuffer = gl.createBuffer();
58
+ if (!glyphLineIndexBuffer)
59
+ throw new Error('Failed to create glyphLineIndex buffer');
60
+ gl.bindBuffer(gl.ARRAY_BUFFER, glyphLineIndexBuffer);
61
+ gl.bufferData(gl.ARRAY_BUFFER, glyphAttributes.glyphLineIndex, gl.STATIC_DRAW);
62
+ buffers.glyphLineIndex = glyphLineIndexBuffer;
63
+ attributes.glyphLineIndex = { size: 1, type: gl.FLOAT, normalized: false };
64
+ }
65
+ return {
66
+ buffers,
67
+ attributes,
68
+ drawCount: indices.length,
69
+ mode: gl.TRIANGLES,
70
+ dispose() {
71
+ gl.deleteBuffer(positionBuffer);
72
+ gl.deleteBuffer(normalBuffer);
73
+ gl.deleteBuffer(indexBuffer);
74
+ if (buffers.color)
75
+ gl.deleteBuffer(buffers.color);
76
+ if (buffers.glyphCenter)
77
+ gl.deleteBuffer(buffers.glyphCenter);
78
+ if (buffers.glyphIndex)
79
+ gl.deleteBuffer(buffers.glyphIndex);
80
+ if (buffers.glyphLineIndex)
81
+ gl.deleteBuffer(buffers.glyphLineIndex);
82
+ }
83
+ };
84
+ }
85
+
86
+ export { createWebGLBuffers };
@@ -0,0 +1,99 @@
1
+ 'use strict';
2
+
3
+ // WebGPU adapter - lightweight utility to create GPU buffers from core geometry
4
+ function createWebGPUBuffers(device, textGeometry) {
5
+ const { vertices, normals, indices, colors } = textGeometry;
6
+ const vertexCount = indices.length;
7
+ // Interleave position and normal data for better cache coherency
8
+ // Layout: [px, py, pz, nx, ny, nz, px, py, pz, nx, ny, nz, ...]
9
+ const interleavedData = new Float32Array((vertices.length / 3) * 6);
10
+ for (let i = 0; i < vertices.length / 3; i++) {
11
+ const baseIndex = i * 6;
12
+ const vertIndex = i * 3;
13
+ // Position (NO FLIP - pass through)
14
+ interleavedData[baseIndex] = vertices[vertIndex];
15
+ interleavedData[baseIndex + 1] = vertices[vertIndex + 1];
16
+ interleavedData[baseIndex + 2] = vertices[vertIndex + 2];
17
+ // Normal (NO FLIP - pass through)
18
+ interleavedData[baseIndex + 3] = normals[vertIndex];
19
+ interleavedData[baseIndex + 4] = normals[vertIndex + 1];
20
+ interleavedData[baseIndex + 5] = normals[vertIndex + 2];
21
+ }
22
+ // Create vertex buffer with interleaved data
23
+ const vertexBuffer = device.createBuffer({
24
+ size: interleavedData.byteLength,
25
+ usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
26
+ mappedAtCreation: true
27
+ });
28
+ new Float32Array(vertexBuffer.getMappedRange()).set(interleavedData);
29
+ vertexBuffer.unmap();
30
+ // Create index buffer (NO FLIP - pass through)
31
+ const indexBuffer = device.createBuffer({
32
+ size: indices.byteLength,
33
+ usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST,
34
+ mappedAtCreation: true
35
+ });
36
+ new Uint32Array(indexBuffer.getMappedRange()).set(indices);
37
+ indexBuffer.unmap();
38
+ // Vertex buffer layout for interleaved data
39
+ const vertexLayout = {
40
+ arrayStride: 24, // 6 floats * 4 bytes = 24 bytes per vertex
41
+ attributes: [
42
+ {
43
+ shaderLocation: 0,
44
+ offset: 0,
45
+ format: 'float32x3' // position
46
+ },
47
+ {
48
+ shaderLocation: 1,
49
+ offset: 12, // 3 floats * 4 bytes
50
+ format: 'float32x3' // normal
51
+ }
52
+ ]
53
+ };
54
+ const buffers = {
55
+ vertex: vertexBuffer,
56
+ indices: indexBuffer
57
+ };
58
+ const layout = {
59
+ vertex: vertexLayout
60
+ };
61
+ // Optional color buffer
62
+ let colorBuffer;
63
+ let colorLayout;
64
+ if (colors) {
65
+ colorBuffer = device.createBuffer({
66
+ size: colors.byteLength,
67
+ usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
68
+ mappedAtCreation: true
69
+ });
70
+ new Float32Array(colorBuffer.getMappedRange()).set(colors);
71
+ colorBuffer.unmap();
72
+ colorLayout = {
73
+ arrayStride: 12, // 3 floats * 4 bytes
74
+ attributes: [
75
+ {
76
+ shaderLocation: 2,
77
+ offset: 0,
78
+ format: 'float32x3'
79
+ }
80
+ ]
81
+ };
82
+ buffers.color = colorBuffer;
83
+ layout.color = colorLayout;
84
+ }
85
+ return {
86
+ buffers,
87
+ layout,
88
+ indexFormat: 'uint32',
89
+ vertexCount,
90
+ dispose() {
91
+ vertexBuffer.destroy();
92
+ indexBuffer.destroy();
93
+ if (colorBuffer)
94
+ colorBuffer.destroy();
95
+ }
96
+ };
97
+ }
98
+
99
+ exports.createWebGPUBuffers = createWebGPUBuffers;
@@ -0,0 +1,19 @@
1
+ import { TextGeometryInfo } from '../core/types';
2
+
3
+ interface WebGPUBufferSet {
4
+ buffers: {
5
+ vertex: GPUBuffer;
6
+ color?: GPUBuffer;
7
+ indices: GPUBuffer;
8
+ };
9
+ layout: {
10
+ vertex: GPUVertexBufferLayout;
11
+ color?: GPUVertexBufferLayout;
12
+ };
13
+ indexFormat: GPUIndexFormat;
14
+ vertexCount: number;
15
+ dispose(): void;
16
+ }
17
+ declare function createWebGPUBuffers(device: GPUDevice, textGeometry: TextGeometryInfo): WebGPUBufferSet;
18
+
19
+ export { WebGPUBufferSet, createWebGPUBuffers };