@luma.gl/gltf 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.
- package/dist/dist.dev.js +4064 -1967
- package/dist/dist.min.js +117 -46
- package/dist/gltf/animations/animations.d.ts +57 -5
- package/dist/gltf/animations/animations.d.ts.map +1 -1
- package/dist/gltf/animations/interpolate.d.ts +6 -3
- package/dist/gltf/animations/interpolate.d.ts.map +1 -1
- package/dist/gltf/animations/interpolate.js +47 -51
- package/dist/gltf/animations/interpolate.js.map +1 -1
- package/dist/gltf/create-gltf-model.d.ts +15 -1
- package/dist/gltf/create-gltf-model.d.ts.map +1 -1
- package/dist/gltf/create-gltf-model.js +168 -43
- package/dist/gltf/create-gltf-model.js.map +1 -1
- package/dist/gltf/create-scenegraph-from-gltf.d.ts +39 -2
- package/dist/gltf/create-scenegraph-from-gltf.d.ts.map +1 -1
- package/dist/gltf/create-scenegraph-from-gltf.js +76 -6
- package/dist/gltf/create-scenegraph-from-gltf.js.map +1 -1
- package/dist/gltf/gltf-animator.d.ts +37 -0
- package/dist/gltf/gltf-animator.d.ts.map +1 -1
- package/dist/gltf/gltf-animator.js +112 -17
- package/dist/gltf/gltf-animator.js.map +1 -1
- package/dist/gltf/gltf-extension-support.d.ts +13 -0
- package/dist/gltf/gltf-extension-support.d.ts.map +1 -0
- package/dist/gltf/gltf-extension-support.js +178 -0
- package/dist/gltf/gltf-extension-support.js.map +1 -0
- package/dist/index.cjs +1806 -298
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/parsers/parse-gltf-animations.d.ts +1 -0
- package/dist/parsers/parse-gltf-animations.d.ts.map +1 -1
- package/dist/parsers/parse-gltf-animations.js +373 -27
- package/dist/parsers/parse-gltf-animations.js.map +1 -1
- package/dist/parsers/parse-gltf-lights.d.ts +5 -0
- package/dist/parsers/parse-gltf-lights.d.ts.map +1 -0
- package/dist/parsers/parse-gltf-lights.js +163 -0
- package/dist/parsers/parse-gltf-lights.js.map +1 -0
- package/dist/parsers/parse-gltf.d.ts +19 -2
- package/dist/parsers/parse-gltf.d.ts.map +1 -1
- package/dist/parsers/parse-gltf.js +120 -67
- package/dist/parsers/parse-gltf.js.map +1 -1
- package/dist/parsers/parse-pbr-material.d.ts +115 -2
- package/dist/parsers/parse-pbr-material.d.ts.map +1 -1
- package/dist/parsers/parse-pbr-material.js +602 -53
- package/dist/parsers/parse-pbr-material.js.map +1 -1
- package/dist/pbr/pbr-environment.d.ts +10 -4
- package/dist/pbr/pbr-environment.d.ts.map +1 -1
- package/dist/pbr/pbr-environment.js +18 -15
- package/dist/pbr/pbr-environment.js.map +1 -1
- package/dist/pbr/pbr-material.d.ts +13 -3
- package/dist/pbr/pbr-material.d.ts.map +1 -1
- package/dist/pbr/texture-transform.d.ts +24 -0
- package/dist/pbr/texture-transform.d.ts.map +1 -0
- package/dist/pbr/texture-transform.js +98 -0
- package/dist/pbr/texture-transform.js.map +1 -0
- package/dist/webgl-to-webgpu/convert-webgl-attribute.d.ts +12 -1
- package/dist/webgl-to-webgpu/convert-webgl-attribute.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-attribute.js +3 -0
- package/dist/webgl-to-webgpu/convert-webgl-attribute.js.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-sampler.d.ts +11 -5
- package/dist/webgl-to-webgpu/convert-webgl-sampler.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-sampler.js +16 -12
- package/dist/webgl-to-webgpu/convert-webgl-sampler.js.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-topology.d.ts +2 -9
- package/dist/webgl-to-webgpu/convert-webgl-topology.d.ts.map +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-topology.js +3 -15
- package/dist/webgl-to-webgpu/convert-webgl-topology.js.map +1 -1
- package/dist/webgl-to-webgpu/gltf-webgl-constants.d.ts +27 -0
- package/dist/webgl-to-webgpu/gltf-webgl-constants.d.ts.map +1 -0
- package/dist/webgl-to-webgpu/gltf-webgl-constants.js +34 -0
- package/dist/webgl-to-webgpu/gltf-webgl-constants.js.map +1 -0
- package/package.json +8 -9
- package/src/gltf/animations/animations.ts +88 -6
- package/src/gltf/animations/interpolate.ts +84 -96
- package/src/gltf/create-gltf-model.ts +233 -48
- package/src/gltf/create-scenegraph-from-gltf.ts +134 -11
- package/src/gltf/gltf-animator.ts +198 -20
- package/src/gltf/gltf-extension-support.ts +226 -0
- package/src/index.ts +11 -2
- package/src/parsers/parse-gltf-animations.ts +533 -32
- package/src/parsers/parse-gltf-lights.ts +218 -0
- package/src/parsers/parse-gltf.ts +189 -96
- package/src/parsers/parse-pbr-material.ts +974 -79
- package/src/pbr/pbr-environment.ts +44 -21
- package/src/pbr/pbr-material.ts +18 -3
- package/src/pbr/texture-transform.ts +263 -0
- package/src/webgl-to-webgpu/convert-webgl-attribute.ts +12 -1
- package/src/webgl-to-webgpu/convert-webgl-sampler.ts +38 -29
- package/src/webgl-to-webgpu/convert-webgl-topology.ts +3 -15
- package/src/webgl-to-webgpu/gltf-webgl-constants.ts +35 -0
- package/dist/utils/deep-copy.d.ts +0 -3
- package/dist/utils/deep-copy.d.ts.map +0 -1
- package/dist/utils/deep-copy.js +0 -21
- package/dist/utils/deep-copy.js.map +0 -1
- package/src/utils/deep-copy.ts +0 -22
|
@@ -3,26 +3,39 @@
|
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
5
|
import {Device, SamplerProps} from '@luma.gl/core';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
DynamicTexture,
|
|
8
|
+
type Texture2DData,
|
|
9
|
+
type TextureCubeData,
|
|
10
|
+
type TextureCubeFace
|
|
11
|
+
} from '@luma.gl/engine';
|
|
7
12
|
import {loadImageTexture} from '@loaders.gl/textures';
|
|
8
13
|
|
|
9
14
|
/** Environment textures for PBR module */
|
|
10
15
|
export type PBREnvironment = {
|
|
11
16
|
/** Bi-directional Reflectance Distribution Function (BRDF) lookup table */
|
|
12
|
-
brdfLutTexture:
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
brdfLutTexture: DynamicTexture;
|
|
18
|
+
/** Diffuse irradiance cubemap. */
|
|
19
|
+
diffuseEnvSampler: DynamicTexture;
|
|
20
|
+
/** Specular reflection cubemap with mip chain. */
|
|
21
|
+
specularEnvSampler: DynamicTexture;
|
|
15
22
|
};
|
|
16
23
|
|
|
24
|
+
/** Configuration used to load an image-based lighting environment. */
|
|
17
25
|
export type PBREnvironmentProps = {
|
|
26
|
+
/** URL of the BRDF lookup texture. */
|
|
18
27
|
brdfLutUrl: string;
|
|
28
|
+
/** Callback that returns the URL for a diffuse or specular cubemap face and mip level. */
|
|
19
29
|
getTexUrl: (name: string, dir: number, level: number) => string;
|
|
30
|
+
/** Number of mip levels in the specular environment map. */
|
|
20
31
|
specularMipLevels?: number;
|
|
21
32
|
};
|
|
22
33
|
|
|
23
34
|
/** Loads textures for PBR environment */
|
|
24
35
|
export function loadPBREnvironment(device: Device, props: PBREnvironmentProps): PBREnvironment {
|
|
25
|
-
const
|
|
36
|
+
const specularMipLevels = props.specularMipLevels ?? 1;
|
|
37
|
+
|
|
38
|
+
const brdfLutTexture = new DynamicTexture(device, {
|
|
26
39
|
id: 'brdfLUT',
|
|
27
40
|
sampler: {
|
|
28
41
|
addressModeU: 'clamp-to-edge',
|
|
@@ -36,7 +49,10 @@ export function loadPBREnvironment(device: Device, props: PBREnvironmentProps):
|
|
|
36
49
|
|
|
37
50
|
const diffuseEnvSampler = makeCube(device, {
|
|
38
51
|
id: 'DiffuseEnvSampler',
|
|
39
|
-
getTextureForFace:
|
|
52
|
+
getTextureForFace: face =>
|
|
53
|
+
loadImageTexture(
|
|
54
|
+
props.getTexUrl('diffuse', FACES.indexOf(face), 0)
|
|
55
|
+
) as Promise<Texture2DData>,
|
|
40
56
|
sampler: {
|
|
41
57
|
addressModeU: 'clamp-to-edge',
|
|
42
58
|
addressModeV: 'clamp-to-edge',
|
|
@@ -47,13 +63,13 @@ export function loadPBREnvironment(device: Device, props: PBREnvironmentProps):
|
|
|
47
63
|
|
|
48
64
|
const specularEnvSampler = makeCube(device, {
|
|
49
65
|
id: 'SpecularEnvSampler',
|
|
50
|
-
getTextureForFace: (
|
|
51
|
-
const imageArray: Promise<
|
|
52
|
-
|
|
53
|
-
for (let lod = 0; lod
|
|
54
|
-
imageArray.push(loadImageTexture(props.getTexUrl('specular',
|
|
66
|
+
getTextureForFace: (face: TextureCubeFace) => {
|
|
67
|
+
const imageArray: Array<Promise<unknown>> = [];
|
|
68
|
+
const direction = FACES.indexOf(face);
|
|
69
|
+
for (let lod = 0; lod < specularMipLevels; lod++) {
|
|
70
|
+
imageArray.push(loadImageTexture(props.getTexUrl('specular', direction, lod)));
|
|
55
71
|
}
|
|
56
|
-
return imageArray
|
|
72
|
+
return Promise.all(imageArray) as Promise<Texture2DData>;
|
|
57
73
|
},
|
|
58
74
|
sampler: {
|
|
59
75
|
addressModeU: 'clamp-to-edge',
|
|
@@ -71,8 +87,9 @@ export function loadPBREnvironment(device: Device, props: PBREnvironmentProps):
|
|
|
71
87
|
}
|
|
72
88
|
|
|
73
89
|
// TODO put somewhere common
|
|
74
|
-
const FACES = [
|
|
90
|
+
const FACES: TextureCubeFace[] = ['+X', '-X', '+Y', '-Y', '+Z', '-Z'];
|
|
75
91
|
|
|
92
|
+
/** Construction props for an asynchronously loaded cubemap. */
|
|
76
93
|
function makeCube(
|
|
77
94
|
device: Device,
|
|
78
95
|
{
|
|
@@ -80,22 +97,28 @@ function makeCube(
|
|
|
80
97
|
getTextureForFace,
|
|
81
98
|
sampler
|
|
82
99
|
}: {
|
|
100
|
+
/** Debug id assigned to the created texture. */
|
|
83
101
|
id: string;
|
|
84
|
-
|
|
102
|
+
/** Returns the image or mip-array promise for one cubemap face. */
|
|
103
|
+
getTextureForFace: (face: TextureCubeFace) => Promise<Texture2DData>;
|
|
104
|
+
/** Sampler configuration shared across faces. */
|
|
85
105
|
sampler: SamplerProps;
|
|
86
106
|
}
|
|
87
|
-
):
|
|
88
|
-
const data =
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
107
|
+
): DynamicTexture {
|
|
108
|
+
const data: Promise<TextureCubeData> = Promise.all(
|
|
109
|
+
FACES.map(face => getTextureForFace(face))
|
|
110
|
+
).then(faceDataArray => {
|
|
111
|
+
const cubeData = {} as TextureCubeData;
|
|
112
|
+
FACES.forEach((face, index) => {
|
|
113
|
+
cubeData[face] = faceDataArray[index];
|
|
114
|
+
});
|
|
115
|
+
return cubeData;
|
|
92
116
|
});
|
|
93
|
-
return new
|
|
117
|
+
return new DynamicTexture(device, {
|
|
94
118
|
id,
|
|
95
119
|
dimension: 'cube',
|
|
96
120
|
mipmaps: false,
|
|
97
121
|
sampler,
|
|
98
|
-
// @ts-expect-error
|
|
99
122
|
data
|
|
100
123
|
});
|
|
101
124
|
}
|
package/src/pbr/pbr-material.ts
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
import type {Texture, Parameters} from '@luma.gl/core';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
IBLBindings,
|
|
4
|
+
PBRMaterialBindings,
|
|
5
|
+
PBRMaterialUniforms,
|
|
6
|
+
PBRProjectionProps
|
|
7
|
+
} from '@luma.gl/shadertools';
|
|
3
8
|
|
|
9
|
+
type ParsedPBRMaterialUniforms = Partial<PBRProjectionProps & PBRMaterialUniforms> & {
|
|
10
|
+
clearcoatRoughnessMapEnabled?: boolean;
|
|
11
|
+
sheenRoughnessMapEnabled?: boolean;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/** Material state extracted from a glTF primitive for consumption by the PBR shader module. */
|
|
4
15
|
export type ParsedPBRMaterial = {
|
|
16
|
+
/** Shader defines inferred from geometry and material features. */
|
|
5
17
|
readonly defines: Record<string, boolean>;
|
|
6
|
-
|
|
7
|
-
readonly
|
|
18
|
+
/** Texture and sampler bindings for the PBR shader module. */
|
|
19
|
+
readonly bindings: Partial<PBRMaterialBindings & IBLBindings>;
|
|
20
|
+
/** Uniform values for the projection and PBR shader modules. */
|
|
21
|
+
readonly uniforms: ParsedPBRMaterialUniforms;
|
|
22
|
+
/** Render pipeline parameters derived from the glTF material. */
|
|
8
23
|
readonly parameters: Parameters;
|
|
9
24
|
/** @deprecated Use parameters */
|
|
10
25
|
readonly glParameters: Record<string, any>;
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import {Matrix3} from '@math.gl/core';
|
|
6
|
+
|
|
7
|
+
export type PBRTextureTransformSlot =
|
|
8
|
+
| 'baseColor'
|
|
9
|
+
| 'metallicRoughness'
|
|
10
|
+
| 'normal'
|
|
11
|
+
| 'occlusion'
|
|
12
|
+
| 'emissive'
|
|
13
|
+
| 'specularColor'
|
|
14
|
+
| 'specularIntensity'
|
|
15
|
+
| 'transmission'
|
|
16
|
+
| 'thickness'
|
|
17
|
+
| 'clearcoat'
|
|
18
|
+
| 'clearcoatRoughness'
|
|
19
|
+
| 'clearcoatNormal'
|
|
20
|
+
| 'sheenColor'
|
|
21
|
+
| 'sheenRoughness'
|
|
22
|
+
| 'iridescence'
|
|
23
|
+
| 'iridescenceThickness'
|
|
24
|
+
| 'anisotropy';
|
|
25
|
+
|
|
26
|
+
export type PBRTextureTransformPath = 'offset' | 'rotation' | 'scale';
|
|
27
|
+
|
|
28
|
+
export type PBRTextureTransform = {
|
|
29
|
+
offset: [number, number];
|
|
30
|
+
rotation: number;
|
|
31
|
+
scale: [number, number];
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type PBRTextureTransformSlotDefinition = {
|
|
35
|
+
slot: PBRTextureTransformSlot;
|
|
36
|
+
binding: string;
|
|
37
|
+
displayName: string;
|
|
38
|
+
pathSegments: string[];
|
|
39
|
+
uvSetUniform: string;
|
|
40
|
+
uvTransformUniform: string;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const IDENTITY_TEXTURE_TRANSFORM: PBRTextureTransform = {
|
|
44
|
+
offset: [0, 0],
|
|
45
|
+
rotation: 0,
|
|
46
|
+
scale: [1, 1]
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const TEXTURE_TRANSFORM_SLOT_DEFINITIONS: PBRTextureTransformSlotDefinition[] = [
|
|
50
|
+
createTextureTransformSlotDefinition('baseColor', 'pbr_baseColorSampler', 'baseColorTexture', [
|
|
51
|
+
'pbrMetallicRoughness',
|
|
52
|
+
'baseColorTexture'
|
|
53
|
+
]),
|
|
54
|
+
createTextureTransformSlotDefinition(
|
|
55
|
+
'metallicRoughness',
|
|
56
|
+
'pbr_metallicRoughnessSampler',
|
|
57
|
+
'metallicRoughnessTexture',
|
|
58
|
+
['pbrMetallicRoughness', 'metallicRoughnessTexture']
|
|
59
|
+
),
|
|
60
|
+
createTextureTransformSlotDefinition('normal', 'pbr_normalSampler', 'normalTexture', [
|
|
61
|
+
'normalTexture'
|
|
62
|
+
]),
|
|
63
|
+
createTextureTransformSlotDefinition('occlusion', 'pbr_occlusionSampler', 'occlusionTexture', [
|
|
64
|
+
'occlusionTexture'
|
|
65
|
+
]),
|
|
66
|
+
createTextureTransformSlotDefinition('emissive', 'pbr_emissiveSampler', 'emissiveTexture', [
|
|
67
|
+
'emissiveTexture'
|
|
68
|
+
]),
|
|
69
|
+
createTextureTransformSlotDefinition(
|
|
70
|
+
'specularColor',
|
|
71
|
+
'pbr_specularColorSampler',
|
|
72
|
+
'KHR_materials_specular.specularColorTexture',
|
|
73
|
+
['extensions', 'KHR_materials_specular', 'specularColorTexture']
|
|
74
|
+
),
|
|
75
|
+
createTextureTransformSlotDefinition(
|
|
76
|
+
'specularIntensity',
|
|
77
|
+
'pbr_specularIntensitySampler',
|
|
78
|
+
'KHR_materials_specular.specularTexture',
|
|
79
|
+
['extensions', 'KHR_materials_specular', 'specularTexture']
|
|
80
|
+
),
|
|
81
|
+
createTextureTransformSlotDefinition(
|
|
82
|
+
'transmission',
|
|
83
|
+
'pbr_transmissionSampler',
|
|
84
|
+
'KHR_materials_transmission.transmissionTexture',
|
|
85
|
+
['extensions', 'KHR_materials_transmission', 'transmissionTexture']
|
|
86
|
+
),
|
|
87
|
+
createTextureTransformSlotDefinition(
|
|
88
|
+
'thickness',
|
|
89
|
+
'pbr_thicknessSampler',
|
|
90
|
+
'KHR_materials_volume.thicknessTexture',
|
|
91
|
+
['extensions', 'KHR_materials_volume', 'thicknessTexture']
|
|
92
|
+
),
|
|
93
|
+
createTextureTransformSlotDefinition(
|
|
94
|
+
'clearcoat',
|
|
95
|
+
'pbr_clearcoatSampler',
|
|
96
|
+
'KHR_materials_clearcoat.clearcoatTexture',
|
|
97
|
+
['extensions', 'KHR_materials_clearcoat', 'clearcoatTexture']
|
|
98
|
+
),
|
|
99
|
+
createTextureTransformSlotDefinition(
|
|
100
|
+
'clearcoatRoughness',
|
|
101
|
+
'pbr_clearcoatRoughnessSampler',
|
|
102
|
+
'KHR_materials_clearcoat.clearcoatRoughnessTexture',
|
|
103
|
+
['extensions', 'KHR_materials_clearcoat', 'clearcoatRoughnessTexture']
|
|
104
|
+
),
|
|
105
|
+
createTextureTransformSlotDefinition(
|
|
106
|
+
'clearcoatNormal',
|
|
107
|
+
'pbr_clearcoatNormalSampler',
|
|
108
|
+
'KHR_materials_clearcoat.clearcoatNormalTexture',
|
|
109
|
+
['extensions', 'KHR_materials_clearcoat', 'clearcoatNormalTexture']
|
|
110
|
+
),
|
|
111
|
+
createTextureTransformSlotDefinition(
|
|
112
|
+
'sheenColor',
|
|
113
|
+
'pbr_sheenColorSampler',
|
|
114
|
+
'KHR_materials_sheen.sheenColorTexture',
|
|
115
|
+
['extensions', 'KHR_materials_sheen', 'sheenColorTexture']
|
|
116
|
+
),
|
|
117
|
+
createTextureTransformSlotDefinition(
|
|
118
|
+
'sheenRoughness',
|
|
119
|
+
'pbr_sheenRoughnessSampler',
|
|
120
|
+
'KHR_materials_sheen.sheenRoughnessTexture',
|
|
121
|
+
['extensions', 'KHR_materials_sheen', 'sheenRoughnessTexture']
|
|
122
|
+
),
|
|
123
|
+
createTextureTransformSlotDefinition(
|
|
124
|
+
'iridescence',
|
|
125
|
+
'pbr_iridescenceSampler',
|
|
126
|
+
'KHR_materials_iridescence.iridescenceTexture',
|
|
127
|
+
['extensions', 'KHR_materials_iridescence', 'iridescenceTexture']
|
|
128
|
+
),
|
|
129
|
+
createTextureTransformSlotDefinition(
|
|
130
|
+
'iridescenceThickness',
|
|
131
|
+
'pbr_iridescenceThicknessSampler',
|
|
132
|
+
'KHR_materials_iridescence.iridescenceThicknessTexture',
|
|
133
|
+
['extensions', 'KHR_materials_iridescence', 'iridescenceThicknessTexture']
|
|
134
|
+
),
|
|
135
|
+
createTextureTransformSlotDefinition(
|
|
136
|
+
'anisotropy',
|
|
137
|
+
'pbr_anisotropySampler',
|
|
138
|
+
'KHR_materials_anisotropy.anisotropyTexture',
|
|
139
|
+
['extensions', 'KHR_materials_anisotropy', 'anisotropyTexture']
|
|
140
|
+
)
|
|
141
|
+
];
|
|
142
|
+
|
|
143
|
+
const TEXTURE_TRANSFORM_SLOT_DEFINITION_MAP = new Map(
|
|
144
|
+
TEXTURE_TRANSFORM_SLOT_DEFINITIONS.map(definition => [definition.slot, definition])
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
function createTextureTransformSlotDefinition(
|
|
148
|
+
slot: PBRTextureTransformSlot,
|
|
149
|
+
binding: string,
|
|
150
|
+
displayName: string,
|
|
151
|
+
pathSegments: string[]
|
|
152
|
+
): PBRTextureTransformSlotDefinition {
|
|
153
|
+
return {
|
|
154
|
+
slot,
|
|
155
|
+
binding,
|
|
156
|
+
displayName,
|
|
157
|
+
pathSegments,
|
|
158
|
+
uvSetUniform: `${slot}UVSet`,
|
|
159
|
+
uvTransformUniform: `${slot}UVTransform`
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export function getTextureTransformSlotDefinitions(): PBRTextureTransformSlotDefinition[] {
|
|
164
|
+
return TEXTURE_TRANSFORM_SLOT_DEFINITIONS;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export function getTextureTransformSlotDefinition(
|
|
168
|
+
slot: PBRTextureTransformSlot
|
|
169
|
+
): PBRTextureTransformSlotDefinition {
|
|
170
|
+
const definition = TEXTURE_TRANSFORM_SLOT_DEFINITION_MAP.get(slot);
|
|
171
|
+
if (!definition) {
|
|
172
|
+
throw new Error(`Unknown PBR texture transform slot ${slot}`);
|
|
173
|
+
}
|
|
174
|
+
return definition;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function getDefaultTextureTransform(): PBRTextureTransform {
|
|
178
|
+
return {
|
|
179
|
+
offset: [...IDENTITY_TEXTURE_TRANSFORM.offset] as [number, number],
|
|
180
|
+
rotation: IDENTITY_TEXTURE_TRANSFORM.rotation,
|
|
181
|
+
scale: [...IDENTITY_TEXTURE_TRANSFORM.scale] as [number, number]
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export function resolveTextureTransform(
|
|
186
|
+
textureInfo: Record<string, any> | undefined
|
|
187
|
+
): PBRTextureTransform {
|
|
188
|
+
const extensionTextureTransform = textureInfo?.['extensions']?.['KHR_texture_transform'];
|
|
189
|
+
return {
|
|
190
|
+
offset: extensionTextureTransform?.offset
|
|
191
|
+
? [extensionTextureTransform.offset[0], extensionTextureTransform.offset[1]]
|
|
192
|
+
: [0, 0],
|
|
193
|
+
rotation: extensionTextureTransform?.rotation ?? 0,
|
|
194
|
+
scale: extensionTextureTransform?.scale
|
|
195
|
+
? [extensionTextureTransform.scale[0], extensionTextureTransform.scale[1]]
|
|
196
|
+
: [1, 1]
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export function resolveTextureCoordinateSet(textureInfo: Record<string, any> | undefined): number {
|
|
201
|
+
const extensionTextureTransform = textureInfo?.['extensions']?.['KHR_texture_transform'];
|
|
202
|
+
return extensionTextureTransform?.['texCoord'] ?? textureInfo?.['texCoord'] ?? 0;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export function resolveTextureTransformSlot(
|
|
206
|
+
pointerSegments: string[]
|
|
207
|
+
): PBRTextureTransformSlotDefinition | null {
|
|
208
|
+
return (
|
|
209
|
+
TEXTURE_TRANSFORM_SLOT_DEFINITIONS.find(
|
|
210
|
+
definition =>
|
|
211
|
+
definition.pathSegments.length === pointerSegments.length &&
|
|
212
|
+
definition.pathSegments.every((segment, index) => pointerSegments[index] === segment)
|
|
213
|
+
) || null
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export function getTextureTransformMatrix(transform: PBRTextureTransform): number[] {
|
|
218
|
+
const translationMatrix = new Matrix3().set(
|
|
219
|
+
1,
|
|
220
|
+
0,
|
|
221
|
+
0,
|
|
222
|
+
0,
|
|
223
|
+
1,
|
|
224
|
+
0,
|
|
225
|
+
transform.offset[0],
|
|
226
|
+
transform.offset[1],
|
|
227
|
+
1
|
|
228
|
+
);
|
|
229
|
+
const rotationMatrix = new Matrix3().set(
|
|
230
|
+
Math.cos(transform.rotation),
|
|
231
|
+
Math.sin(transform.rotation),
|
|
232
|
+
0,
|
|
233
|
+
-Math.sin(transform.rotation),
|
|
234
|
+
Math.cos(transform.rotation),
|
|
235
|
+
0,
|
|
236
|
+
0,
|
|
237
|
+
0,
|
|
238
|
+
1
|
|
239
|
+
);
|
|
240
|
+
const scaleMatrix = new Matrix3().set(
|
|
241
|
+
transform.scale[0],
|
|
242
|
+
0,
|
|
243
|
+
0,
|
|
244
|
+
0,
|
|
245
|
+
transform.scale[1],
|
|
246
|
+
0,
|
|
247
|
+
0,
|
|
248
|
+
0,
|
|
249
|
+
1
|
|
250
|
+
);
|
|
251
|
+
|
|
252
|
+
return Array.from(translationMatrix.multiplyRight(rotationMatrix).multiplyRight(scaleMatrix));
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export function getTextureTransformDeltaMatrix(
|
|
256
|
+
baseTransform: PBRTextureTransform,
|
|
257
|
+
currentTransform: PBRTextureTransform
|
|
258
|
+
): number[] {
|
|
259
|
+
const baseMatrix = new Matrix3(getTextureTransformMatrix(baseTransform));
|
|
260
|
+
const currentMatrix = new Matrix3(getTextureTransformMatrix(currentTransform));
|
|
261
|
+
const inverseBaseMatrix = new Matrix3(baseMatrix).invert();
|
|
262
|
+
return Array.from(currentMatrix.multiplyRight(inverseBaseMatrix));
|
|
263
|
+
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// TODO: convert in loaders.gl?
|
|
6
6
|
import type {TypedArray} from '@math.gl/types';
|
|
7
7
|
|
|
8
|
+
/** Maps glTF accessor type strings to their component counts. */
|
|
8
9
|
export const ATTRIBUTE_TYPE_TO_COMPONENTS: Record<string, number> = {
|
|
9
10
|
SCALAR: 1,
|
|
10
11
|
VEC2: 2,
|
|
@@ -15,6 +16,7 @@ export const ATTRIBUTE_TYPE_TO_COMPONENTS: Record<string, number> = {
|
|
|
15
16
|
MAT4: 16
|
|
16
17
|
};
|
|
17
18
|
|
|
19
|
+
/** Maps glTF accessor component-type enums to typed-array constructors. */
|
|
18
20
|
export const ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY: Record<number, any> = {
|
|
19
21
|
5120: Int8Array,
|
|
20
22
|
5121: Uint8Array,
|
|
@@ -24,16 +26,25 @@ export const ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY: Record<number, any> = {
|
|
|
24
26
|
5126: Float32Array
|
|
25
27
|
};
|
|
26
28
|
|
|
29
|
+
/** Minimal accessor shape required to materialize a typed array. */
|
|
27
30
|
type GLTFAccessor = {
|
|
31
|
+
/** Numeric component type enum. */
|
|
28
32
|
componentType: number;
|
|
33
|
+
/** Accessor type string such as `VEC3` or `SCALAR`. */
|
|
29
34
|
type: string;
|
|
35
|
+
/** Number of logical elements in the accessor. */
|
|
30
36
|
count: number;
|
|
31
|
-
|
|
37
|
+
/** Buffer view carrying the raw bytes. */
|
|
38
|
+
bufferView?: {data: {buffer: ArrayBufferLike; byteOffset?: number}};
|
|
39
|
+
/** Byte offset into the buffer view. */
|
|
32
40
|
byteOffset?: number;
|
|
33
41
|
};
|
|
34
42
|
|
|
43
|
+
/** Converts a glTF accessor into a typed array plus its component count. */
|
|
35
44
|
export function accessorToTypedArray(accessor: GLTFAccessor): {
|
|
45
|
+
/** Typed array view over the accessor data. */
|
|
36
46
|
typedArray: TypedArray;
|
|
47
|
+
/** Number of scalar components per element. */
|
|
37
48
|
components: number;
|
|
38
49
|
} {
|
|
39
50
|
const ArrayType = ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY[accessor.componentType];
|
|
@@ -5,21 +5,27 @@
|
|
|
5
5
|
// TODO: convert in loaders.gl?
|
|
6
6
|
|
|
7
7
|
import type {SamplerProps} from '@luma.gl/core';
|
|
8
|
-
import {
|
|
8
|
+
import {GLEnum} from './gltf-webgl-constants';
|
|
9
9
|
|
|
10
|
+
/** Minimal glTF sampler representation used during conversion. */
|
|
10
11
|
type GLTFSampler = {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
/** Horizontal wrap mode. */
|
|
13
|
+
wrapS?: GLEnum.CLAMP_TO_EDGE | GLEnum.REPEAT | GLEnum.MIRRORED_REPEAT;
|
|
14
|
+
/** Vertical wrap mode. */
|
|
15
|
+
wrapT?: GLEnum.CLAMP_TO_EDGE | GLEnum.REPEAT | GLEnum.MIRRORED_REPEAT;
|
|
16
|
+
/** Magnification filter. */
|
|
17
|
+
magFilter?: GLEnum.NEAREST | GLEnum.LINEAR;
|
|
18
|
+
/** Minification and mip filter combination. */
|
|
14
19
|
minFilter?:
|
|
15
|
-
|
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
|
|
|
20
|
+
| GLEnum.NEAREST
|
|
21
|
+
| GLEnum.LINEAR
|
|
22
|
+
| GLEnum.NEAREST_MIPMAP_NEAREST
|
|
23
|
+
| GLEnum.LINEAR_MIPMAP_NEAREST
|
|
24
|
+
| GLEnum.NEAREST_MIPMAP_LINEAR
|
|
25
|
+
| GLEnum.LINEAR_MIPMAP_LINEAR;
|
|
21
26
|
};
|
|
22
27
|
|
|
28
|
+
/** Converts a glTF sampler into luma.gl sampler props. */
|
|
23
29
|
export function convertSampler(gltfSampler: GLTFSampler): SamplerProps {
|
|
24
30
|
return {
|
|
25
31
|
addressModeU: convertSamplerWrapMode(gltfSampler.wrapS),
|
|
@@ -29,56 +35,59 @@ export function convertSampler(gltfSampler: GLTFSampler): SamplerProps {
|
|
|
29
35
|
};
|
|
30
36
|
}
|
|
31
37
|
|
|
38
|
+
/** Converts a glTF wrap enum into a luma.gl address mode. */
|
|
32
39
|
function convertSamplerWrapMode(
|
|
33
|
-
mode:
|
|
40
|
+
mode: GLEnum.CLAMP_TO_EDGE | GLEnum.REPEAT | GLEnum.MIRRORED_REPEAT | undefined
|
|
34
41
|
): 'clamp-to-edge' | 'repeat' | 'mirror-repeat' | undefined {
|
|
35
42
|
switch (mode) {
|
|
36
|
-
case
|
|
43
|
+
case GLEnum.CLAMP_TO_EDGE:
|
|
37
44
|
return 'clamp-to-edge';
|
|
38
|
-
case
|
|
45
|
+
case GLEnum.REPEAT:
|
|
39
46
|
return 'repeat';
|
|
40
|
-
case
|
|
47
|
+
case GLEnum.MIRRORED_REPEAT:
|
|
41
48
|
return 'mirror-repeat';
|
|
42
49
|
default:
|
|
43
50
|
return undefined;
|
|
44
51
|
}
|
|
45
52
|
}
|
|
46
53
|
|
|
54
|
+
/** Converts a glTF mag filter enum into a luma.gl mag filter. */
|
|
47
55
|
function convertSamplerMagFilter(
|
|
48
|
-
mode:
|
|
56
|
+
mode: GLEnum.NEAREST | GLEnum.LINEAR | undefined
|
|
49
57
|
): 'nearest' | 'linear' | undefined {
|
|
50
58
|
switch (mode) {
|
|
51
|
-
case
|
|
59
|
+
case GLEnum.NEAREST:
|
|
52
60
|
return 'nearest';
|
|
53
|
-
case
|
|
61
|
+
case GLEnum.LINEAR:
|
|
54
62
|
return 'linear';
|
|
55
63
|
default:
|
|
56
64
|
return undefined;
|
|
57
65
|
}
|
|
58
66
|
}
|
|
59
67
|
|
|
68
|
+
/** Converts a glTF min filter enum into luma.gl minification and mipmap filters. */
|
|
60
69
|
function convertSamplerMinFilter(
|
|
61
70
|
mode:
|
|
62
|
-
|
|
|
63
|
-
|
|
|
64
|
-
|
|
|
65
|
-
|
|
|
66
|
-
|
|
|
67
|
-
|
|
|
71
|
+
| GLEnum.NEAREST
|
|
72
|
+
| GLEnum.LINEAR
|
|
73
|
+
| GLEnum.NEAREST_MIPMAP_NEAREST
|
|
74
|
+
| GLEnum.LINEAR_MIPMAP_NEAREST
|
|
75
|
+
| GLEnum.NEAREST_MIPMAP_LINEAR
|
|
76
|
+
| GLEnum.LINEAR_MIPMAP_LINEAR
|
|
68
77
|
| undefined
|
|
69
78
|
): {minFilter?: 'nearest' | 'linear'; mipmapFilter?: 'nearest' | 'linear'} {
|
|
70
79
|
switch (mode) {
|
|
71
|
-
case
|
|
80
|
+
case GLEnum.NEAREST:
|
|
72
81
|
return {minFilter: 'nearest'};
|
|
73
|
-
case
|
|
82
|
+
case GLEnum.LINEAR:
|
|
74
83
|
return {minFilter: 'linear'};
|
|
75
|
-
case
|
|
84
|
+
case GLEnum.NEAREST_MIPMAP_NEAREST:
|
|
76
85
|
return {minFilter: 'nearest', mipmapFilter: 'nearest'};
|
|
77
|
-
case
|
|
86
|
+
case GLEnum.LINEAR_MIPMAP_NEAREST:
|
|
78
87
|
return {minFilter: 'linear', mipmapFilter: 'nearest'};
|
|
79
|
-
case
|
|
88
|
+
case GLEnum.NEAREST_MIPMAP_LINEAR:
|
|
80
89
|
return {minFilter: 'nearest', mipmapFilter: 'linear'};
|
|
81
|
-
case
|
|
90
|
+
case GLEnum.LINEAR_MIPMAP_LINEAR:
|
|
82
91
|
return {minFilter: 'linear', mipmapFilter: 'linear'};
|
|
83
92
|
default:
|
|
84
93
|
return {};
|
|
@@ -3,21 +3,9 @@
|
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
5
|
import {PrimitiveTopology} from '@luma.gl/core';
|
|
6
|
+
import {GLEnum} from './gltf-webgl-constants';
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
// `@luma.gl/constants`. Locally we use `GLEnum` instead of `GL` to avoid
|
|
9
|
-
// conflicts with the `babel-plugin-inline-webgl-constants` plugin.
|
|
10
|
-
// eslint-disable-next-line no-shadow
|
|
11
|
-
export enum GLEnum {
|
|
12
|
-
POINTS = 0x0,
|
|
13
|
-
LINES = 0x1,
|
|
14
|
-
LINE_LOOP = 0x2,
|
|
15
|
-
LINE_STRIP = 0x3,
|
|
16
|
-
TRIANGLES = 0x4,
|
|
17
|
-
TRIANGLE_STRIP = 0x5,
|
|
18
|
-
TRIANGLE_FAN = 0x6
|
|
19
|
-
}
|
|
20
|
-
|
|
8
|
+
/** Converts a WebGL draw mode into a luma.gl primitive topology string. */
|
|
21
9
|
export function convertGLDrawModeToTopology(
|
|
22
10
|
drawMode:
|
|
23
11
|
| GLEnum.POINTS
|
|
@@ -28,7 +16,7 @@ export function convertGLDrawModeToTopology(
|
|
|
28
16
|
| GLEnum.TRIANGLE_STRIP
|
|
29
17
|
| GLEnum.TRIANGLE_FAN
|
|
30
18
|
): PrimitiveTopology {
|
|
31
|
-
//
|
|
19
|
+
// biome-ignore format: preserve layout
|
|
32
20
|
switch (drawMode) {
|
|
33
21
|
case GLEnum.POINTS: return 'point-list';
|
|
34
22
|
case GLEnum.LINES: return 'line-list';
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
// NOTE: `@luma.gl/gltf` intentionally keeps this as a local enum subset so it
|
|
6
|
+
// does not need to depend on `@luma.gl/webgl` for a handful of stable WebGL values.
|
|
7
|
+
// eslint-disable-next-line no-shadow
|
|
8
|
+
export enum GLEnum {
|
|
9
|
+
POINTS = 0x0,
|
|
10
|
+
LINES = 0x1,
|
|
11
|
+
LINE_LOOP = 0x2,
|
|
12
|
+
LINE_STRIP = 0x3,
|
|
13
|
+
TRIANGLES = 0x4,
|
|
14
|
+
TRIANGLE_STRIP = 0x5,
|
|
15
|
+
TRIANGLE_FAN = 0x6,
|
|
16
|
+
|
|
17
|
+
ONE = 1,
|
|
18
|
+
SRC_ALPHA = 0x0302,
|
|
19
|
+
ONE_MINUS_SRC_ALPHA = 0x0303,
|
|
20
|
+
FUNC_ADD = 0x8006,
|
|
21
|
+
|
|
22
|
+
LINEAR = 0x2601,
|
|
23
|
+
NEAREST = 0x2600,
|
|
24
|
+
NEAREST_MIPMAP_NEAREST = 0x2700,
|
|
25
|
+
LINEAR_MIPMAP_NEAREST = 0x2701,
|
|
26
|
+
NEAREST_MIPMAP_LINEAR = 0x2702,
|
|
27
|
+
LINEAR_MIPMAP_LINEAR = 0x2703,
|
|
28
|
+
TEXTURE_MIN_FILTER = 0x2801,
|
|
29
|
+
TEXTURE_WRAP_S = 0x2802,
|
|
30
|
+
TEXTURE_WRAP_T = 0x2803,
|
|
31
|
+
REPEAT = 0x2901,
|
|
32
|
+
CLAMP_TO_EDGE = 0x812f,
|
|
33
|
+
MIRRORED_REPEAT = 0x8370,
|
|
34
|
+
UNPACK_FLIP_Y_WEBGL = 0x9240
|
|
35
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"deep-copy.d.ts","sourceRoot":"","sources":["../../src/utils/deep-copy.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,wBAAgB,QAAQ,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,CAoBzC"}
|
package/dist/utils/deep-copy.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/** Deeply copies a JS data structure */
|
|
2
|
-
export function deepCopy(object) {
|
|
3
|
-
// don't copy binary data
|
|
4
|
-
if (ArrayBuffer.isView(object) ||
|
|
5
|
-
object instanceof ArrayBuffer ||
|
|
6
|
-
object instanceof ImageBitmap) {
|
|
7
|
-
return object;
|
|
8
|
-
}
|
|
9
|
-
if (Array.isArray(object)) {
|
|
10
|
-
return object.map(deepCopy);
|
|
11
|
-
}
|
|
12
|
-
if (object && typeof object === 'object') {
|
|
13
|
-
const result = {};
|
|
14
|
-
for (const key in object) {
|
|
15
|
-
result[key] = deepCopy(object[key]);
|
|
16
|
-
}
|
|
17
|
-
return result;
|
|
18
|
-
}
|
|
19
|
-
return object;
|
|
20
|
-
}
|
|
21
|
-
//# sourceMappingURL=deep-copy.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"deep-copy.js","sourceRoot":"","sources":["../../src/utils/deep-copy.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,MAAM,UAAU,QAAQ,CAAC,MAAW;IAClC,yBAAyB;IACzB,IACE,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;QAC1B,MAAM,YAAY,WAAW;QAC7B,MAAM,YAAY,WAAW,EAC7B,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IACD,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QACzC,MAAM,MAAM,GAAkB,EAAE,CAAC;QACjC,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;YACzB,MAAM,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|