meshwriter-cudu 3.0.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.
Files changed (81) hide show
  1. package/LICENSE.md +11 -0
  2. package/README.md +349 -0
  3. package/dist/fonts/comic-sans.d.ts +1105 -0
  4. package/dist/fonts/helvetica.d.ts +1208 -0
  5. package/dist/fonts/hiruko-pro.d.ts +658 -0
  6. package/dist/fonts/jura.d.ts +750 -0
  7. package/dist/fonts/webgl-dings.d.ts +109 -0
  8. package/dist/index.d.ts +295 -0
  9. package/dist/meshwriter.cjs.js +2645 -0
  10. package/dist/meshwriter.cjs.js.map +1 -0
  11. package/dist/meshwriter.esm.js +2606 -0
  12. package/dist/meshwriter.esm.js.map +1 -0
  13. package/dist/meshwriter.min.js +2 -0
  14. package/dist/meshwriter.min.js.map +1 -0
  15. package/dist/meshwriter.umd.js +7146 -0
  16. package/dist/meshwriter.umd.js.map +1 -0
  17. package/dist/src/babylonImports.d.ts +11 -0
  18. package/dist/src/bakedFontLoader.d.ts +43 -0
  19. package/dist/src/colorContrast.d.ts +117 -0
  20. package/dist/src/csg.d.ts +55 -0
  21. package/dist/src/curves.d.ts +20 -0
  22. package/dist/src/fogPlugin.d.ts +32 -0
  23. package/dist/src/fontCompression.d.ts +12 -0
  24. package/dist/src/fontRegistry.d.ts +54 -0
  25. package/dist/src/index.d.ts +47 -0
  26. package/dist/src/letterMesh.d.ts +46 -0
  27. package/dist/src/material.d.ts +34 -0
  28. package/dist/src/meshSplitter.d.ts +10 -0
  29. package/dist/src/meshwriter.d.ts +46 -0
  30. package/dist/src/sps.d.ts +27 -0
  31. package/dist/src/umd-entry.d.ts +3 -0
  32. package/dist/src/utils.d.ts +12 -0
  33. package/dist/src/variableFontCache.d.ts +56 -0
  34. package/dist/src/variableFontConverter.d.ts +21 -0
  35. package/dist/src/variableFontLoader.d.ts +99 -0
  36. package/fonts/Figure1.png +0 -0
  37. package/fonts/LICENSE-OFL.txt +93 -0
  38. package/fonts/README.md +174 -0
  39. package/fonts/atkinson-hyperlegible-next.d.ts +8 -0
  40. package/fonts/atkinson-hyperlegible-next.js +6576 -0
  41. package/fonts/atkinson-hyperlegible.js +3668 -0
  42. package/fonts/baked/atkinson-hyperlegible-next-200.json +1 -0
  43. package/fonts/baked/atkinson-hyperlegible-next-250.json +1 -0
  44. package/fonts/baked/atkinson-hyperlegible-next-300.json +1 -0
  45. package/fonts/baked/atkinson-hyperlegible-next-350.json +1 -0
  46. package/fonts/baked/atkinson-hyperlegible-next-400.json +1 -0
  47. package/fonts/baked/atkinson-hyperlegible-next-450.json +1 -0
  48. package/fonts/baked/atkinson-hyperlegible-next-500.json +1 -0
  49. package/fonts/baked/atkinson-hyperlegible-next-550.json +1 -0
  50. package/fonts/baked/atkinson-hyperlegible-next-600.json +1 -0
  51. package/fonts/baked/atkinson-hyperlegible-next-650.json +1 -0
  52. package/fonts/baked/atkinson-hyperlegible-next-700.json +1 -0
  53. package/fonts/baked/atkinson-hyperlegible-next-750.json +1 -0
  54. package/fonts/baked/atkinson-hyperlegible-next-800.json +1 -0
  55. package/fonts/baked/manifest.json +41 -0
  56. package/fonts/comic-sans.js +1532 -0
  57. package/fonts/helvetica.js +1695 -0
  58. package/fonts/hiruko-pro.js +838 -0
  59. package/fonts/index.js +16 -0
  60. package/fonts/jura.js +994 -0
  61. package/fonts/variable/atkinson-hyperlegible-next-variable.ttf +0 -0
  62. package/fonts/webgl-dings.js +113 -0
  63. package/package.json +76 -0
  64. package/src/babylonImports.js +29 -0
  65. package/src/bakedFontLoader.js +125 -0
  66. package/src/colorContrast.js +528 -0
  67. package/src/csg.js +220 -0
  68. package/src/curves.js +67 -0
  69. package/src/fogPlugin.js +98 -0
  70. package/src/fontCompression.js +141 -0
  71. package/src/fontRegistry.js +98 -0
  72. package/src/globals.d.ts +20 -0
  73. package/src/index.js +136 -0
  74. package/src/letterMesh.js +417 -0
  75. package/src/material.js +103 -0
  76. package/src/meshSplitter.js +337 -0
  77. package/src/meshwriter.js +303 -0
  78. package/src/sps.js +106 -0
  79. package/src/types.d.ts +551 -0
  80. package/src/umd-entry.js +130 -0
  81. package/src/utils.js +57 -0
