@luma.gl/engine 9.2.6 → 9.3.0-alpha.11

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 (198) hide show
  1. package/dist/animation-loop/animation-loop.d.ts +11 -5
  2. package/dist/animation-loop/animation-loop.d.ts.map +1 -1
  3. package/dist/animation-loop/animation-loop.js +83 -47
  4. package/dist/animation-loop/animation-loop.js.map +1 -1
  5. package/dist/animation-loop/make-animation-loop.d.ts.map +1 -1
  6. package/dist/animation-loop/make-animation-loop.js +8 -1
  7. package/dist/animation-loop/make-animation-loop.js.map +1 -1
  8. package/dist/animation-loop/request-animation-frame.d.ts.map +1 -1
  9. package/dist/animation-loop/request-animation-frame.js +23 -6
  10. package/dist/animation-loop/request-animation-frame.js.map +1 -1
  11. package/dist/compute/computation.d.ts +3 -7
  12. package/dist/compute/computation.d.ts.map +1 -1
  13. package/dist/compute/computation.js +16 -13
  14. package/dist/compute/computation.js.map +1 -1
  15. package/dist/compute/swap.d.ts +2 -0
  16. package/dist/compute/swap.d.ts.map +1 -1
  17. package/dist/compute/swap.js +10 -5
  18. package/dist/compute/swap.js.map +1 -1
  19. package/dist/debug/debug-framebuffer.d.ts +9 -4
  20. package/dist/debug/debug-framebuffer.d.ts.map +1 -1
  21. package/dist/debug/debug-framebuffer.js +91 -45
  22. package/dist/debug/debug-framebuffer.js.map +1 -1
  23. package/dist/dist.dev.js +2767 -1344
  24. package/dist/dist.min.js +326 -211
  25. package/dist/dynamic-texture/dynamic-texture.d.ts +102 -0
  26. package/dist/dynamic-texture/dynamic-texture.d.ts.map +1 -0
  27. package/dist/dynamic-texture/dynamic-texture.js +558 -0
  28. package/dist/dynamic-texture/dynamic-texture.js.map +1 -0
  29. package/dist/dynamic-texture/texture-data.d.ts +144 -0
  30. package/dist/dynamic-texture/texture-data.d.ts.map +1 -0
  31. package/dist/dynamic-texture/texture-data.js +208 -0
  32. package/dist/dynamic-texture/texture-data.js.map +1 -0
  33. package/dist/geometries/cone-geometry.d.ts +3 -1
  34. package/dist/geometries/cone-geometry.d.ts.map +1 -1
  35. package/dist/geometries/cone-geometry.js.map +1 -1
  36. package/dist/geometries/cube-geometry.js +7 -7
  37. package/dist/geometries/cube-geometry.js.map +1 -1
  38. package/dist/geometries/cylinder-geometry.d.ts +2 -1
  39. package/dist/geometries/cylinder-geometry.d.ts.map +1 -1
  40. package/dist/geometries/cylinder-geometry.js.map +1 -1
  41. package/dist/geometries/ico-sphere-geometry.js +3 -1
  42. package/dist/geometries/ico-sphere-geometry.js.map +1 -1
  43. package/dist/geometry/gpu-geometry.d.ts.map +1 -1
  44. package/dist/geometry/gpu-geometry.js +11 -3
  45. package/dist/geometry/gpu-geometry.js.map +1 -1
  46. package/dist/index.cjs +2620 -1267
  47. package/dist/index.cjs.map +4 -4
  48. package/dist/index.d.ts +20 -6
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +12 -4
  51. package/dist/index.js.map +1 -1
  52. package/dist/material/material-factory.d.ts +73 -0
  53. package/dist/material/material-factory.d.ts.map +1 -0
  54. package/dist/material/material-factory.js +111 -0
  55. package/dist/material/material-factory.js.map +1 -0
  56. package/dist/material/material.d.ts +84 -0
  57. package/dist/material/material.d.ts.map +1 -0
  58. package/dist/material/material.js +176 -0
  59. package/dist/material/material.js.map +1 -0
  60. package/dist/model/model.d.ts +47 -16
  61. package/dist/model/model.d.ts.map +1 -1
  62. package/dist/model/model.js +148 -71
  63. package/dist/model/model.js.map +1 -1
  64. package/dist/model/split-uniforms-and-bindings.d.ts +4 -3
  65. package/dist/model/split-uniforms-and-bindings.d.ts.map +1 -1
  66. package/dist/model/split-uniforms-and-bindings.js +2 -2
  67. package/dist/model/split-uniforms-and-bindings.js.map +1 -1
  68. package/dist/models/billboard-texture-model.d.ts +8 -5
  69. package/dist/models/billboard-texture-model.d.ts.map +1 -1
  70. package/dist/models/billboard-texture-model.js +79 -25
  71. package/dist/models/billboard-texture-model.js.map +1 -1
  72. package/dist/models/billboard-texture-module.d.ts +1 -1
  73. package/dist/models/billboard-texture-module.js +1 -1
  74. package/dist/models/clip-space.js +7 -7
  75. package/dist/models/directional-light-model.d.ts +7 -0
  76. package/dist/models/directional-light-model.d.ts.map +1 -0
  77. package/dist/models/directional-light-model.js +23 -0
  78. package/dist/models/directional-light-model.js.map +1 -0
  79. package/dist/models/light-model-utils.d.ts +69 -0
  80. package/dist/models/light-model-utils.d.ts.map +1 -0
  81. package/dist/models/light-model-utils.js +395 -0
  82. package/dist/models/light-model-utils.js.map +1 -0
  83. package/dist/models/point-light-model.d.ts +7 -0
  84. package/dist/models/point-light-model.d.ts.map +1 -0
  85. package/dist/models/point-light-model.js +22 -0
  86. package/dist/models/point-light-model.js.map +1 -0
  87. package/dist/models/spot-light-model.d.ts +7 -0
  88. package/dist/models/spot-light-model.d.ts.map +1 -0
  89. package/dist/models/spot-light-model.js +23 -0
  90. package/dist/models/spot-light-model.js.map +1 -0
  91. package/dist/modules/picking/color-picking.d.ts +5 -9
  92. package/dist/modules/picking/color-picking.d.ts.map +1 -1
  93. package/dist/modules/picking/color-picking.js +122 -115
  94. package/dist/modules/picking/color-picking.js.map +1 -1
  95. package/dist/modules/picking/index-picking.d.ts +4 -4
  96. package/dist/modules/picking/index-picking.d.ts.map +1 -1
  97. package/dist/modules/picking/index-picking.js +36 -16
  98. package/dist/modules/picking/index-picking.js.map +1 -1
  99. package/dist/modules/picking/legacy-color-picking.d.ts +26 -0
  100. package/dist/modules/picking/legacy-color-picking.d.ts.map +1 -0
  101. package/dist/modules/picking/legacy-color-picking.js +7 -0
  102. package/dist/modules/picking/legacy-color-picking.js.map +1 -0
  103. package/dist/modules/picking/picking-manager.d.ts +29 -3
  104. package/dist/modules/picking/picking-manager.d.ts.map +1 -1
  105. package/dist/modules/picking/picking-manager.js +188 -41
  106. package/dist/modules/picking/picking-manager.js.map +1 -1
  107. package/dist/modules/picking/picking-uniforms.d.ts +13 -12
  108. package/dist/modules/picking/picking-uniforms.d.ts.map +1 -1
  109. package/dist/modules/picking/picking-uniforms.js +27 -14
  110. package/dist/modules/picking/picking-uniforms.js.map +1 -1
  111. package/dist/modules/picking/picking.d.ts +25 -0
  112. package/dist/modules/picking/picking.d.ts.map +1 -0
  113. package/dist/modules/picking/picking.js +18 -0
  114. package/dist/modules/picking/picking.js.map +1 -0
  115. package/dist/passes/get-fragment-shader.js +12 -27
  116. package/dist/passes/get-fragment-shader.js.map +1 -1
  117. package/dist/passes/shader-pass-renderer.d.ts +5 -7
  118. package/dist/passes/shader-pass-renderer.d.ts.map +1 -1
  119. package/dist/passes/shader-pass-renderer.js +16 -42
  120. package/dist/passes/shader-pass-renderer.js.map +1 -1
  121. package/dist/scenegraph/group-node.d.ts +5 -0
  122. package/dist/scenegraph/group-node.d.ts.map +1 -1
  123. package/dist/scenegraph/group-node.js +12 -0
  124. package/dist/scenegraph/group-node.js.map +1 -1
  125. package/dist/scenegraph/model-node.d.ts +2 -2
  126. package/dist/scenegraph/model-node.d.ts.map +1 -1
  127. package/dist/scenegraph/model-node.js.map +1 -1
  128. package/dist/scenegraph/scenegraph-node.d.ts +1 -1
  129. package/dist/scenegraph/scenegraph-node.d.ts.map +1 -1
  130. package/dist/scenegraph/scenegraph-node.js +23 -15
  131. package/dist/scenegraph/scenegraph-node.js.map +1 -1
  132. package/dist/shader-inputs.d.ts +9 -7
  133. package/dist/shader-inputs.d.ts.map +1 -1
  134. package/dist/shader-inputs.js +90 -13
  135. package/dist/shader-inputs.js.map +1 -1
  136. package/dist/utils/buffer-layout-order.d.ts.map +1 -1
  137. package/dist/utils/buffer-layout-order.js +12 -2
  138. package/dist/utils/buffer-layout-order.js.map +1 -1
  139. package/dist/utils/shader-module-utils.d.ts +7 -0
  140. package/dist/utils/shader-module-utils.d.ts.map +1 -0
  141. package/dist/utils/shader-module-utils.js +46 -0
  142. package/dist/utils/shader-module-utils.js.map +1 -0
  143. package/package.json +6 -6
  144. package/src/animation-loop/animation-loop.ts +89 -50
  145. package/src/animation-loop/make-animation-loop.ts +14 -5
  146. package/src/animation-loop/request-animation-frame.ts +32 -6
  147. package/src/compute/computation.ts +32 -17
  148. package/src/compute/swap.ts +13 -7
  149. package/src/debug/debug-framebuffer.ts +139 -61
  150. package/src/dynamic-texture/dynamic-texture.ts +730 -0
  151. package/src/dynamic-texture/texture-data.ts +336 -0
  152. package/src/{async-texture/texture-setters.ts.disabled → dynamic-texture/texture-data.ts.disabled} +1 -1
  153. package/src/geometries/cone-geometry.ts +6 -1
  154. package/src/geometries/cube-geometry.ts +7 -7
  155. package/src/geometries/cylinder-geometry.ts +5 -1
  156. package/src/geometries/ico-sphere-geometry.ts +3 -1
  157. package/src/geometry/gpu-geometry.ts +11 -3
  158. package/src/index.ts +38 -8
  159. package/src/material/material-factory.ts +157 -0
  160. package/src/material/material.ts +254 -0
  161. package/src/model/model.ts +196 -93
  162. package/src/model/split-uniforms-and-bindings.ts +8 -6
  163. package/src/models/billboard-texture-model.ts +90 -29
  164. package/src/models/billboard-texture-module.ts +1 -1
  165. package/src/models/clip-space.ts +7 -7
  166. package/src/models/directional-light-model.ts +32 -0
  167. package/src/models/light-model-utils.ts +587 -0
  168. package/src/models/point-light-model.ts +31 -0
  169. package/src/models/spot-light-model.ts +32 -0
  170. package/src/modules/picking/color-picking.ts +123 -122
  171. package/src/modules/picking/index-picking.ts +36 -16
  172. package/src/modules/picking/legacy-color-picking.ts +8 -0
  173. package/src/modules/picking/picking-manager.ts +252 -50
  174. package/src/modules/picking/picking-uniforms.ts +39 -24
  175. package/src/modules/picking/picking.ts +22 -0
  176. package/src/passes/get-fragment-shader.ts +12 -27
  177. package/src/passes/shader-pass-renderer.ts +25 -48
  178. package/src/scenegraph/group-node.ts +16 -0
  179. package/src/scenegraph/model-node.ts +2 -2
  180. package/src/scenegraph/scenegraph-node.ts +27 -16
  181. package/src/shader-inputs.ts +167 -26
  182. package/src/utils/buffer-layout-order.ts +18 -2
  183. package/src/utils/shader-module-utils.ts +65 -0
  184. package/dist/async-texture/async-texture.d.ts +0 -166
  185. package/dist/async-texture/async-texture.d.ts.map +0 -1
  186. package/dist/async-texture/async-texture.js +0 -386
  187. package/dist/async-texture/async-texture.js.map +0 -1
  188. package/dist/factories/pipeline-factory.d.ts +0 -37
  189. package/dist/factories/pipeline-factory.d.ts.map +0 -1
  190. package/dist/factories/pipeline-factory.js +0 -181
  191. package/dist/factories/pipeline-factory.js.map +0 -1
  192. package/dist/factories/shader-factory.d.ts +0 -22
  193. package/dist/factories/shader-factory.d.ts.map +0 -1
  194. package/dist/factories/shader-factory.js +0 -88
  195. package/dist/factories/shader-factory.js.map +0 -1
  196. package/src/async-texture/async-texture.ts +0 -551
  197. package/src/factories/pipeline-factory.ts +0 -224
  198. package/src/factories/shader-factory.ts +0 -103
