@dice-o-rolla/dice-renderer-three 0.4.0 → 0.5.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/README.md +7 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/mesh-factory.d.ts +6 -3
- package/dist/mesh-factory.js +46 -9
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -13,6 +13,13 @@ KTX2 capability detection and GPU-backed asset setup available in perspective an
|
|
|
13
13
|
Their common theme, resizing, framebuffer-limit, antialiasing, and material options are exported as
|
|
14
14
|
`ThreeRendererOptions`; top-down options only extend that contract with camera and tray framing.
|
|
15
15
|
|
|
16
|
+
A material provider may implement `getSurfaceUvs(definition, preset)` to return a complete
|
|
17
|
+
`SurfaceUvMap` keyed by physical face value. Coordinates follow each face's vertex order. The
|
|
18
|
+
mesh factory validates them before allocation and writes them to `uv1`, preserving the original
|
|
19
|
+
`uv` channel for labels. Assign `texture.channel = 1` for maps that use the surface unwrap.
|
|
20
|
+
`createPolyhedronGeometry(definition, scale, surfaceUvs)` also accepts the map directly;
|
|
21
|
+
`validateSurfaceUvs` is available for early validation. Omitting the map preserves existing UVs.
|
|
22
|
+
|
|
16
23
|
Most browser applications should use the preassembled entry point from
|
|
17
24
|
`@dice-o-rolla/dice-engine/browser`.
|
|
18
25
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { ThreeMaterialFactory, type DiceMaterialStyle, type FaceLabel, type FaceMaterialOptions, } from './material-factory.js';
|
|
2
|
-
export { createPolyhedronGeometry, createFaceUvs, DEFAULT_THREE_THEME, getFaceLabel, ThreeDiceMeshFactory, type ThreeDiceMesh, type FaceMaterialContext, type FaceMaterialResource, type ThreeFaceMaterialProvider, } from './mesh-factory.js';
|
|
2
|
+
export { createPolyhedronGeometry, validateSurfaceUvs, type SurfaceUvMap, type Vector2Tuple, createFaceUvs, DEFAULT_THREE_THEME, getFaceLabel, ThreeDiceMeshFactory, type ThreeDiceMesh, type FaceMaterialContext, type FaceMaterialResource, type ThreeFaceMaterialProvider, } from './mesh-factory.js';
|
|
3
3
|
export type { ThreeRendererOptions } from './renderer-options.js';
|
|
4
4
|
export { ThreeCamera, ThreeLighting, ThreeScene } from './scene.js';
|
|
5
5
|
export { TopDownCamera, type TopDownCameraOptions } from './top-down-camera.js';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { ThreeMaterialFactory, } from './material-factory.js';
|
|
2
|
-
export { createPolyhedronGeometry, createFaceUvs, DEFAULT_THREE_THEME, getFaceLabel, ThreeDiceMeshFactory, } from './mesh-factory.js';
|
|
2
|
+
export { createPolyhedronGeometry, validateSurfaceUvs, createFaceUvs, DEFAULT_THREE_THEME, getFaceLabel, ThreeDiceMeshFactory, } from './mesh-factory.js';
|
|
3
3
|
export { ThreeCamera, ThreeLighting, ThreeScene } from './scene.js';
|
|
4
4
|
export { TopDownCamera } from './top-down-camera.js';
|
|
5
5
|
export { TopDownDiceRenderer } from './top-down-dice-renderer.js';
|
package/dist/mesh-factory.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { PolygonDefinition, PolyhedronDefinition } from '@dice-o-rolla/dice-geometry';
|
|
2
2
|
import type { RendererTheme, VisualPresetDescriptor } from '@dice-o-rolla/dice-renderer';
|
|
3
3
|
import { BufferGeometry, Mesh, type MeshStandardMaterial } from 'three';
|
|
4
|
-
type Vector2Tuple = readonly [u: number, v: number];
|
|
4
|
+
export type Vector2Tuple = readonly [u: number, v: number];
|
|
5
5
|
export declare const DEFAULT_THREE_THEME: RendererTheme;
|
|
6
6
|
export interface ThreeDiceMesh {
|
|
7
7
|
readonly mesh: Mesh<BufferGeometry, MeshStandardMaterial[]>;
|
|
@@ -18,11 +18,13 @@ export interface FaceMaterialResource {
|
|
|
18
18
|
readonly material: MeshStandardMaterial;
|
|
19
19
|
dispose(): void;
|
|
20
20
|
}
|
|
21
|
+
export type SurfaceUvMap = Readonly<Record<number, readonly Vector2Tuple[]>>;
|
|
21
22
|
export interface ThreeFaceMaterialProvider {
|
|
23
|
+
getSurfaceUvs?(definition: PolyhedronDefinition, preset?: VisualPresetDescriptor): SurfaceUvMap | undefined;
|
|
22
24
|
createFace(context: FaceMaterialContext): FaceMaterialResource;
|
|
23
25
|
dispose?(): void;
|
|
24
26
|
}
|
|
25
|
-
export declare function createPolyhedronGeometry(definition: PolyhedronDefinition, scale?: number): BufferGeometry;
|
|
27
|
+
export declare function createPolyhedronGeometry(definition: PolyhedronDefinition, scale?: number, surfaceUvs?: SurfaceUvMap): BufferGeometry;
|
|
26
28
|
export declare class ThreeDiceMeshFactory {
|
|
27
29
|
#private;
|
|
28
30
|
constructor(materials?: ThreeFaceMaterialProvider);
|
|
@@ -31,4 +33,5 @@ export declare class ThreeDiceMeshFactory {
|
|
|
31
33
|
}
|
|
32
34
|
export declare function createFaceUvs(definition: PolyhedronDefinition, face: PolygonDefinition): readonly Vector2Tuple[];
|
|
33
35
|
export declare function getFaceLabel(definition: PolyhedronDefinition, face: PolygonDefinition, faceLabels?: Readonly<Record<number, string | number>>): string | number | readonly number[];
|
|
34
|
-
|
|
36
|
+
/** Validate complete per-corner UVs before allocating geometry or materials. */
|
|
37
|
+
export declare function validateSurfaceUvs(definition: PolyhedronDefinition, uvs: SurfaceUvMap): void;
|
package/dist/mesh-factory.js
CHANGED
|
@@ -10,10 +10,13 @@ export const DEFAULT_THREE_THEME = Object.freeze({
|
|
|
10
10
|
roughness: 0.28,
|
|
11
11
|
metalness: 0,
|
|
12
12
|
});
|
|
13
|
-
export function createPolyhedronGeometry(definition, scale = 1) {
|
|
13
|
+
export function createPolyhedronGeometry(definition, scale = 1, surfaceUvs) {
|
|
14
14
|
if (!Number.isFinite(scale) || scale <= 0) {
|
|
15
15
|
throw new RangeError('scale must be a positive finite number');
|
|
16
16
|
}
|
|
17
|
+
if (surfaceUvs !== undefined)
|
|
18
|
+
validateSurfaceUvs(definition, surfaceUvs);
|
|
19
|
+
const surface = [];
|
|
17
20
|
const positions = [];
|
|
18
21
|
const uvs = [];
|
|
19
22
|
const geometry = new BufferGeometry();
|
|
@@ -30,12 +33,15 @@ export function createPolyhedronGeometry(definition, scale = 1) {
|
|
|
30
33
|
}
|
|
31
34
|
positions.push(vertex[0] * scale, vertex[1] * scale, vertex[2] * scale);
|
|
32
35
|
uvs.push(uv[0], uv[1]);
|
|
36
|
+
const mapped = surfaceUvs?.[face.value]?.[faceIndex] ?? uv;
|
|
37
|
+
surface.push(mapped[0], mapped[1]);
|
|
33
38
|
}
|
|
34
39
|
}
|
|
35
40
|
geometry.addGroup(start, positions.length / 3 - start, materialIndex);
|
|
36
41
|
});
|
|
37
42
|
geometry.setAttribute('position', new Float32BufferAttribute(positions, 3));
|
|
38
43
|
geometry.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
|
|
44
|
+
geometry.setAttribute('uv1', new Float32BufferAttribute(surface, 2));
|
|
39
45
|
geometry.computeVertexNormals();
|
|
40
46
|
geometry.computeBoundingSphere();
|
|
41
47
|
return geometry;
|
|
@@ -46,14 +52,24 @@ export class ThreeDiceMeshFactory {
|
|
|
46
52
|
this.#materials = materials;
|
|
47
53
|
}
|
|
48
54
|
create(definition, theme = DEFAULT_THREE_THEME, scale = 1, faceLabels, preset) {
|
|
49
|
-
const geometry = createPolyhedronGeometry(definition, scale);
|
|
50
|
-
const resources =
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
const geometry = createPolyhedronGeometry(definition, scale, this.#materials.getSurfaceUvs?.(definition, preset));
|
|
56
|
+
const resources = [];
|
|
57
|
+
try {
|
|
58
|
+
for (const face of definition.faces)
|
|
59
|
+
resources.push(this.#materials.createFace({
|
|
60
|
+
label: getFaceLabel(definition, face, faceLabels),
|
|
61
|
+
faceValue: face.value,
|
|
62
|
+
theme,
|
|
63
|
+
...(preset === undefined ? {} : { preset }),
|
|
64
|
+
...(definition.id === 'd10' ? { labelScale: D10_LABEL_SCALE } : {}),
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
geometry.dispose();
|
|
69
|
+
for (const resource of resources)
|
|
70
|
+
resource.dispose();
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
57
73
|
const materials = resources.map(({ material }) => material);
|
|
58
74
|
const mesh = new Mesh(geometry, materials);
|
|
59
75
|
mesh.castShadow = true;
|
|
@@ -169,3 +185,24 @@ export function getFaceLabel(definition, face, faceLabels) {
|
|
|
169
185
|
return 0;
|
|
170
186
|
return face.value;
|
|
171
187
|
}
|
|
188
|
+
/** Validate complete per-corner UVs before allocating geometry or materials. */
|
|
189
|
+
export function validateSurfaceUvs(definition, uvs) {
|
|
190
|
+
const fail = (face) => {
|
|
191
|
+
throw new RangeError(`Geometry "${definition.id}" face ${face}: invalid surface UVs`);
|
|
192
|
+
};
|
|
193
|
+
for (const key of Object.keys(uvs)) {
|
|
194
|
+
if (!definition.faces.some((face) => String(face.value) === key))
|
|
195
|
+
fail(Number(key));
|
|
196
|
+
}
|
|
197
|
+
for (const face of definition.faces) {
|
|
198
|
+
const coordinates = uvs[face.value];
|
|
199
|
+
if (!Array.isArray(coordinates) || coordinates.length !== face.indices.length)
|
|
200
|
+
fail(face.value);
|
|
201
|
+
for (const uv of coordinates) {
|
|
202
|
+
if (!Array.isArray(uv) ||
|
|
203
|
+
uv.length !== 2 ||
|
|
204
|
+
!uv.every((value) => Number.isFinite(value) && value >= 0 && value <= 1))
|
|
205
|
+
fail(face.value);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dice-o-rolla/dice-renderer-three",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Three.js WebGL renderers for animated physical dice.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dice",
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"registry": "https://registry.npmjs.org/"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@dice-o-rolla/dice-geometry": "0.
|
|
44
|
-
"@dice-o-rolla/dice-renderer": "0.
|
|
43
|
+
"@dice-o-rolla/dice-geometry": "0.5.0",
|
|
44
|
+
"@dice-o-rolla/dice-renderer": "0.5.0",
|
|
45
45
|
"@types/three": "^0.185.0",
|
|
46
46
|
"three": "^0.185.0"
|
|
47
47
|
},
|