package/LICENSE.md ADDED
@@ -0,0 +1,11 @@
1
+ Copyright (c) 2018-2023 Brian Button
2
+ Copyright (c) 2024-2025 Cullen Dudas
3
+
4
+ Originally adapted to BABYLON.js by Brian Button
5
+ Additional modifications by Cullen Dudas
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8
+
9
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,349 @@
1
+ # meshwriter-cudu
2
+
3
+ Modern 3D text rendering for Babylon.js 8+ with ES modules, variable font weights, and accessibility features.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/meshwriter-cudu.svg)](https://www.npmjs.com/package/meshwriter-cudu)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## Features
9
+
10
+ - **Babylon.js 6-8+ support** with async/sync APIs for CSG2 compatibility
11
+ - **ES modules** with full tree-shaking support
12
+ - **Variable font weights** via build-time baking for personalized typography
13
+ - **Dyslexia-friendly fonts** including Atkinson Hyperlegible Next with kerning
14
+ - **TypeScript declarations** included
15
+ - **WCAG color contrast utilities** for accessible text rendering
16
+ - **Fog support** for emissive text via custom material plugin
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install meshwriter-cudu
22
+ ```
23
+
24
+ **Peer dependencies:**
25
+ ```bash
26
+ npm install @babylonjs/core earcut
27
+ ```
28
+
29
+ ## Quick Start
30
+
31
+ ```javascript
32
+ import { MeshWriter, registerFont } from 'meshwriter-cudu';
33
+ import helvetica from 'meshwriter-cudu/fonts/helvetica';
34
+
35
+ // Register a font
36
+ registerFont('Helvetica', helvetica);
37
+
38
+ // Create writer (async for Babylon 8+)
39
+ const Writer = await MeshWriter.createAsync(scene);
40
+
41
+ // Create 3D text
42
+ const text = new Writer("Hello World", {
43
+ 'font-family': 'Helvetica',
44
+ 'letter-height': 50,
45
+ 'letter-thickness': 5,
46
+ color: '#1C3870'
47
+ });
48
+
49
+ // Get the mesh for manipulation
50
+ const mesh = text.getMesh();
51
+ ```
52
+
53
+ ## Babylon.js Version Compatibility
54
+
55
+ | Babylon Version | API | Notes |
56
+ |-----------------|-----|-------|
57
+ | 6.x - 7.30 | `MeshWriter.create(scene, prefs)` | Sync, uses legacy CSG |
58
+ | 7.31+ / 8.x | `await MeshWriter.createAsync(scene, prefs)` | Async, uses CSG2 |
59
+
60
+ **Recommendation:** Use `createAsync` for all new projects. It handles CSG initialization automatically and works across all supported Babylon versions.
61
+
62
+ ## API Reference
63
+
64
+ ### Font Registration
65
+
66
+ ```javascript
67
+ import { registerFont, registerFontAliases, isFontRegistered, getRegisteredFonts } from 'meshwriter-cudu';
68
+
69
+ // Register font
70
+ registerFont('MyFont', fontSpec);
71
+
72
+ // Create aliases for the same font
73
+ registerFontAliases('MyFont', 'myfont', 'my-font');
74
+
75
+ // Check registration
76
+ isFontRegistered('MyFont'); // true
77
+ getRegisteredFonts(); // ['MyFont', 'myfont', 'my-font', ...]
78
+ ```
79
+
80
+ ### Text Creation Options
81
+
82
+ ```javascript
83
+ new Writer("Text", {
84
+ // Positioning
85
+ position: { x: 0, y: 0, z: 0 },
86
+ anchor: 'left' | 'center' | 'right',
87
+
88
+ // Sizing
89
+ 'letter-height': 50, // Height in world units
90
+ 'letter-thickness': 5, // Depth/extrusion
91
+
92
+ // Appearance
93
+ color: '#FF0000', // Emissive color (hex)
94
+ alpha: 1.0, // Transparency (0-1)
95
+ 'emissive-only': false, // Disable lighting (self-lit)
96
+ 'fog-enabled': true, // Affected by scene fog
97
+
98
+ // Material colors (advanced)
99
+ colors: {
100
+ diffuse: '#FFFFFF',
101
+ specular: '#FFFFFF',
102
+ ambient: '#000000',
103
+ emissive: '#FF0000'
104
+ },
105
+
106
+ // Font
107
+ 'font-family': 'Helvetica'
108
+ });
109
+ ```
110
+
111
+ ### Instance Methods
112
+
113
+ ```javascript
114
+ const text = new Writer("Hello");
115
+
116
+ // Get meshes
117
+ text.getMesh(); // Combined mesh
118
+ text.getSPS(); // SolidParticleSystem
119
+ text.getMaterial(); // StandardMaterial
120
+
121
+ // Appearance
122
+ text.setColor('#00FF00'); // Change color
123
+ text.setAlpha(0.5); // Change transparency
124
+ text.color('#00FF00'); // Get/set color
125
+ text.alpha(0.5); // Get/set alpha
126
+
127
+ // Layout info
128
+ text.getLetterCenter(0); // Center of first letter
129
+ text.getLettersBoxes(); // Bounding boxes
130
+ text.getLettersOrigins(); // Origin positions per letter
131
+ text.getOffsetX(); // Anchor offset
132
+
133
+ // Cleanup
134
+ text.dispose();
135
+ text.isDisposed();
136
+ ```
137
+
138
+ ### Static Methods
139
+
140
+ ```javascript
141
+ MeshWriter.isReady(); // Check if CSG is initialized
142
+ MeshWriter.getCSGVersion(); // Returns 'CSG2', 'CSG', or null
143
+ MeshWriter.setCSGInitializer(fn); // Custom CSG2 initializer
144
+ MeshWriter.setCSGReadyCheck(fn); // Custom readiness check
145
+ MeshWriter.onCSGReady(callback); // Run code when CSG is ready
146
+ MeshWriter.markCSGReady(); // Manually flag CSG ready
147
+ ```
148
+
149
+ ## Available Fonts
150
+
151
+ | Font | Import Path | Notes |
152
+ |------|-------------|-------|
153
+ | Helvetica | `meshwriter-cudu/fonts/helvetica` | Classic sans-serif |
154
+ | Comic Sans | `meshwriter-cudu/fonts/comic-sans` | Display font |
155
+ | Jura | `meshwriter-cudu/fonts/jura` | Modern geometric |
156
+ | Hiruko Pro | `meshwriter-cudu/fonts/hiruko-pro` | Japanese-compatible |
157
+ | WebGL Dings | `meshwriter-cudu/fonts/webgl-dings` | Symbols |
158
+ | Atkinson Hyperlegible | `meshwriter-cudu/fonts/atkinson-hyperlegible` | Dyslexia-friendly |
159
+ | Atkinson Hyperlegible Next | `meshwriter-cudu/fonts/atkinson-hyperlegible-next` | Enhanced with kerning |
160
+
161
+ ```javascript
162
+ import helvetica from 'meshwriter-cudu/fonts/helvetica';
163
+ import atkinson from 'meshwriter-cudu/fonts/atkinson-hyperlegible-next';
164
+
165
+ registerFont('Helvetica', helvetica);
166
+ registerFont('Atkinson', atkinson);
167
+ ```
168
+
169
+ ## Variable Font Weights
170
+
171
+ MeshWriter supports variable font weights for accessibility applications, allowing users to select their preferred font weight for improved readability.
172
+
173
+ ### Pre-baked Weights (Recommended)
174
+
175
+ Generate FontSpec JSON files at build time for zero runtime overhead:
176
+
177
+ #### 1. Bake fonts during build
178
+
179
+ ```bash
180
+ # Default: weights 200-800 in steps of 50, ASCII keyboard characters
181
+ npm run bake:fonts
182
+
183
+ # Custom weights
184
+ npm run bake:fonts -- --weights=350,400,425,450,500
185
+
186
+ # Custom charset (smaller files)
187
+ npm run bake:fonts -- --charset="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 .!?"
188
+
189
+ # Different font
190
+ npm run bake:fonts -- --font=./path/to/variable-font.ttf
191
+ ```
192
+
193
+ #### 2. Load at runtime
194
+
195
+ ```javascript
196
+ import { loadBakedFont, findNearestWeight, registerFont, MeshWriter } from 'meshwriter-cudu';
197
+
198
+ // Available weights from your bake step
199
+ const availableWeights = [350, 400, 425, 450, 500];
200
+
201
+ // Find nearest to user's preferred weight
202
+ const userWeight = 415; // e.g., from user profile
203
+ const nearest = findNearestWeight(userWeight, availableWeights);
204
+
205
+ // Load just the one weight file (~45KB)
206
+ const fontSpec = await loadBakedFont(`/fonts/baked/atkinson-hyperlegible-next-${nearest}.json`);
207
+ registerFont('Atkinson', fontSpec);
208
+
209
+ // Create text
210
+ const Writer = await MeshWriter.createAsync(scene);
211
+ const text = new Writer("Hello!", {
212
+ 'font-family': 'Atkinson',
213
+ 'letter-height': 50
214
+ });
215
+ ```
216
+
217
+ ### Bake Script Options
218
+
219
+ | Option | Description | Default |
220
+ |--------|-------------|---------|
221
+ | `--font=PATH` | Variable font file (.ttf) | `./fonts/variable/atkinson-hyperlegible-next-variable.ttf` |
222
+ | `--weights=N,N,N` | Comma-separated weights | `200,250,300,...,800` (13 weights) |
223
+ | `--charset=CHARS` | Characters to include | ASCII 32-126 (95 chars) |
224
+ | `--output=DIR` | Output directory | `./fonts/baked` |
225
+
226
+ ### Using the Manifest
227
+
228
+ ```javascript
229
+ import { loadBakedFontsFromManifest, getBakedFontManifest } from 'meshwriter-cudu';
230
+
231
+ // Get available weights without loading fonts
232
+ const manifest = await getBakedFontManifest('/fonts/baked/manifest.json');
233
+ console.log(manifest.weights); // [200, 250, 300, ...]
234
+
235
+ // Load specific weights
236
+ const fonts = await loadBakedFontsFromManifest('/fonts/baked/manifest.json', [400, 450]);
237
+ const fontSpec = fonts.get(400);
238
+ ```
239
+
240
+ ## Advanced Features
241
+
242
+ ### Color Contrast Utilities
243
+
244
+ WCAG 2.1 compliant color utilities for accessible text:
245
+
246
+ ```javascript
247
+ import { deriveEdgeColors, adjustForContrast, CONTRAST_LEVELS } from 'meshwriter-cudu';
248
+
249
+ // Auto-generate high-contrast edge colors
250
+ const colors = deriveEdgeColors('#FF6600', CONTRAST_LEVELS.AA_NORMAL);
251
+ // { diffuse: '...', ambient: '...', emissive: '...' }
252
+
253
+ // Adjust existing colors to meet contrast requirements
254
+ const adjusted = adjustForContrast(
255
+ { emissive: '#FF6600', diffuse: '#333333' },
256
+ { targetContrast: 4.5 }
257
+ );
258
+ ```
259
+
260
+ ### Custom CSG Initialization
261
+
262
+ For bundled environments where globals may be tree-shaken:
263
+
264
+ ```javascript
265
+ import { MeshWriter, registerFont } from 'meshwriter-cudu';
266
+ import { InitializeCSG2Async, IsCSG2Ready } from "@babylonjs/core/Meshes/csg2";
267
+ import helvetica from 'meshwriter-cudu/fonts/helvetica';
268
+
269
+ registerFont('Helvetica', helvetica);
270
+
271
+ // Configure custom CSG handling
272
+ MeshWriter.setCSGInitializer(() => InitializeCSG2Async());
273
+ MeshWriter.setCSGReadyCheck(() => IsCSG2Ready());
274
+
275
+ const Writer = await MeshWriter.createAsync(scene, { scale: 1 });
276
+ ```
277
+
278
+ ### Fog Support for Emissive Text
279
+
280
+ By default, Babylon.js fog doesn't affect emissive materials. MeshWriter includes a material plugin to fix this:
281
+
282
+ ```javascript
283
+ const text = new Writer("Foggy Text", {
284
+ 'font-family': 'Helvetica',
285
+ 'letter-height': 50,
286
+ 'emissive-only': true, // Self-lit text
287
+ 'fog-enabled': true // Respects scene fog
288
+ });
289
+ ```
290
+
291
+ ## UMD Bundle (Script Tag)
292
+
293
+ For non-bundler environments:
294
+
295
+ ```html
296
+ <script src="https://cdn.babylonjs.com/babylon.js"></script>
297
+ <script src="https://unpkg.com/earcut@3.0.2/dist/earcut.min.js"></script>
298
+ <script src="path/to/meshwriter.min.js"></script>
299
+ <script>
300
+ const Writer = await BABYLON.MeshWriter.createAsync(scene, { scale: 1 });
301
+ const text = new Writer("Hello", { "letter-height": 50 });
302
+ </script>
303
+ ```
304
+
305
+ ## Building from Source
306
+
307
+ ```bash
308
+ # Install dependencies
309
+ npm install
310
+
311
+ # Build all formats (ESM, CJS, UMD)
312
+ npm run build
313
+
314
+ # Build and watch
315
+ npm run dev
316
+
317
+ # Bake variable font weights
318
+ npm run bake:fonts
319
+
320
+ # Type check
321
+ npm run typecheck
322
+ ```
323
+
324
+ ### Output Formats
325
+
326
+ - `dist/meshwriter.esm.js` - ES modules (tree-shakeable)
327
+ - `dist/meshwriter.cjs.js` - CommonJS (Node.js)
328
+ - `dist/meshwriter.umd.js` - UMD (script tags)
329
+ - `dist/meshwriter.min.js` - Minified UMD
330
+
331
+ ## Acknowledgments
332
+
333
+ This project is a fork of [meshwriter](https://github.com/briantbutton/meshwriter) by **Brian T Button**. The original library pioneered 3D text rendering in Babylon.js and remains the foundation of this work.
334
+
335
+ **What this fork adds:**
336
+ - ES module support with tree-shaking
337
+ - Babylon.js 8+ compatibility with async CSG2 initialization
338
+ - Variable font weight support via build-time baking
339
+ - Dyslexia-friendly fonts (Atkinson Hyperlegible Next) with kerning
340
+ - TypeScript declarations
341
+ - WCAG color contrast utilities
342
+ - Fog plugin for emissive text
343
+ - Improved hole rendering for characters like 8, B, etc.
344
+
345
+ Thank you to Brian T Button for creating and maintaining the original meshwriter library.
346
+
347
+ ## License
348
+
349
+ MIT - See [LICENSE](LICENSE) file for details.