3d-spinner 0.9.4 → 0.9.6

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 (54) hide show
  1. package/dist/animations/charged-orb.js +4 -2
  2. package/dist/animations/ghost-train.d.ts +1 -1
  3. package/dist/animations/ghost-train.js +3 -1
  4. package/dist/animations/grid-assembly.d.ts +1 -1
  5. package/dist/animations/spin.d.ts +3 -1
  6. package/dist/animations/spin.js +6 -1
  7. package/dist/cjs/animations/charged-orb.cjs +177 -30
  8. package/dist/cjs/animations/grid-assembly.cjs +171 -28
  9. package/dist/cjs/animations/object-motion.cjs +163 -26
  10. package/dist/cjs/animations/particles.cjs +181 -30
  11. package/dist/cjs/animations/spin.cjs +176 -29
  12. package/dist/cjs/engines/little-3d-engine/little-3d-engine.cjs +200 -47
  13. package/dist/cjs/engines/little-3d-engine/loaders/obj.cjs +51 -13
  14. package/dist/cjs/engines/little-3d-engine/renderers/canvas2d-textured.cjs +56 -6
  15. package/dist/cjs/engines/little-3d-engine/renderers/webgl-textured.cjs +69 -10
  16. package/dist/cjs/engines/little-3d-engine/renderers/webgpu-textured.cjs +64 -11
  17. package/dist/cjs/prefabs/prefabs.cjs +200 -44
  18. package/dist/engines/little-3d-engine/core/geometry.d.ts +15 -2
  19. package/dist/engines/little-3d-engine/core/geometry.js +25 -3
  20. package/dist/engines/little-3d-engine/core/light.d.ts +28 -4
  21. package/dist/engines/little-3d-engine/core/light.js +48 -7
  22. package/dist/engines/little-3d-engine/core/mesh.d.ts +33 -0
  23. package/dist/engines/little-3d-engine/core/mesh.js +12 -0
  24. package/dist/engines/little-3d-engine/little-3d-engine.d.ts +2 -2
  25. package/dist/engines/little-3d-engine/little-3d-engine.js +1 -1
  26. package/dist/engines/little-3d-engine/loaders/obj.d.ts +8 -7
  27. package/dist/engines/little-3d-engine/loaders/obj.js +74 -20
  28. package/dist/engines/little-3d-engine/renderers/canvas2d.js +23 -1
  29. package/dist/engines/little-3d-engine/renderers/webgl-textured.js +8 -3
  30. package/dist/engines/little-3d-engine/renderers/webgl.js +41 -7
  31. package/dist/engines/little-3d-engine/renderers/webgpu.js +43 -10
  32. package/dist/engines/little-3d-engine/shapes/complex/plane.d.ts +8 -3
  33. package/dist/engines/little-3d-engine/shapes/complex/plane.js +10 -4
  34. package/dist/engines/little-3d-engine/shapes/primitives/cube.d.ts +3 -2
  35. package/dist/engines/little-3d-engine/shapes/primitives/cube.js +4 -2
  36. package/dist/engines/little-3d-engine/shapes/primitives/octahedron.d.ts +3 -2
  37. package/dist/engines/little-3d-engine/shapes/primitives/octahedron.js +4 -2
  38. package/dist/engines/little-3d-engine/shapes/primitives/pyramid.d.ts +3 -2
  39. package/dist/engines/little-3d-engine/shapes/primitives/pyramid.js +4 -2
  40. package/dist/engines/little-3d-engine/shapes/primitives/quad.d.ts +3 -2
  41. package/dist/engines/little-3d-engine/shapes/primitives/quad.js +4 -2
  42. package/dist/engines/little-3d-engine/shapes/primitives/spheres/cube-sphere.d.ts +3 -2
  43. package/dist/engines/little-3d-engine/shapes/primitives/spheres/cube-sphere.js +4 -2
  44. package/dist/engines/little-3d-engine/shapes/primitives/spheres/icosphere.d.ts +3 -2
  45. package/dist/engines/little-3d-engine/shapes/primitives/spheres/icosphere.js +4 -2
  46. package/dist/engines/little-3d-engine/shapes/primitives/spheres/octa-sphere.d.ts +3 -2
  47. package/dist/engines/little-3d-engine/shapes/primitives/spheres/octa-sphere.js +4 -2
  48. package/dist/engines/little-3d-engine/shapes/primitives/spheres/uv-sphere.d.ts +3 -2
  49. package/dist/engines/little-3d-engine/shapes/primitives/spheres/uv-sphere.js +4 -2
  50. package/dist/engines/little-3d-engine/shapes/primitives/tetrahedron.d.ts +3 -2
  51. package/dist/engines/little-3d-engine/shapes/primitives/tetrahedron.js +4 -2
  52. package/dist/umd/spinner.global.js +271 -67
  53. package/dist/umd/spinner.global.min.js +58 -17
  54. package/package.json +1 -1
