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.
- package/LICENSE.md +11 -0
- package/README.md +349 -0
- package/dist/fonts/comic-sans.d.ts +1105 -0
- package/dist/fonts/helvetica.d.ts +1208 -0
- package/dist/fonts/hiruko-pro.d.ts +658 -0
- package/dist/fonts/jura.d.ts +750 -0
- package/dist/fonts/webgl-dings.d.ts +109 -0
- package/dist/index.d.ts +295 -0
- package/dist/meshwriter.cjs.js +2645 -0
- package/dist/meshwriter.cjs.js.map +1 -0
- package/dist/meshwriter.esm.js +2606 -0
- package/dist/meshwriter.esm.js.map +1 -0
- package/dist/meshwriter.min.js +2 -0
- package/dist/meshwriter.min.js.map +1 -0
- package/dist/meshwriter.umd.js +7146 -0
- package/dist/meshwriter.umd.js.map +1 -0
- package/dist/src/babylonImports.d.ts +11 -0
- package/dist/src/bakedFontLoader.d.ts +43 -0
- package/dist/src/colorContrast.d.ts +117 -0
- package/dist/src/csg.d.ts +55 -0
- package/dist/src/curves.d.ts +20 -0
- package/dist/src/fogPlugin.d.ts +32 -0
- package/dist/src/fontCompression.d.ts +12 -0
- package/dist/src/fontRegistry.d.ts +54 -0
- package/dist/src/index.d.ts +47 -0
- package/dist/src/letterMesh.d.ts +46 -0
- package/dist/src/material.d.ts +34 -0
- package/dist/src/meshSplitter.d.ts +10 -0
- package/dist/src/meshwriter.d.ts +46 -0
- package/dist/src/sps.d.ts +27 -0
- package/dist/src/umd-entry.d.ts +3 -0
- package/dist/src/utils.d.ts +12 -0
- package/dist/src/variableFontCache.d.ts +56 -0
- package/dist/src/variableFontConverter.d.ts +21 -0
- package/dist/src/variableFontLoader.d.ts +99 -0
- package/fonts/Figure1.png +0 -0
- package/fonts/LICENSE-OFL.txt +93 -0
- package/fonts/README.md +174 -0
- package/fonts/atkinson-hyperlegible-next.d.ts +8 -0
- package/fonts/atkinson-hyperlegible-next.js +6576 -0
- package/fonts/atkinson-hyperlegible.js +3668 -0
- package/fonts/baked/atkinson-hyperlegible-next-200.json +1 -0
- package/fonts/baked/atkinson-hyperlegible-next-250.json +1 -0
- package/fonts/baked/atkinson-hyperlegible-next-300.json +1 -0
- package/fonts/baked/atkinson-hyperlegible-next-350.json +1 -0
- package/fonts/baked/atkinson-hyperlegible-next-400.json +1 -0
- package/fonts/baked/atkinson-hyperlegible-next-450.json +1 -0
- package/fonts/baked/atkinson-hyperlegible-next-500.json +1 -0
- package/fonts/baked/atkinson-hyperlegible-next-550.json +1 -0
- package/fonts/baked/atkinson-hyperlegible-next-600.json +1 -0
- package/fonts/baked/atkinson-hyperlegible-next-650.json +1 -0
- package/fonts/baked/atkinson-hyperlegible-next-700.json +1 -0
- package/fonts/baked/atkinson-hyperlegible-next-750.json +1 -0
- package/fonts/baked/atkinson-hyperlegible-next-800.json +1 -0
- package/fonts/baked/manifest.json +41 -0
- package/fonts/comic-sans.js +1532 -0
- package/fonts/helvetica.js +1695 -0
- package/fonts/hiruko-pro.js +838 -0
- package/fonts/index.js +16 -0
- package/fonts/jura.js +994 -0
- package/fonts/variable/atkinson-hyperlegible-next-variable.ttf +0 -0
- package/fonts/webgl-dings.js +113 -0
- package/package.json +76 -0
- package/src/babylonImports.js +29 -0
- package/src/bakedFontLoader.js +125 -0
- package/src/colorContrast.js +528 -0
- package/src/csg.js +220 -0
- package/src/curves.js +67 -0
- package/src/fogPlugin.js +98 -0
- package/src/fontCompression.js +141 -0
- package/src/fontRegistry.js +98 -0
- package/src/globals.d.ts +20 -0
- package/src/index.js +136 -0
- package/src/letterMesh.js +417 -0
- package/src/material.js +103 -0
- package/src/meshSplitter.js +337 -0
- package/src/meshwriter.js +303 -0
- package/src/sps.js +106 -0
- package/src/types.d.ts +551 -0
- package/src/umd-entry.js +130 -0
- package/src/utils.js +57 -0
|
Binary file
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webgl-dings Font for MeshWriter
|
|
3
|
+
* Pre-initialized FontSpec format
|
|
4
|
+
* @type {import("../src/types").FontSpec}
|
|
5
|
+
*/
|
|
6
|
+
export default {
|
|
7
|
+
reverseHoles: false,
|
|
8
|
+
reverseShapes: true,
|
|
9
|
+
"4": {
|
|
10
|
+
sC: [],
|
|
11
|
+
xMin: 24,
|
|
12
|
+
xMax: 522,
|
|
13
|
+
yMin: 0,
|
|
14
|
+
yMax: 700,
|
|
15
|
+
wdth: 556
|
|
16
|
+
},
|
|
17
|
+
"5": {
|
|
18
|
+
sC: [],
|
|
19
|
+
xMin: 34,
|
|
20
|
+
xMax: 522,
|
|
21
|
+
yMin: -14,
|
|
22
|
+
yMax: 700,
|
|
23
|
+
wdth: 556
|
|
24
|
+
},
|
|
25
|
+
"A": {
|
|
26
|
+
sC: [],
|
|
27
|
+
xMin: -7,
|
|
28
|
+
xMax: 675,
|
|
29
|
+
yMin: 0,
|
|
30
|
+
yMax: 714,
|
|
31
|
+
wdth: 667
|
|
32
|
+
},
|
|
33
|
+
"B": {
|
|
34
|
+
sC: [],
|
|
35
|
+
xMin: 76,
|
|
36
|
+
xMax: 667,
|
|
37
|
+
yMin: 0,
|
|
38
|
+
yMax: 714,
|
|
39
|
+
wdth: 704
|
|
40
|
+
},
|
|
41
|
+
"X": {
|
|
42
|
+
sC: [],
|
|
43
|
+
xMin: -3,
|
|
44
|
+
xMax: 651,
|
|
45
|
+
yMin: 0,
|
|
46
|
+
yMax: 714,
|
|
47
|
+
wdth: 648
|
|
48
|
+
},
|
|
49
|
+
"Y": {
|
|
50
|
+
sC: [],
|
|
51
|
+
xMin: -6,
|
|
52
|
+
xMax: 654,
|
|
53
|
+
yMin: 0,
|
|
54
|
+
yMax: 714,
|
|
55
|
+
wdth: 648
|
|
56
|
+
},
|
|
57
|
+
"Z": {
|
|
58
|
+
sC: [],
|
|
59
|
+
xMin: 23,
|
|
60
|
+
xMax: 976.5,
|
|
61
|
+
yMin: -139.5,
|
|
62
|
+
yMax: 812,
|
|
63
|
+
wdth: 999.5
|
|
64
|
+
},
|
|
65
|
+
"a": {
|
|
66
|
+
sC: [],
|
|
67
|
+
xMin: -340,
|
|
68
|
+
xMax: 340,
|
|
69
|
+
yMin: 47,
|
|
70
|
+
yMax: 806,
|
|
71
|
+
wdth: 700
|
|
72
|
+
},
|
|
73
|
+
"\u00e1": {
|
|
74
|
+
sC: [],
|
|
75
|
+
xMin: 20,
|
|
76
|
+
xMax: 950,
|
|
77
|
+
yMin: -145.6,
|
|
78
|
+
yMax: 894.4,
|
|
79
|
+
wdth: 950
|
|
80
|
+
},
|
|
81
|
+
"b": {
|
|
82
|
+
sC: [],
|
|
83
|
+
xMin: 63,
|
|
84
|
+
xMax: 575,
|
|
85
|
+
yMin: -14,
|
|
86
|
+
yMax: 714,
|
|
87
|
+
wdth: 611
|
|
88
|
+
},
|
|
89
|
+
"c": {
|
|
90
|
+
sC: [],
|
|
91
|
+
xMin: 35,
|
|
92
|
+
xMax: 523,
|
|
93
|
+
yMin: -14,
|
|
94
|
+
yMax: 531,
|
|
95
|
+
wdth: 556
|
|
96
|
+
},
|
|
97
|
+
"\u00a0": {
|
|
98
|
+
sC: [],
|
|
99
|
+
xMin: 31,
|
|
100
|
+
xMax: 400,
|
|
101
|
+
yMin: -4,
|
|
102
|
+
yMax: 644,
|
|
103
|
+
wdth: 278
|
|
104
|
+
},
|
|
105
|
+
" ": {
|
|
106
|
+
sC: [],
|
|
107
|
+
xMin: 31,
|
|
108
|
+
xMax: 400,
|
|
109
|
+
yMin: -4,
|
|
110
|
+
yMax: 644,
|
|
111
|
+
wdth: 278
|
|
112
|
+
}
|
|
113
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "meshwriter-cudu",
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "Modern 3D text rendering for Babylon.js with variable font weights and accessibility features",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/meshwriter.cjs.js",
|
|
7
|
+
"module": "./dist/meshwriter.esm.js",
|
|
8
|
+
"types": "./src/types.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/meshwriter.esm.js",
|
|
12
|
+
"require": "./dist/meshwriter.cjs.js",
|
|
13
|
+
"types": "./src/types.d.ts"
|
|
14
|
+
},
|
|
15
|
+
"./fonts/*": "./fonts/*.js",
|
|
16
|
+
"./fonts": "./fonts/index.js"
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
20
|
+
"build:rollup": "rollup -c",
|
|
21
|
+
"build:types": "tsc",
|
|
22
|
+
"build": "npm run build:rollup && npm run build:types",
|
|
23
|
+
"typecheck": "tsc --noEmit",
|
|
24
|
+
"dev": "rollup -c -w",
|
|
25
|
+
"bake:fonts": "node scripts/bake-fonts.js"
|
|
26
|
+
},
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/cududa/meshwriter-cudu"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"babylonjs",
|
|
33
|
+
"babylon",
|
|
34
|
+
"meshwriter",
|
|
35
|
+
"3d-text",
|
|
36
|
+
"webgl",
|
|
37
|
+
"accessibility",
|
|
38
|
+
"dyslexia",
|
|
39
|
+
"variable-font",
|
|
40
|
+
"typescript",
|
|
41
|
+
"esm"
|
|
42
|
+
],
|
|
43
|
+
"authors": ["Brian T Button","Cullen Dudas"],
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"@babylonjs/core": ">=6.0.0",
|
|
47
|
+
"earcut": ">=2.0.0"
|
|
48
|
+
},
|
|
49
|
+
"peerDependenciesMeta": {
|
|
50
|
+
"@babylonjs/core": {
|
|
51
|
+
"optional": false
|
|
52
|
+
},
|
|
53
|
+
"earcut": {
|
|
54
|
+
"optional": false
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@babylonjs/core": "^8.0.0",
|
|
59
|
+
"@rollup/plugin-commonjs": "^28.0.0",
|
|
60
|
+
"@rollup/plugin-node-resolve": "^16.0.0",
|
|
61
|
+
"@rollup/plugin-terser": "^0.4.0",
|
|
62
|
+
"earcut": "^3.0.2",
|
|
63
|
+
"fontkit": "^2.0.4",
|
|
64
|
+
"rollup": "^4.0.0",
|
|
65
|
+
"typescript": "^5.0.0"
|
|
66
|
+
},
|
|
67
|
+
"files": [
|
|
68
|
+
"dist",
|
|
69
|
+
"fonts",
|
|
70
|
+
"src"
|
|
71
|
+
],
|
|
72
|
+
"bugs": {
|
|
73
|
+
"url": "https://github.com/cududa/meshwriter-cudu/issues"
|
|
74
|
+
},
|
|
75
|
+
"homepage": "https://github.com/cududa/meshwriter-cudu#readme"
|
|
76
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MeshWriter Babylon.js Imports
|
|
3
|
+
* Centralized imports from @babylonjs/core for tree-shaking
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Core math types
|
|
7
|
+
export { Vector2, Vector3 } from '@babylonjs/core/Maths/math.vector';
|
|
8
|
+
export { Color3 } from '@babylonjs/core/Maths/math.color';
|
|
9
|
+
export { Path2, Curve3 } from '@babylonjs/core/Maths/math.path';
|
|
10
|
+
|
|
11
|
+
// Mesh types
|
|
12
|
+
export { Mesh } from '@babylonjs/core/Meshes/mesh';
|
|
13
|
+
export { VertexData } from '@babylonjs/core/Meshes/mesh.vertexData';
|
|
14
|
+
export { PolygonMeshBuilder } from '@babylonjs/core/Meshes/polygonMesh';
|
|
15
|
+
|
|
16
|
+
// Materials
|
|
17
|
+
export { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial';
|
|
18
|
+
export { MaterialPluginBase } from '@babylonjs/core/Materials/materialPluginBase';
|
|
19
|
+
|
|
20
|
+
// Particle system
|
|
21
|
+
export { SolidParticleSystem } from '@babylonjs/core/Particles/solidParticleSystem';
|
|
22
|
+
|
|
23
|
+
// CSG - legacy (Babylon < 7.31)
|
|
24
|
+
export { CSG } from '@babylonjs/core/Meshes/csg';
|
|
25
|
+
|
|
26
|
+
// CSG2 - modern (Babylon 7.31+)
|
|
27
|
+
// Import directly - will be available in Babylon 7.31+
|
|
28
|
+
// For older versions, these will be undefined but that's handled in csg.js
|
|
29
|
+
export { CSG2, InitializeCSG2Async, IsCSG2Ready } from '@babylonjs/core/Meshes/csg2';
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MeshWriter Baked Font Loader
|
|
3
|
+
* Loads pre-baked FontSpec JSON files at runtime.
|
|
4
|
+
* Zero dependencies - just fetch and use.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Load a pre-baked font from a JSON file
|
|
9
|
+
* @param {string} url - URL to the baked FontSpec JSON file
|
|
10
|
+
* @returns {Promise<object>} - FontSpec object ready for use with MeshWriter
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* const fontSpec = await loadBakedFont('/fonts/baked/atkinson-hyperlegible-next-400.json');
|
|
14
|
+
* registerFont('Atkinson400', fontSpec);
|
|
15
|
+
*/
|
|
16
|
+
export async function loadBakedFont(url) {
|
|
17
|
+
const response = await fetch(url);
|
|
18
|
+
|
|
19
|
+
if (!response.ok) {
|
|
20
|
+
throw new Error(`MeshWriter: Failed to load baked font from ${url} (HTTP ${response.status})`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const fontSpec = await response.json();
|
|
24
|
+
|
|
25
|
+
// Validate it looks like a FontSpec
|
|
26
|
+
if (typeof fontSpec !== 'object' || fontSpec === null) {
|
|
27
|
+
throw new Error(`MeshWriter: Invalid baked font data from ${url}`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return fontSpec;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Load multiple pre-baked weights from a manifest
|
|
35
|
+
* @param {string} manifestUrl - URL to the manifest.json file
|
|
36
|
+
* @param {number[]} [weights] - Specific weights to load (loads all if omitted)
|
|
37
|
+
* @returns {Promise<Map<number, object>>} - Map of weight -> FontSpec
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* const fonts = await loadBakedFontsFromManifest('/fonts/baked/manifest.json', [400, 450]);
|
|
41
|
+
* const fontSpec = fonts.get(400);
|
|
42
|
+
*/
|
|
43
|
+
export async function loadBakedFontsFromManifest(manifestUrl, weights) {
|
|
44
|
+
const response = await fetch(manifestUrl);
|
|
45
|
+
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
throw new Error(`MeshWriter: Failed to load manifest from ${manifestUrl} (HTTP ${response.status})`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const manifest = await response.json();
|
|
51
|
+
const baseUrl = manifestUrl.substring(0, manifestUrl.lastIndexOf('/') + 1);
|
|
52
|
+
|
|
53
|
+
// Determine which weights to load
|
|
54
|
+
const weightsToLoad = weights
|
|
55
|
+
? weights.filter(w => manifest.weights.includes(w))
|
|
56
|
+
: manifest.weights;
|
|
57
|
+
|
|
58
|
+
if (weights && weightsToLoad.length !== weights.length) {
|
|
59
|
+
const missing = weights.filter(w => !manifest.weights.includes(w));
|
|
60
|
+
console.warn(`MeshWriter: Requested weights not available: ${missing.join(', ')}`);
|
|
61
|
+
console.warn(`MeshWriter: Available weights: ${manifest.weights.join(', ')}`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Load all requested weights in parallel
|
|
65
|
+
const results = await Promise.all(
|
|
66
|
+
weightsToLoad.map(async (weight) => {
|
|
67
|
+
const idx = manifest.weights.indexOf(weight);
|
|
68
|
+
const file = manifest.files[idx];
|
|
69
|
+
const fontSpec = await loadBakedFont(baseUrl + file);
|
|
70
|
+
return { weight, fontSpec };
|
|
71
|
+
})
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
// Build map
|
|
75
|
+
const fontMap = new Map();
|
|
76
|
+
for (const { weight, fontSpec } of results) {
|
|
77
|
+
fontMap.set(weight, fontSpec);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return fontMap;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Find the nearest available weight from a set of baked weights
|
|
85
|
+
* @param {number} targetWeight - Desired weight
|
|
86
|
+
* @param {number[]} availableWeights - Array of available weights
|
|
87
|
+
* @returns {number} - Nearest available weight
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* const nearest = findNearestWeight(425, [400, 450, 500]);
|
|
91
|
+
* // Returns 450 (closest to 425)
|
|
92
|
+
*/
|
|
93
|
+
export function findNearestWeight(targetWeight, availableWeights) {
|
|
94
|
+
if (!availableWeights || availableWeights.length === 0) {
|
|
95
|
+
throw new Error('MeshWriter: No available weights provided');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
let nearest = availableWeights[0];
|
|
99
|
+
let minDiff = Math.abs(targetWeight - nearest);
|
|
100
|
+
|
|
101
|
+
for (const weight of availableWeights) {
|
|
102
|
+
const diff = Math.abs(targetWeight - weight);
|
|
103
|
+
if (diff < minDiff) {
|
|
104
|
+
minDiff = diff;
|
|
105
|
+
nearest = weight;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return nearest;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Get manifest info without loading fonts
|
|
114
|
+
* @param {string} manifestUrl - URL to the manifest.json file
|
|
115
|
+
* @returns {Promise<object>} - Manifest object with fontName, weights, etc.
|
|
116
|
+
*/
|
|
117
|
+
export async function getBakedFontManifest(manifestUrl) {
|
|
118
|
+
const response = await fetch(manifestUrl);
|
|
119
|
+
|
|
120
|
+
if (!response.ok) {
|
|
121
|
+
throw new Error(`MeshWriter: Failed to load manifest from ${manifestUrl} (HTTP ${response.status})`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return response.json();
|
|
125
|
+
}
|