@@ -0,0 +1,336 @@
1
+ import type {TypedArray, TextureFormat, ExternalImage} from '@luma.gl/core';
2
+ import {isExternalImage, getExternalImageSize} from '@luma.gl/core';
3
+
4
+ export type TextureImageSource = ExternalImage;
5
+
6
+ /**
7
+ * One mip level
8
+ * Basic data structure is similar to `ImageData`
9
+ * additional optional fields can describe compressed texture data.
10
+ */
11
+ export type TextureImageData = {
12
+ /** Preferred WebGPU style format string. */
13
+ textureFormat?: TextureFormat;
14
+ /** WebGPU style format string. Defaults to 'rgba8unorm' */
15
+ format?: TextureFormat;
16
+ /** Typed Array with the bytes of the image. @note beware row byte alignment requirements */
17
+ data: TypedArray;
18
+ /** Width of the image, in pixels, @note beware row byte alignment requirements */
19
+ width: number;
20
+ /** Height of the image, in rows */
21
+ height: number;
22
+ };
23
+
24
+ /**
25
+ * A single mip-level can be initialized by data or an ImageBitmap etc
26
+ * @note in the WebGPU spec a mip-level is called a subresource
27
+ */
28
+ export type TextureMipLevelData = TextureImageData | TextureImageSource;
29
+
30
+ /**
31
+ * Texture data for one image "slice" (which can consist of multiple miplevels)
32
+ * Thus data for one slice be a single mip level or an array of miplevels
33
+ * @note in the WebGPU spec each cross-section image in a 3D texture is called a "slice",
34
+ * in a array texture each image in the array is called an array "layer"
35
+ * luma.gl calls one image in a GPU texture a "slice" regardless of context.
36
+ */
37
+ export type TextureSliceData = TextureMipLevelData | TextureMipLevelData[];
38
+
39
+ /** Names of cube texture faces */
40
+ export type TextureCubeFace = '+X' | '-X' | '+Y' | '-Y' | '+Z' | '-Z';
41
+
42
+ /** Array of cube texture faces. @note: index in array is the face index */
43
+ // biome-ignore format: preserve layout
44
+ export const TEXTURE_CUBE_FACES = ['+X', '-X', '+Y', '-Y', '+Z', '-Z'] as const satisfies readonly TextureCubeFace[];
45
+
46
+ /** Map of cube texture face names to face indexes */
47
+ // biome-ignore format: preserve layout
48
+ export const TEXTURE_CUBE_FACE_MAP = {'+X': 0, '-X': 1, '+Y': 2, '-Y': 3, '+Z': 4, '-Z': 5} as const satisfies Record<TextureCubeFace, number>;
49
+
50
+ /** @todo - Define what data type is supported for 1D textures. TextureImageData with height = 1 */
51
+ export type Texture1DData = TextureSliceData;
52
+
53
+ /** Texture data can be one or more mip levels */
54
+ export type Texture2DData = TextureSliceData;
55
+
56
+ /** 6 face textures */
57
+ export type TextureCubeData = Record<TextureCubeFace, TextureSliceData>;
58
+
59
+ /** Array of textures */
60
+ export type Texture3DData = TextureSliceData[];
61
+
62
+ /** Array of textures */
63
+ export type TextureArrayData = TextureSliceData[];
64
+
65
+ /** Array of 6 face textures */
66
+ export type TextureCubeArrayData = Record<TextureCubeFace, TextureSliceData>[];
67
+
68
+ type TextureData =
69
+ | Texture1DData
70
+ | Texture3DData
71
+ | TextureArrayData
72
+ | TextureCubeArrayData
73
+ | TextureCubeData;
74
+
75
+ /** Sync data props */
76
+ export type TextureDataProps =
77
+ | {dimension: '1d'; data: Texture1DData | null}
78
+ | {dimension?: '2d'; data: Texture2DData | null}
79
+ | {dimension: '3d'; data: Texture3DData | null}
80
+ | {dimension: '2d-array'; data: TextureArrayData | null}
81
+ | {dimension: 'cube'; data: TextureCubeData | null}
82
+ | {dimension: 'cube-array'; data: TextureCubeArrayData | null};
83
+
84
+ /** Async data props */
85
+ export type TextureDataAsyncProps =
86
+ | {dimension: '1d'; data?: Promise<Texture1DData> | Texture1DData | null}
87
+ | {dimension?: '2d'; data?: Promise<Texture2DData> | Texture2DData | null}
88
+ | {dimension: '3d'; data?: Promise<Texture3DData> | Texture3DData | null}
89
+ | {dimension: '2d-array'; data?: Promise<TextureArrayData> | TextureArrayData | null}
90
+ | {dimension: 'cube'; data?: Promise<TextureCubeData> | TextureCubeData | null}
91
+ | {dimension: 'cube-array'; data?: Promise<TextureCubeArrayData> | TextureCubeArrayData | null};
92
+
93
+ /** Describes data for one sub resource (one mip level of one slice (depth or array layer)) */
94
+ export type TextureSubresource = {
95
+ /** slice (depth or array layer)) */
96
+ z: number;
97
+ /** mip level (0 - max mip levels) */
98
+ mipLevel: number;
99
+ } & (
100
+ | {
101
+ type: 'external-image';
102
+ image: ExternalImage;
103
+ /** @deprecated is this an appropriate place for this flag? */
104
+ flipY?: boolean;
105
+ }
106
+ | {
107
+ type: 'texture-data';
108
+ data: TextureImageData;
109
+ textureFormat?: TextureFormat;
110
+ }
111
+ );
112
+
113
+ /** Check if texture data is a typed array */
114
+ export function isTextureSliceData(data: TextureData): data is TextureImageData {
115
+ const typedArray = (data as TextureImageData)?.data;
116
+ return ArrayBuffer.isView(typedArray);
117
+ }
118
+
119
+ export function getFirstMipLevel(layer: TextureSliceData | null): TextureMipLevelData | null {
120
+ if (!layer) return null;
121
+ return Array.isArray(layer) ? (layer[0] ?? null) : layer;
122
+ }
123
+
124
+ export function getTextureSizeFromData(
125
+ props: TextureDataProps
126
+ ): {width: number; height: number} | null {
127
+ const {dimension, data} = props;
128
+ if (!data) {
129
+ return null;
130
+ }
131
+
132
+ switch (dimension) {
133
+ case '1d': {
134
+ const mipLevel = getFirstMipLevel(data);
135
+ if (!mipLevel) return null;
136
+ const {width} = getTextureMipLevelSize(mipLevel);
137
+ return {width, height: 1};
138
+ }
139
+ case '2d': {
140
+ const mipLevel = getFirstMipLevel(data);
141
+ return mipLevel ? getTextureMipLevelSize(mipLevel) : null;
142
+ }
143
+ case '3d':
144
+ case '2d-array': {
145
+ if (!Array.isArray(data) || data.length === 0) return null;
146
+ const mipLevel = getFirstMipLevel(data[0]);
147
+ return mipLevel ? getTextureMipLevelSize(mipLevel) : null;
148
+ }
149
+ case 'cube': {
150
+ const face = (Object.keys(data)[0] as TextureCubeFace) ?? null;
151
+ if (!face) return null;
152
+ const faceData = (data as Record<TextureCubeFace, TextureSliceData>)[face];
153
+ const mipLevel = getFirstMipLevel(faceData);
154
+ return mipLevel ? getTextureMipLevelSize(mipLevel) : null;
155
+ }
156
+ case 'cube-array': {
157
+ if (!Array.isArray(data) || data.length === 0) return null;
158
+ const firstCube = data[0];
159
+ const face = (Object.keys(firstCube)[0] as TextureCubeFace) ?? null;
160
+ if (!face) return null;
161
+ const mipLevel = getFirstMipLevel(firstCube[face]);
162
+ return mipLevel ? getTextureMipLevelSize(mipLevel) : null;
163
+ }
164
+ default:
165
+ return null;
166
+ }
167
+ }
168
+
169
+ function getTextureMipLevelSize(data: TextureMipLevelData): {width: number; height: number} {
170
+ if (isExternalImage(data)) {
171
+ return getExternalImageSize(data);
172
+ }
173
+ if (typeof data === 'object' && 'width' in data && 'height' in data) {
174
+ return {width: data.width, height: data.height};
175
+ }
176
+ throw new Error('Unsupported mip-level data');
177
+ }
178
+
179
+ /** Type guard: is a mip-level `TextureImageData` (vs ExternalImage or bare typed array) */
180
+ function isTextureImageData(data: unknown): data is TextureImageData {
181
+ return (
182
+ typeof data === 'object' &&
183
+ data !== null &&
184
+ 'data' in data &&
185
+ 'width' in data &&
186
+ 'height' in data
187
+ );
188
+ }
189
+
190
+ function isTypedArrayMipLevelData(data: unknown): data is TypedArray {
191
+ return ArrayBuffer.isView(data);
192
+ }
193
+
194
+ export function resolveTextureImageFormat(data: TextureImageData): TextureFormat | undefined {
195
+ const {textureFormat, format} = data;
196
+ if (textureFormat && format && textureFormat !== format) {
197
+ throw new Error(
198
+ `Conflicting texture formats "${textureFormat}" and "${format}" provided for the same mip level`
199
+ );
200
+ }
201
+ return textureFormat ?? format;
202
+ }
203
+
204
+ /** Resolve size for a single mip-level datum */
205
+ // function getTextureMipLevelSizeFromData(data: TextureMipLevelData): {
206
+ // width: number;
207
+ // height: number;
208
+ // } {
209
+ // if (this.device.isExternalImage(data)) {
210
+ // return this.device.getExternalImageSize(data);
211
+ // }
212
+ // if (this.isTextureImageData(data)) {
213
+ // return {width: data.width, height: data.height};
214
+ // }
215
+ // // Fallback (should not happen with current types)
216
+ // throw new Error('Unsupported mip-level data');
217
+ // }
218
+
219
+ /** Convert cube face label to depth index */
220
+ export function getCubeFaceIndex(face: TextureCubeFace): number {
221
+ const idx = TEXTURE_CUBE_FACE_MAP[face];
222
+ if (idx === undefined) throw new Error(`Invalid cube face: ${face}`);
223
+ return idx;
224
+ }
225
+
226
+ /** Convert cube face label to texture slice index. Index can be used with `setTexture2DData()`. */
227
+ export function getCubeArrayFaceIndex(cubeIndex: number, face: TextureCubeFace): number {
228
+ return 6 * cubeIndex + getCubeFaceIndex(face);
229
+ }
230
+
231
+ // ------------------ Upload helpers ------------------
232
+
233
+ /** Experimental: Set multiple mip levels (1D) */
234
+ export function getTexture1DSubresources(data: Texture1DData): TextureSubresource[] {
235
+ // Not supported in WebGL; left explicit
236
+ throw new Error('setTexture1DData not supported in WebGL.');
237
+ // const subresources: TextureSubresource[] = [];
238
+ // return subresources;
239
+ }
240
+
241
+ /** Normalize 2D layer payload into an array of mip-level items */
242
+ function _normalizeTexture2DData(
243
+ data: Texture2DData
244
+ ): (TextureImageData | ExternalImage | TypedArray)[] {
245
+ return Array.isArray(data) ? data : [data];
246
+ }
247
+
248
+ /** Experimental: Set multiple mip levels (2D), optionally at `z` (depth/array index) */
249
+ export function getTexture2DSubresources(
250
+ slice: number,
251
+ lodData: Texture2DData,
252
+ baseLevelSize?: {width: number; height: number},
253
+ textureFormat?: TextureFormat
254
+ ): TextureSubresource[] {
255
+ const lodArray = _normalizeTexture2DData(lodData);
256
+ const z = slice;
257
+
258
+ const subresources: TextureSubresource[] = [];
259
+
260
+ for (let mipLevel = 0; mipLevel < lodArray.length; mipLevel++) {
261
+ const imageData = lodArray[mipLevel];
262
+ if (isExternalImage(imageData)) {
263
+ subresources.push({
264
+ type: 'external-image',
265
+ image: imageData,
266
+ z,
267
+ mipLevel
268
+ });
269
+ } else if (isTextureImageData(imageData)) {
270
+ subresources.push({
271
+ type: 'texture-data',
272
+ data: imageData,
273
+ textureFormat: resolveTextureImageFormat(imageData),
274
+ z,
275
+ mipLevel
276
+ });
277
+ } else if (isTypedArrayMipLevelData(imageData) && baseLevelSize) {
278
+ subresources.push({
279
+ type: 'texture-data',
280
+ data: {
281
+ data: imageData,
282
+ width: Math.max(1, baseLevelSize.width >> mipLevel),
283
+ height: Math.max(1, baseLevelSize.height >> mipLevel),
284
+ ...(textureFormat ? {format: textureFormat} : {})
285
+ },
286
+ textureFormat,
287
+ z,
288
+ mipLevel
289
+ });
290
+ } else {
291
+ throw new Error('Unsupported 2D mip-level payload');
292
+ }
293
+ }
294
+
295
+ return subresources;
296
+ }
297
+
298
+ /** 3D: multiple depth slices, each may carry multiple mip levels */
299
+ export function getTexture3DSubresources(data: Texture3DData): TextureSubresource[] {
300
+ const subresources: TextureSubresource[] = [];
301
+ for (let depth = 0; depth < data.length; depth++) {
302
+ subresources.push(...getTexture2DSubresources(depth, data[depth]));
303
+ }
304
+ return subresources;
305
+ }
306
+
307
+ /** 2D array: multiple layers, each may carry multiple mip levels */
308
+ export function getTextureArraySubresources(data: TextureArrayData): TextureSubresource[] {
309
+ const subresources: TextureSubresource[] = [];
310
+ for (let layer = 0; layer < data.length; layer++) {
311
+ subresources.push(...getTexture2DSubresources(layer, data[layer]));
312
+ }
313
+ return subresources;
314
+ }
315
+
316
+ /** Cube: 6 faces, each may carry multiple mip levels */
317
+ export function getTextureCubeSubresources(data: TextureCubeData): TextureSubresource[] {
318
+ const subresources: TextureSubresource[] = [];
319
+ for (const [face, faceData] of Object.entries(data) as [TextureCubeFace, TextureSliceData][]) {
320
+ const faceDepth = getCubeFaceIndex(face);
321
+ subresources.push(...getTexture2DSubresources(faceDepth, faceData));
322
+ }
323
+ return subresources;
324
+ }
325
+
326
+ /** Cube array: multiple cubes (faces×layers), each face may carry multiple mips */
327
+ export function getTextureCubeArraySubresources(data: TextureCubeArrayData): TextureSubresource[] {
328
+ const subresources: TextureSubresource[] = [];
329
+ data.forEach((cubeData, cubeIndex) => {
330
+ for (const [face, faceData] of Object.entries(cubeData)) {
331
+ const faceDepth = getCubeArrayFaceIndex(cubeIndex, face as TextureCubeFace);
332
+ subresources.push(...getTexture2DSubresources(faceDepth, faceData));
333
+ }
334
+ });
335
+ return subresources;
336
+ }
@@ -131,7 +131,7 @@ export function normalizeTextureData(
131
131
 
132
132
  /** Convert luma.gl cubemap face constants to depth index */
133
133
  export function getCubeFaceDepth(face: TextureCubeFace): number {
134
- // prettier-ignore
134
+ // biome-ignore format: preserve layout
135
135
  switch (face) {
136
136
  case '+X': return 0;
137
137
  case '-X': return 1;
@@ -2,13 +2,18 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
+ import type {TruncatedConeGeometryProps} from './truncated-cone-geometry';
5
6
  import {TruncatedConeGeometry} from './truncated-cone-geometry';
6
7
  import {uid} from '../utils/uid';
7
8
 
8
- export type ConeGeometryProps = {
9
+ export type ConeGeometryProps = Omit<
10
+ TruncatedConeGeometryProps,
11
+ 'topRadius' | 'bottomRadius' | 'topCap' | 'bottomCap'
12
+ > & {
9
13
  id?: string;
10
14
  radius?: number;
11
15
  cap?: boolean;
16
+ attributes?: any;
12
17
  };
13
18
 
14
19
  export class ConeGeometry extends TruncatedConeGeometry {
@@ -35,13 +35,13 @@ export class CubeGeometry extends Geometry {
35
35
  }
36
36
  }
37
37
 
38
- // prettier-ignore
38
+ // biome-ignore format: preserve layout
39
39
  const CUBE_INDICES = new Uint16Array([
40
40
  0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13,
41
41
  14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23
42
42
  ]);
43
43
 
44
- // prettier-ignore
44
+ // biome-ignore format: preserve layout
45
45
  const CUBE_POSITIONS = new Float32Array([
46
46
  -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1,
47
47
  -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1,
@@ -52,7 +52,7 @@ const CUBE_POSITIONS = new Float32Array([
52
52
  ]);
53
53
 
54
54
  // TODO - could be Uint8
55
- // prettier-ignore
55
+ // biome-ignore format: preserve layout
56
56
  const CUBE_NORMALS = new Float32Array([
57
57
  // Front face
58
58
  0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1,
@@ -68,7 +68,7 @@ const CUBE_NORMALS = new Float32Array([
68
68
  -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0
69
69
  ]);
70
70
 
71
- // prettier-ignore
71
+ // biome-ignore format: preserve layout
72
72
  const CUBE_TEX_COORDS = new Float32Array([
73
73
  // Front face
74
74
  0, 0, 1, 0, 1, 1, 0, 1,
@@ -85,7 +85,7 @@ const CUBE_TEX_COORDS = new Float32Array([
85
85
  ]);
86
86
 
87
87
  // float4 position
88
- // prettier-ignore
88
+ // biome-ignore format: preserve layout
89
89
  export const CUBE_NON_INDEXED_POSITIONS = new Float32Array([
90
90
  1, -1, 1,
91
91
  -1, -1, 1,
@@ -131,7 +131,7 @@ export const CUBE_NON_INDEXED_POSITIONS = new Float32Array([
131
131
  ]);
132
132
 
133
133
  // float2 uv,
134
- // prettier-ignore
134
+ // biome-ignore format: preserve layout
135
135
  export const CUBE_NON_INDEXED_TEX_COORDS = new Float32Array([
136
136
  1, 1,
137
137
  0, 1,
@@ -177,7 +177,7 @@ export const CUBE_NON_INDEXED_TEX_COORDS = new Float32Array([
177
177
  ]);
178
178
 
179
179
  // float4 color
180
- // prettier-ignore
180
+ // biome-ignore format: preserve layout
181
181
  export const CUBE_NON_INDEXED_COLORS = new Float32Array([
182
182
  1, 0, 1, 1,
183
183
  0, 0, 1, 1,
@@ -2,10 +2,14 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
+ import type {TruncatedConeGeometryProps} from './truncated-cone-geometry';
5
6
  import {TruncatedConeGeometry} from './truncated-cone-geometry';
6
7
  import {uid} from '../utils/uid';
7
8
 
8
- export type CylinderGeometryProps = {
9
+ export type CylinderGeometryProps = Omit<
10
+ TruncatedConeGeometryProps,
11
+ 'topRadius' | 'bottomRadius'
12
+ > & {
9
13
  id?: string;
10
14
  radius?: number;
11
15
  attributes?: any;
@@ -75,7 +75,9 @@ function tesselateIcosaHedron(props: IcoSphereGeometryProps) {
75
75
 
76
76
  positions.push(xm, ym, zm);
77
77
 
78
- return (pointMemo[key] = positions.length / 3 - 1);
78
+ const pointIndex = positions.length / 3 - 1;
79
+ pointMemo[key] = pointIndex;
80
+ return pointIndex;
79
81
  };
80
82
  })();
81
83
 
@@ -3,7 +3,7 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
5
  import type {PrimitiveTopology, BufferLayout} from '@luma.gl/core';
6
- import {Device, Buffer, getVertexFormatFromAttribute} from '@luma.gl/core';
6
+ import {Device, Buffer, vertexFormatDecoder} from '@luma.gl/core';
7
7
  import type {Geometry} from '../geometry/geometry';
8
8
  import {uid} from '../utils/uid';
9
9
 
@@ -117,6 +117,9 @@ export function getAttributeBuffersFromGeometry(
117
117
  case 'TEXCOORD_0':
118
118
  name = 'texCoords';
119
119
  break;
120
+ case 'TEXCOORD_1':
121
+ name = 'texCoords1';
122
+ break;
120
123
  case 'COLOR_0':
121
124
  name = 'colors';
122
125
  break;
@@ -127,8 +130,13 @@ export function getAttributeBuffersFromGeometry(
127
130
  id: `${attributeName}-buffer`
128
131
  });
129
132
  const {value, size, normalized} = attribute;
130
- // @ts-expect-error
131
- bufferLayout.push({name, format: getVertexFormatFromAttribute(value, size, normalized)});
133
+ if (size === undefined) {
134
+ throw new Error(`Attribute ${attributeName} is missing a size`);
135
+ }
136
+ bufferLayout.push({
137
+ name,
138
+ format: vertexFormatDecoder.getVertexFormatFromAttribute(value, size, normalized)
139
+ });
132
140
  }
133
141
  }
134
142
 
package/src/index.ts CHANGED
@@ -19,6 +19,10 @@ export {makeAnimationLoop} from './animation-loop/make-animation-loop';
19
19
 
20
20
  export type {ModelProps} from './model/model';
21
21
  export {Model} from './model/model';
22
+ export type {MaterialProps} from './material/material';
23
+ export {Material} from './material/material';
24
+ export type {MaterialFactoryProps} from './material/material-factory';
25
+ export {MaterialFactory} from './material/material-factory';
22
26
 
23
27
  // Transforms
24
28
  export type {BufferTransformProps} from './compute/buffer-transform';
@@ -26,14 +30,20 @@ export {BufferTransform} from './compute/buffer-transform';
26
30
  export type {TextureTransformProps} from './compute/texture-transform';
27
31
  export {TextureTransform} from './compute/texture-transform';
28
32
 
29
- export {PipelineFactory} from './factories/pipeline-factory';
30
- export {ShaderFactory} from './factories/shader-factory';
31
-
32
33
  // Models
33
34
  export type {ClipSpaceProps} from './models/clip-space';
34
35
  export {ClipSpace} from './models/clip-space';
35
36
  export type {BackgroundTextureModelProps} from './models/billboard-texture-model';
36
37
  export {BackgroundTextureModel} from './models/billboard-texture-model';
38
+ export type {
39
+ BaseLightModelProps,
40
+ PointLightModelProps,
41
+ SpotLightModelProps,
42
+ DirectionalLightModelProps
43
+ } from './models/light-model-utils';
44
+ export {PointLightModel} from './models/point-light-model';
45
+ export {SpotLightModel} from './models/spot-light-model';
46
+ export {DirectionalLightModel} from './models/directional-light-model';
37
47
 
38
48
  // Scenegraph Core nodes
39
49
  export {ScenegraphNode} from './scenegraph/scenegraph-node';
@@ -83,19 +93,32 @@ export {Computation} from './compute/computation';
83
93
  export type {
84
94
  TextureCubeFace,
85
95
  TextureImageData,
86
- TextureData,
87
96
  Texture1DData,
88
97
  Texture2DData,
89
98
  Texture3DData,
90
99
  TextureCubeData,
91
100
  TextureArrayData,
92
101
  TextureCubeArrayData
93
- } from './async-texture/async-texture';
102
+ } from './dynamic-texture/texture-data';
94
103
 
95
- export type {AsyncTextureProps} from './async-texture/async-texture';
96
- export {AsyncTexture} from './async-texture/async-texture';
104
+ export type {DynamicTextureProps} from './dynamic-texture/dynamic-texture';
105
+ export {DynamicTexture} from './dynamic-texture/dynamic-texture';
97
106
 
98
- export {PickingManager} from './modules/picking/picking-manager';
107
+ export type {
108
+ PickInfo,
109
+ PickingMode,
110
+ ResolvedPickingMode,
111
+ PickingBackend,
112
+ PickingManagerProps,
113
+ ResolvedPickingBackend
114
+ } from './modules/picking/picking-manager';
115
+ export {
116
+ PickingManager,
117
+ supportsIndexPicking,
118
+ resolvePickingMode,
119
+ resolvePickingBackend
120
+ } from './modules/picking/picking-manager';
121
+ export {picking} from './modules/picking/picking';
99
122
  export {picking as indexPicking} from './modules/picking/index-picking';
100
123
  export {picking as colorPicking} from './modules/picking/color-picking';
101
124
 
@@ -107,3 +130,10 @@ export {
107
130
  // DEPRECATED
108
131
 
109
132
  export {LegacyPickingManager} from './modules/picking/legacy-picking-manager';
133
+ export {legacyColorPicking} from './modules/picking/legacy-color-picking';
134
+
135
+ import {DynamicTexture, type DynamicTextureProps} from './dynamic-texture/dynamic-texture';
136
+ /** @deprecated use DynamicTexture */
137
+ export const AsyncTexture = DynamicTexture;
138
+ /** @deprecated use DynamicTextureProps */
139
+ export type AsyncTextureProps = DynamicTextureProps;