@@ -7,6 +7,7 @@ struct Uniforms {
7
7
  model: mat4x4<f32>,
8
8
  toLight: vec4<f32>,
9
9
  params: vec4<f32>,
10
+ eye: vec4<f32>,
10
11
  };
11
12
  @group(0) @binding(0) var<uniform> u: Uniforms;
12
13
 
@@ -14,23 +15,40 @@ struct VSOut {
14
15
  @builtin(position) position: vec4<f32>,
15
16
  @location(0) normal: vec3<f32>,
16
17
  @location(1) color: vec3<f32>,
18
+ @location(2) emissive: vec3<f32>,
19
+ @location(3) specular: vec4<f32>,
20
+ @location(4) worldPos: vec3<f32>,
17
21
  };
18
22
 
19
23
  @vertex
20
- fn vs(@location(0) pos: vec3<f32>, @location(1) normal: vec3<f32>, @location(2) color: vec3<f32>) -> VSOut {
24
+ fn vs(@location(0) pos: vec3<f32>, @location(1) normal: vec3<f32>, @location(2) color: vec3<f32>, @location(3) emissive: vec3<f32>, @location(4) specular: vec4<f32>) -> VSOut {
21
25
  var out: VSOut;
22
26
  let m = mat3x3<f32>(u.model[0].xyz, u.model[1].xyz, u.model[2].xyz);
23
27
  out.normal = m * normal;
24
28
  out.color = color;
25
- out.position = u.viewProj * u.model * vec4<f32>(pos, 1.0);
29
+ out.emissive = emissive;
30
+ out.specular = specular;
31
+ let world = u.model * vec4<f32>(pos, 1.0);
32
+ out.worldPos = world.xyz;
33
+ out.position = u.viewProj * world;
26
34
  return out;
27
35
  }
28
36
 
29
37
  @fragment
30
38
  fn fs(in: VSOut) -> @location(0) vec4<f32> {
31
- let lambert = max(dot(normalize(in.normal), normalize(u.toLight.xyz)), 0.0);
39
+ let normal = normalize(in.normal);
40
+ let toLight = normalize(u.toLight.xyz);
41
+ let lambert = max(dot(normal, toLight), 0.0);
32
42
  let brightness = clamp(u.params.y + u.params.x * lambert, 0.0, 1.0);
33
- return vec4<f32>(in.color * brightness, u.params.z);
43
+ var lit = in.color * brightness;
44
+ if (lambert > 0.0) {
45
+ let viewDir = normalize(u.eye.xyz - in.worldPos);
46
+ let halfVec = normalize(toLight + viewDir);
47
+ let highlight = pow(max(dot(normal, halfVec), 0.0), in.specular.w) * u.params.x;
48
+ lit = lit + highlight * in.specular.xyz;
49
+ }
50
+ lit = lit + in.emissive;
51
+ return vec4<f32>(lit, u.params.z);
34
52
  }
35
53
  `;
36
54
  // Maps OpenGL clip space (z in -1..1) to WebGPU clip space (z in 0..1).
@@ -77,13 +95,15 @@ export class WebGPURenderer {
77
95
  {
78
96
  binding: 0,
79
97
  visibility: stage.VERTEX | stage.FRAGMENT,
80
- buffer: { type: "uniform", hasDynamicOffset: true, minBindingSize: 160 },
98
+ buffer: { type: "uniform", hasDynamicOffset: true, minBindingSize: 176 },
81
99
  },
82
100
  ],
83
101
  });
84
- const vertexBuffer = (location) => ({
85
- arrayStride: 12,
86
- attributes: [{ shaderLocation: location, offset: 0, format: "float32x3" }],
102
+ const vertexBuffer = (location, components = 3) => ({
103
+ arrayStride: components * 4,
104
+ attributes: [
105
+ { shaderLocation: location, offset: 0, format: `float32x${components}` },
106
+ ],
87
107
  });
88
108
  const pipelineLayout = device.createPipelineLayout({ bindGroupLayouts: [layout] });
89
109
  const blend = {
@@ -99,7 +119,13 @@ export class WebGPURenderer {
99
119
  vertex: {
100
120
  module,
101
121
  entryPoint: "vs",
102
- buffers: [vertexBuffer(0), vertexBuffer(1), vertexBuffer(2)],
122
+ buffers: [
123
+ vertexBuffer(0),
124
+ vertexBuffer(1),
125
+ vertexBuffer(2),
126
+ vertexBuffer(3),
127
+ vertexBuffer(4, 4),
128
+ ],
103
129
  },
104
130
  fragment: {
105
131
  module,
@@ -155,6 +181,8 @@ export class WebGPURenderer {
155
181
  position: upload(data.positions),
156
182
  normal: upload(data.normals),
157
183
  color: upload(data.colors),
184
+ emissive: upload(data.emissives),
185
+ specular: upload(data.speculars),
158
186
  count: data.count,
159
187
  };
160
188
  this.cache.set(mesh, result);
@@ -212,7 +240,7 @@ export class WebGPURenderer {
212
240
  const bindGroup = this.device.createBindGroup({
213
241
  layout,
214
242
  entries: [
215
- { binding: 0, resource: { buffer: this.uniformBuffer, offset: 0, size: 160 } },
243
+ { binding: 0, resource: { buffer: this.uniformBuffer, offset: 0, size: 176 } },
216
244
  ],
217
245
  });
218
246
  draws.forEach((draw, i) => {
@@ -221,6 +249,7 @@ export class WebGPURenderer {
221
249
  data.set(draw.item.model, 16);
222
250
  data.set([frame.light.toLight.x, frame.light.toLight.y, frame.light.toLight.z, 0], 32);
223
251
  data.set([frame.light.intensity, frame.light.ambient, draw.opacity, 0], 36);
252
+ data.set([frame.eye.x, frame.eye.y, frame.eye.z, 0], 40);
224
253
  this.device.queue.writeBuffer(this.uniformBuffer, i * UNIFORM_STRIDE, data);
225
254
  });
226
255
  const encoder = this.device.createCommandEncoder();
@@ -247,6 +276,8 @@ export class WebGPURenderer {
247
276
  pass.setVertexBuffer(0, mesh.position);
248
277
  pass.setVertexBuffer(1, mesh.normal);
249
278
  pass.setVertexBuffer(2, mesh.color);
279
+ pass.setVertexBuffer(3, mesh.emissive);
280
+ pass.setVertexBuffer(4, mesh.specular);
250
281
  pass.draw(mesh.count);
251
282
  });
252
283
  pass.end();
@@ -258,6 +289,8 @@ export class WebGPURenderer {
258
289
  mesh.position.destroy?.();
259
290
  mesh.normal.destroy?.();
260
291
  mesh.color.destroy?.();
292
+ mesh.emissive.destroy?.();
293
+ mesh.specular.destroy?.();
261
294
  }
262
295
  this.cache.clear();
263
296
  this.uniformBuffer?.destroy?.();
@@ -1,3 +1,8 @@
1
- import type { Mesh } from "../../core/mesh.js";
2
- /** Build a low-poly plane mesh pointing along the positive X axis. */
3
- export declare function planeMesh(colors?: string[]): Mesh;
1
+ import { type Material, type Mesh } from "../../core/mesh.js";
2
+ /**
3
+ * Build a low-poly plane mesh pointing along the positive X axis.
4
+ *
5
+ * @param colors CSS colors cycled across faces. Defaults to a built-in palette.
6
+ * @param material Optional surface material applied to every face.
7
+ */
8
+ export declare function planeMesh(colors?: string[], material?: Material): Mesh;
@@ -1,7 +1,13 @@
1
+ import { attachMaterial } from "../../core/mesh.js";
1
2
  const DEFAULT_COLORS = ["#e0f2fe", "#7dd3fc", "#38bdf8", "#f8fafc"];
2
- /** Build a low-poly plane mesh pointing along the positive X axis. */
3
- export function planeMesh(colors = DEFAULT_COLORS) {
4
- return {
3
+ /**
4
+ * Build a low-poly plane mesh pointing along the positive X axis.
5
+ *
6
+ * @param colors CSS colors cycled across faces. Defaults to a built-in palette.
7
+ * @param material Optional surface material applied to every face.
8
+ */
9
+ export function planeMesh(colors = DEFAULT_COLORS, material) {
10
+ return attachMaterial({
5
11
  vertices: [
6
12
  { x: 0.9, y: 0, z: 0 },
7
13
  { x: -0.2, y: 0, z: 0.82 },
@@ -29,5 +35,5 @@ export function planeMesh(colors = DEFAULT_COLORS) {
29
35
  { indices: [3, 6, 8], color: colors[0] ?? DEFAULT_COLORS[0] },
30
36
  { indices: [3, 8, 6], color: colors[1] ?? DEFAULT_COLORS[1] },
31
37
  ],
32
- };
38
+ }, material);
33
39
  }
@@ -1,9 +1,10 @@
1
- import type { Mesh } from "../../core/mesh.js";
1
+ import { type Material, type Mesh } from "../../core/mesh.js";
2
2
  /**
3
3
  * Build a cube mesh centered on the origin.
4
4
  *
5
5
  * @param size Edge length. Defaults to `1`.
6
6
  * @param colors Six CSS colors, one per face (front, back, top, bottom, right, left).
7
7
  * Defaults to a built-in palette.
8
+ * @param material Optional surface material applied to every face.
8
9
  */
9
- export declare function cube(size?: number, colors?: string[]): Mesh;
10
+ export declare function cube(size?: number, colors?: string[], material?: Material): Mesh;
@@ -1,3 +1,4 @@
1
+ import { attachMaterial } from "../../core/mesh.js";
1
2
  const DEFAULT_COLORS = ["#3b82f6", "#8b5cf6", "#ec4899", "#f59e0b", "#10b981", "#ef4444"];
2
3
  /**
3
4
  * Build a cube mesh centered on the origin.
@@ -5,8 +6,9 @@ const DEFAULT_COLORS = ["#3b82f6", "#8b5cf6", "#ec4899", "#f59e0b", "#10b981", "
5
6
  * @param size Edge length. Defaults to `1`.
6
7
  * @param colors Six CSS colors, one per face (front, back, top, bottom, right, left).
7
8
  * Defaults to a built-in palette.
9
+ * @param material Optional surface material applied to every face.
8
10
  */
9
- export function cube(size = 1, colors = DEFAULT_COLORS) {
11
+ export function cube(size = 1, colors = DEFAULT_COLORS, material) {
10
12
  const h = size / 2;
11
13
  const vertices = [
12
14
  { x: -h, y: -h, z: h },
@@ -26,5 +28,5 @@ export function cube(size = 1, colors = DEFAULT_COLORS) {
26
28
  { indices: [1, 5, 6, 2], color: colors[4 % colors.length] },
27
29
  { indices: [4, 0, 3, 7], color: colors[5 % colors.length] },
28
30
  ];
29
- return { vertices, faces };
31
+ return attachMaterial({ vertices, faces }, material);
30
32
  }
@@ -1,8 +1,9 @@
1
- import type { Mesh } from "../../core/mesh.js";
1
+ import { type Material, type Mesh } from "../../core/mesh.js";
2
2
  /**
3
3
  * Build a regular octahedron mesh centered on the origin.
4
4
  *
5
5
  * @param size Distance between opposite vertices. Defaults to `1`.
6
6
  * @param colors Eight CSS colors, one per triangular face. Defaults to a built-in palette.
7
+ * @param material Optional surface material applied to every face.
7
8
  */
8
- export declare function octahedron(size?: number, colors?: string[]): Mesh;
9
+ export declare function octahedron(size?: number, colors?: string[], material?: Material): Mesh;
@@ -1,3 +1,4 @@
1
+ import { attachMaterial } from "../../core/mesh.js";
1
2
  const DEFAULT_COLORS = [
2
3
  "#3b82f6",
3
4
  "#8b5cf6",
@@ -13,8 +14,9 @@ const DEFAULT_COLORS = [
13
14
  *
14
15
  * @param size Distance between opposite vertices. Defaults to `1`.
15
16
  * @param colors Eight CSS colors, one per triangular face. Defaults to a built-in palette.
17
+ * @param material Optional surface material applied to every face.
16
18
  */
17
- export function octahedron(size = 1, colors = DEFAULT_COLORS) {
19
+ export function octahedron(size = 1, colors = DEFAULT_COLORS, material) {
18
20
  const r = size / 2;
19
21
  const vertices = [
20
22
  { x: r, y: 0, z: 0 },
@@ -34,5 +36,5 @@ export function octahedron(size = 1, colors = DEFAULT_COLORS) {
34
36
  { indices: [5, 3, 1], color: colors[6 % colors.length] },
35
37
  { indices: [5, 0, 3], color: colors[7 % colors.length] },
36
38
  ];
37
- return { vertices, faces };
39
+ return attachMaterial({ vertices, faces }, material);
38
40
  }
@@ -1,9 +1,10 @@
1
- import type { Mesh } from "../../core/mesh.js";
1
+ import { type Material, type Mesh } from "../../core/mesh.js";
2
2
  /**
3
3
  * Build a square pyramid mesh centered on the origin, base down.
4
4
  *
5
5
  * @param size Base edge length (also the height). Defaults to `1`.
6
6
  * @param colors Five CSS colors: the square base, then the four triangular sides.
7
7
  * Defaults to a built-in palette.
8
+ * @param material Optional surface material applied to every face.
8
9
  */
9
- export declare function pyramid(size?: number, colors?: string[]): Mesh;
10
+ export declare function pyramid(size?: number, colors?: string[], material?: Material): Mesh;
@@ -1,3 +1,4 @@
1
+ import { attachMaterial } from "../../core/mesh.js";
1
2
  const DEFAULT_COLORS = ["#3b82f6", "#8b5cf6", "#ec4899", "#f59e0b", "#10b981"];
2
3
  /**
3
4
  * Build a square pyramid mesh centered on the origin, base down.
@@ -5,8 +6,9 @@ const DEFAULT_COLORS = ["#3b82f6", "#8b5cf6", "#ec4899", "#f59e0b", "#10b981"];
5
6
  * @param size Base edge length (also the height). Defaults to `1`.
6
7
  * @param colors Five CSS colors: the square base, then the four triangular sides.
7
8
  * Defaults to a built-in palette.
9
+ * @param material Optional surface material applied to every face.
8
10
  */
9
- export function pyramid(size = 1, colors = DEFAULT_COLORS) {
11
+ export function pyramid(size = 1, colors = DEFAULT_COLORS, material) {
10
12
  const h = size / 2;
11
13
  const vertices = [
12
14
  { x: -h, y: -h, z: h },
@@ -22,5 +24,5 @@ export function pyramid(size = 1, colors = DEFAULT_COLORS) {
22
24
  { indices: [4, 2, 3], color: colors[3 % colors.length] },
23
25
  { indices: [4, 3, 0], color: colors[4 % colors.length] },
24
26
  ];
25
- return { vertices, faces };
27
+ return attachMaterial({ vertices, faces }, material);
26
28
  }
@@ -1,9 +1,10 @@
1
- import type { Mesh } from "../../core/mesh.js";
1
+ import { type Material, type Mesh } from "../../core/mesh.js";
2
2
  /**
3
3
  * Build a flat square in the XY plane, facing +Z, as a single four-vertex
4
4
  * face. Useful as a billboard when kept facing the camera.
5
5
  *
6
6
  * @param size Edge length. Defaults to `1`.
7
7
  * @param colors CSS color for the face. Defaults to a built-in blue.
8
+ * @param material Optional surface material applied to every face.
8
9
  */
9
- export declare function quad(size?: number, colors?: string[]): Mesh;
10
+ export declare function quad(size?: number, colors?: string[], material?: Material): Mesh;
@@ -1,3 +1,4 @@
1
+ import { attachMaterial } from "../../core/mesh.js";
1
2
  const DEFAULT_COLORS = ["#3b82f6"];
2
3
  /**
3
4
  * Build a flat square in the XY plane, facing +Z, as a single four-vertex
@@ -5,8 +6,9 @@ const DEFAULT_COLORS = ["#3b82f6"];
5
6
  *
6
7
  * @param size Edge length. Defaults to `1`.
7
8
  * @param colors CSS color for the face. Defaults to a built-in blue.
9
+ * @param material Optional surface material applied to every face.
8
10
  */
9
- export function quad(size = 1, colors = DEFAULT_COLORS) {
11
+ export function quad(size = 1, colors = DEFAULT_COLORS, material) {
10
12
  const s = size / 2;
11
13
  const vertices = [
12
14
  { x: -s, y: -s, z: 0 },
@@ -14,5 +16,5 @@ export function quad(size = 1, colors = DEFAULT_COLORS) {
14
16
  { x: s, y: s, z: 0 },
15
17
  { x: -s, y: s, z: 0 },
16
18
  ];
17
- return { vertices, faces: [{ indices: [0, 1, 2, 3], color: colors[0] }] };
19
+ return attachMaterial({ vertices, faces: [{ indices: [0, 1, 2, 3], color: colors[0] }] }, material);
18
20
  }
@@ -1,4 +1,4 @@
1
- import type { Mesh } from "../../../core/mesh.js";
1
+ import { type Material, type Mesh } from "../../../core/mesh.js";
2
2
  /**
3
3
  * Build a cube-sphere (spherified cube) centered on the origin: each cube face
4
4
  * is gridded and projected onto the sphere. Even, all-quad, no poles.
@@ -7,5 +7,6 @@ import type { Mesh } from "../../../core/mesh.js";
7
7
  * @param detail Subdivisions per cube face edge, `1` = simplest (6 quads).
8
8
  * Defaults to `1`.
9
9
  * @param colors CSS colors cycled across faces. Defaults to a built-in palette.
10
+ * @param material Optional surface material applied to every face.
10
11
  */
11
- export declare function cubeSphere(size?: number, detail?: number, colors?: string[]): Mesh;
12
+ export declare function cubeSphere(size?: number, detail?: number, colors?: string[], material?: Material): Mesh;
@@ -1,3 +1,4 @@
1
+ import { attachMaterial } from "../../../core/mesh.js";
1
2
  const DEFAULT_COLORS = ["#3b82f6", "#8b5cf6", "#ec4899", "#f59e0b", "#10b981", "#ef4444"];
2
3
  // right x up == normal for each face, so generated quads wind CCW outward.
3
4
  const CUBE_FACES = [
@@ -16,8 +17,9 @@ const CUBE_FACES = [
16
17
  * @param detail Subdivisions per cube face edge, `1` = simplest (6 quads).
17
18
  * Defaults to `1`.
18
19
  * @param colors CSS colors cycled across faces. Defaults to a built-in palette.
20
+ * @param material Optional surface material applied to every face.
19
21
  */
20
- export function cubeSphere(size = 1, detail = 1, colors = DEFAULT_COLORS) {
22
+ export function cubeSphere(size = 1, detail = 1, colors = DEFAULT_COLORS, material) {
21
23
  const r = size / 2;
22
24
  const n = Math.max(1, Math.floor(detail));
23
25
  const vertices = [];
@@ -46,5 +48,5 @@ export function cubeSphere(size = 1, detail = 1, colors = DEFAULT_COLORS) {
46
48
  }
47
49
  }
48
50
  }
49
- return { vertices, faces };
51
+ return attachMaterial({ vertices, faces }, material);
50
52
  }
@@ -1,4 +1,4 @@
1
- import type { Mesh } from "../../../core/mesh.js";
1
+ import { type Material, type Mesh } from "../../../core/mesh.js";
2
2
  /**
3
3
  * Build an icosphere (subdivided icosahedron) centered on the origin. Gives the
4
4
  * most uniform triangle distribution of the sphere types.
@@ -7,5 +7,6 @@ import type { Mesh } from "../../../core/mesh.js";
7
7
  * @param detail Subdivision level, `1` = base icosahedron (20 faces). Each level
8
8
  * splits every triangle into four. Defaults to `1`.
9
9
  * @param colors CSS colors cycled across faces. Defaults to a built-in palette.
10
+ * @param material Optional surface material applied to every face.
10
11
  */
11
- export declare function icosphere(size?: number, detail?: number, colors?: string[]): Mesh;
12
+ export declare function icosphere(size?: number, detail?: number, colors?: string[], material?: Material): Mesh;
@@ -1,4 +1,5 @@
1
1
  import { sphereFromTriangles } from "../../../core/geometry.js";
2
+ import { attachMaterial } from "../../../core/mesh.js";
2
3
  const DEFAULT_COLORS = ["#3b82f6", "#8b5cf6", "#ec4899", "#f59e0b", "#10b981", "#ef4444"];
3
4
  const T = (1 + Math.sqrt(5)) / 2;
4
5
  const SEED_VERTICES = [
@@ -45,7 +46,8 @@ const SEED_FACES = [
45
46
  * @param detail Subdivision level, `1` = base icosahedron (20 faces). Each level
46
47
  * splits every triangle into four. Defaults to `1`.
47
48
  * @param colors CSS colors cycled across faces. Defaults to a built-in palette.
49
+ * @param material Optional surface material applied to every face.
48
50
  */
49
- export function icosphere(size = 1, detail = 1, colors = DEFAULT_COLORS) {
50
- return sphereFromTriangles(SEED_VERTICES, SEED_FACES, size, detail, colors);
51
+ export function icosphere(size = 1, detail = 1, colors = DEFAULT_COLORS, material) {
52
+ return attachMaterial(sphereFromTriangles(SEED_VERTICES, SEED_FACES, size, detail, colors), material);
51
53
  }
@@ -1,4 +1,4 @@
1
- import type { Mesh } from "../../../core/mesh.js";
1
+ import { type Material, type Mesh } from "../../../core/mesh.js";
2
2
  /**
3
3
  * Build an octa-sphere (subdivided octahedron) centered on the origin.
4
4
  *
@@ -6,5 +6,6 @@ import type { Mesh } from "../../../core/mesh.js";
6
6
  * @param detail Subdivision level, `1` = base octahedron (8 faces). Each level
7
7
  * splits every triangle into four. Defaults to `1`.
8
8
  * @param colors CSS colors cycled across faces. Defaults to a built-in palette.
9
+ * @param material Optional surface material applied to every face.
9
10
  */
10
- export declare function octaSphere(size?: number, detail?: number, colors?: string[]): Mesh;
11
+ export declare function octaSphere(size?: number, detail?: number, colors?: string[], material?: Material): Mesh;
@@ -1,4 +1,5 @@
1
1
  import { sphereFromTriangles } from "../../../core/geometry.js";
2
+ import { attachMaterial } from "../../../core/mesh.js";
2
3
  const DEFAULT_COLORS = ["#3b82f6", "#8b5cf6", "#ec4899", "#f59e0b", "#10b981", "#ef4444"];
3
4
  const SEED_VERTICES = [
4
5
  { x: 1, y: 0, z: 0 },
@@ -25,7 +26,8 @@ const SEED_FACES = [
25
26
  * @param detail Subdivision level, `1` = base octahedron (8 faces). Each level
26
27
  * splits every triangle into four. Defaults to `1`.
27
28
  * @param colors CSS colors cycled across faces. Defaults to a built-in palette.
29
+ * @param material Optional surface material applied to every face.
28
30
  */
29
- export function octaSphere(size = 1, detail = 1, colors = DEFAULT_COLORS) {
30
- return sphereFromTriangles(SEED_VERTICES, SEED_FACES, size, detail, colors);
31
+ export function octaSphere(size = 1, detail = 1, colors = DEFAULT_COLORS, material) {
32
+ return attachMaterial(sphereFromTriangles(SEED_VERTICES, SEED_FACES, size, detail, colors), material);
31
33
  }
@@ -1,4 +1,4 @@
1
- import type { Mesh } from "../../../core/mesh.js";
1
+ import { type Material, type Mesh } from "../../../core/mesh.js";
2
2
  /**
3
3
  * Build a UV (latitude/longitude) sphere centered on the origin.
4
4
  *
@@ -6,5 +6,6 @@ import type { Mesh } from "../../../core/mesh.js";
6
6
  * @param detail Tessellation level, `1` = simplest. Higher values add rings and
7
7
  * segments. Defaults to `1`.
8
8
  * @param colors CSS colors cycled across faces. Defaults to a built-in palette.
9
+ * @param material Optional surface material applied to every face.
9
10
  */
10
- export declare function uvSphere(size?: number, detail?: number, colors?: string[]): Mesh;
11
+ export declare function uvSphere(size?: number, detail?: number, colors?: string[], material?: Material): Mesh;
@@ -1,3 +1,4 @@
1
+ import { attachMaterial } from "../../../core/mesh.js";
1
2
  const DEFAULT_COLORS = ["#3b82f6", "#8b5cf6", "#ec4899", "#f59e0b", "#10b981", "#ef4444"];
2
3
  /**
3
4
  * Build a UV (latitude/longitude) sphere centered on the origin.
@@ -6,8 +7,9 @@ const DEFAULT_COLORS = ["#3b82f6", "#8b5cf6", "#ec4899", "#f59e0b", "#10b981", "
6
7
  * @param detail Tessellation level, `1` = simplest. Higher values add rings and
7
8
  * segments. Defaults to `1`.
8
9
  * @param colors CSS colors cycled across faces. Defaults to a built-in palette.
10
+ * @param material Optional surface material applied to every face.
9
11
  */
10
- export function uvSphere(size = 1, detail = 1, colors = DEFAULT_COLORS) {
12
+ export function uvSphere(size = 1, detail = 1, colors = DEFAULT_COLORS, material) {
11
13
  const r = size / 2;
12
14
  const d = Math.max(1, Math.floor(detail));
13
15
  const slices = Math.max(4, d * 4);
@@ -46,5 +48,5 @@ export function uvSphere(size = 1, detail = 1, colors = DEFAULT_COLORS) {
46
48
  color: color(),
47
49
  });
48
50
  }
49
- return { vertices, faces };
51
+ return attachMaterial({ vertices, faces }, material);
50
52
  }
@@ -1,8 +1,9 @@
1
- import type { Mesh } from "../../core/mesh.js";
1
+ import { type Material, type Mesh } from "../../core/mesh.js";
2
2
  /**
3
3
  * Build a regular tetrahedron mesh centered on the origin.
4
4
  *
5
5
  * @param size Approximate diameter. Defaults to `1`.
6
6
  * @param colors Four CSS colors, one per triangular face. Defaults to a built-in palette.
7
+ * @param material Optional surface material applied to every face.
7
8
  */
8
- export declare function tetrahedron(size?: number, colors?: string[]): Mesh;
9
+ export declare function tetrahedron(size?: number, colors?: string[], material?: Material): Mesh;
@@ -1,11 +1,13 @@
1
+ import { attachMaterial } from "../../core/mesh.js";
1
2
  const DEFAULT_COLORS = ["#3b82f6", "#8b5cf6", "#ec4899", "#f59e0b"];
2
3
  /**
3
4
  * Build a regular tetrahedron mesh centered on the origin.
4
5
  *
5
6
  * @param size Approximate diameter. Defaults to `1`.
6
7
  * @param colors Four CSS colors, one per triangular face. Defaults to a built-in palette.
8
+ * @param material Optional surface material applied to every face.
7
9
  */
8
- export function tetrahedron(size = 1, colors = DEFAULT_COLORS) {
10
+ export function tetrahedron(size = 1, colors = DEFAULT_COLORS, material) {
9
11
  const s = size / 2;
10
12
  const vertices = [
11
13
  { x: s, y: s, z: s },
@@ -19,5 +21,5 @@ export function tetrahedron(size = 1, colors = DEFAULT_COLORS) {
19
21
  { indices: [0, 2, 3], color: colors[2 % colors.length] },
20
22
  { indices: [1, 3, 2], color: colors[3 % colors.length] },
21
23
  ];
22
- return { vertices, faces };
24
+ return attachMaterial({ vertices, faces }, material);
23
25
  }