@zephyr3d/scene 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. package/dist/animation/animation.js +173 -0
  2. package/dist/animation/animation.js.map +1 -0
  3. package/dist/animation/animationset.js +95 -0
  4. package/dist/animation/animationset.js.map +1 -0
  5. package/dist/animation/animationtrack.js +38 -0
  6. package/dist/animation/animationtrack.js.map +1 -0
  7. package/dist/animation/eulerrotationtrack.js +33 -0
  8. package/dist/animation/eulerrotationtrack.js.map +1 -0
  9. package/dist/animation/rotationtrack.js +37 -0
  10. package/dist/animation/rotationtrack.js.map +1 -0
  11. package/dist/animation/scaletrack.js +36 -0
  12. package/dist/animation/scaletrack.js.map +1 -0
  13. package/dist/animation/skeleton.js +97 -0
  14. package/dist/animation/skeleton.js.map +1 -0
  15. package/dist/animation/translationtrack.js +36 -0
  16. package/dist/animation/translationtrack.js.map +1 -0
  17. package/dist/animation/usertrack.js +47 -0
  18. package/dist/animation/usertrack.js.map +1 -0
  19. package/dist/app.js +173 -0
  20. package/dist/app.js.map +1 -0
  21. package/dist/asset/assetmanager.js +476 -0
  22. package/dist/asset/assetmanager.js.map +1 -0
  23. package/dist/asset/builtin.js +373 -0
  24. package/dist/asset/builtin.js.map +1 -0
  25. package/dist/asset/loaders/dds/dds.js +472 -0
  26. package/dist/asset/loaders/dds/dds.js.map +1 -0
  27. package/dist/asset/loaders/dds/dds_loader.js +38 -0
  28. package/dist/asset/loaders/dds/dds_loader.js.map +1 -0
  29. package/dist/asset/loaders/gltf/gltf_loader.js +981 -0
  30. package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -0
  31. package/dist/asset/loaders/gltf/helpers.js +314 -0
  32. package/dist/asset/loaders/gltf/helpers.js.map +1 -0
  33. package/dist/asset/loaders/hdr/hdr.js +175 -0
  34. package/dist/asset/loaders/hdr/hdr.js.map +1 -0
  35. package/dist/asset/loaders/image/tga_Loader.js +117 -0
  36. package/dist/asset/loaders/image/tga_Loader.js.map +1 -0
  37. package/dist/asset/loaders/image/webimage_loader.js +50 -0
  38. package/dist/asset/loaders/image/webimage_loader.js.map +1 -0
  39. package/dist/asset/loaders/loader.js +45 -0
  40. package/dist/asset/loaders/loader.js.map +1 -0
  41. package/dist/asset/model.js +264 -0
  42. package/dist/asset/model.js.map +1 -0
  43. package/dist/blitter/blitter.js +389 -0
  44. package/dist/blitter/blitter.js.map +1 -0
  45. package/dist/blitter/box.js +118 -0
  46. package/dist/blitter/box.js.map +1 -0
  47. package/dist/blitter/copy.js +22 -0
  48. package/dist/blitter/copy.js.map +1 -0
  49. package/dist/blitter/depthlimitedgaussion.js +166 -0
  50. package/dist/blitter/depthlimitedgaussion.js.map +1 -0
  51. package/dist/blitter/gaussianblur.js +229 -0
  52. package/dist/blitter/gaussianblur.js.map +1 -0
  53. package/dist/camera/base.js +90 -0
  54. package/dist/camera/base.js.map +1 -0
  55. package/dist/camera/camera.js +358 -0
  56. package/dist/camera/camera.js.map +1 -0
  57. package/dist/camera/fps.js +246 -0
  58. package/dist/camera/fps.js.map +1 -0
  59. package/dist/camera/orbit.js +157 -0
  60. package/dist/camera/orbit.js.map +1 -0
  61. package/dist/camera/orthocamera.js +126 -0
  62. package/dist/camera/orthocamera.js.map +1 -0
  63. package/dist/camera/perspectivecamera.js +133 -0
  64. package/dist/camera/perspectivecamera.js.map +1 -0
  65. package/dist/index.d.ts +8402 -0
  66. package/dist/index.js +87 -0
  67. package/dist/index.js.map +1 -0
  68. package/dist/input/inputmgr.js +242 -0
  69. package/dist/input/inputmgr.js.map +1 -0
  70. package/dist/material/blinn.js +75 -0
  71. package/dist/material/blinn.js.map +1 -0
  72. package/dist/material/grassmaterial.js +221 -0
  73. package/dist/material/grassmaterial.js.map +1 -0
  74. package/dist/material/lambert.js +52 -0
  75. package/dist/material/lambert.js.map +1 -0
  76. package/dist/material/lightmodel.js +2074 -0
  77. package/dist/material/lightmodel.js.map +1 -0
  78. package/dist/material/lit.js +578 -0
  79. package/dist/material/lit.js.map +1 -0
  80. package/dist/material/material.js +458 -0
  81. package/dist/material/material.js.map +1 -0
  82. package/dist/material/meshmaterial.js +311 -0
  83. package/dist/material/meshmaterial.js.map +1 -0
  84. package/dist/material/mixins/albedocolor.js +130 -0
  85. package/dist/material/mixins/albedocolor.js.map +1 -0
  86. package/dist/material/mixins/texture.js +110 -0
  87. package/dist/material/mixins/texture.js.map +1 -0
  88. package/dist/material/mixins/vertexcolor.js +45 -0
  89. package/dist/material/mixins/vertexcolor.js.map +1 -0
  90. package/dist/material/pbr.js +27 -0
  91. package/dist/material/pbr.js.map +1 -0
  92. package/dist/material/standard.js +282 -0
  93. package/dist/material/standard.js.map +1 -0
  94. package/dist/material/terrainlightmodel.js +259 -0
  95. package/dist/material/terrainlightmodel.js.map +1 -0
  96. package/dist/material/terrainmaterial.js +139 -0
  97. package/dist/material/terrainmaterial.js.map +1 -0
  98. package/dist/material/unlit.js +29 -0
  99. package/dist/material/unlit.js.map +1 -0
  100. package/dist/posteffect/bloom.js +398 -0
  101. package/dist/posteffect/bloom.js.map +1 -0
  102. package/dist/posteffect/compositor.js +264 -0
  103. package/dist/posteffect/compositor.js.map +1 -0
  104. package/dist/posteffect/fxaa.js +291 -0
  105. package/dist/posteffect/fxaa.js.map +1 -0
  106. package/dist/posteffect/grayscale.js +87 -0
  107. package/dist/posteffect/grayscale.js.map +1 -0
  108. package/dist/posteffect/posteffect.js +165 -0
  109. package/dist/posteffect/posteffect.js.map +1 -0
  110. package/dist/posteffect/sao.js +327 -0
  111. package/dist/posteffect/sao.js.map +1 -0
  112. package/dist/posteffect/tonemap.js +112 -0
  113. package/dist/posteffect/tonemap.js.map +1 -0
  114. package/dist/posteffect/water.js +535 -0
  115. package/dist/posteffect/water.js.map +1 -0
  116. package/dist/render/clipmap.js +462 -0
  117. package/dist/render/clipmap.js.map +1 -0
  118. package/dist/render/cluster_light.js +329 -0
  119. package/dist/render/cluster_light.js.map +1 -0
  120. package/dist/render/cull_visitor.js +124 -0
  121. package/dist/render/cull_visitor.js.map +1 -0
  122. package/dist/render/depth_pass.js +47 -0
  123. package/dist/render/depth_pass.js.map +1 -0
  124. package/dist/render/envlight.js +282 -0
  125. package/dist/render/envlight.js.map +1 -0
  126. package/dist/render/forward.js +186 -0
  127. package/dist/render/forward.js.map +1 -0
  128. package/dist/render/forward_pass.js +137 -0
  129. package/dist/render/forward_pass.js.map +1 -0
  130. package/dist/render/helper.js +38 -0
  131. package/dist/render/helper.js.map +1 -0
  132. package/dist/render/primitive.js +246 -0
  133. package/dist/render/primitive.js.map +1 -0
  134. package/dist/render/render_queue.js +163 -0
  135. package/dist/render/render_queue.js.map +1 -0
  136. package/dist/render/renderpass.js +151 -0
  137. package/dist/render/renderpass.js.map +1 -0
  138. package/dist/render/renderscheme.js +61 -0
  139. package/dist/render/renderscheme.js.map +1 -0
  140. package/dist/render/scatteringlut.js +634 -0
  141. package/dist/render/scatteringlut.js.map +1 -0
  142. package/dist/render/shadowmap_pass.js +70 -0
  143. package/dist/render/shadowmap_pass.js.map +1 -0
  144. package/dist/render/sky.js +881 -0
  145. package/dist/render/sky.js.map +1 -0
  146. package/dist/render/temporalcache.js +222 -0
  147. package/dist/render/temporalcache.js.map +1 -0
  148. package/dist/render/watermesh.js +835 -0
  149. package/dist/render/watermesh.js.map +1 -0
  150. package/dist/scene/environment.js +146 -0
  151. package/dist/scene/environment.js.map +1 -0
  152. package/dist/scene/graph_node.js +69 -0
  153. package/dist/scene/graph_node.js.map +1 -0
  154. package/dist/scene/light.js +436 -0
  155. package/dist/scene/light.js.map +1 -0
  156. package/dist/scene/mesh.js +215 -0
  157. package/dist/scene/mesh.js.map +1 -0
  158. package/dist/scene/model.js +111 -0
  159. package/dist/scene/model.js.map +1 -0
  160. package/dist/scene/octree.js +651 -0
  161. package/dist/scene/octree.js.map +1 -0
  162. package/dist/scene/octree_update_visitor.js +16 -0
  163. package/dist/scene/octree_update_visitor.js.map +1 -0
  164. package/dist/scene/raycast_visitor.js +72 -0
  165. package/dist/scene/raycast_visitor.js.map +1 -0
  166. package/dist/scene/scene.js +225 -0
  167. package/dist/scene/scene.js.map +1 -0
  168. package/dist/scene/scene_node.js +299 -0
  169. package/dist/scene/scene_node.js.map +1 -0
  170. package/dist/scene/terrain/grass.js +277 -0
  171. package/dist/scene/terrain/grass.js.map +1 -0
  172. package/dist/scene/terrain/heightfield.js +391 -0
  173. package/dist/scene/terrain/heightfield.js.map +1 -0
  174. package/dist/scene/terrain/patch.js +530 -0
  175. package/dist/scene/terrain/patch.js.map +1 -0
  176. package/dist/scene/terrain/quadtree.js +430 -0
  177. package/dist/scene/terrain/quadtree.js.map +1 -0
  178. package/dist/scene/terrain/terrain.js +258 -0
  179. package/dist/scene/terrain/terrain.js.map +1 -0
  180. package/dist/scene/xform.js +224 -0
  181. package/dist/scene/xform.js.map +1 -0
  182. package/dist/shaders/builtins.js +110 -0
  183. package/dist/shaders/builtins.js.map +1 -0
  184. package/dist/shaders/framework.js +709 -0
  185. package/dist/shaders/framework.js.map +1 -0
  186. package/dist/shaders/lighting.js +335 -0
  187. package/dist/shaders/lighting.js.map +1 -0
  188. package/dist/shaders/misc.js +405 -0
  189. package/dist/shaders/misc.js.map +1 -0
  190. package/dist/shaders/noise.js +157 -0
  191. package/dist/shaders/noise.js.map +1 -0
  192. package/dist/shaders/pbr.js +132 -0
  193. package/dist/shaders/pbr.js.map +1 -0
  194. package/dist/shaders/shadow.js +642 -0
  195. package/dist/shaders/shadow.js.map +1 -0
  196. package/dist/shaders/water.js +630 -0
  197. package/dist/shaders/water.js.map +1 -0
  198. package/dist/shadow/esm.js +235 -0
  199. package/dist/shadow/esm.js.map +1 -0
  200. package/dist/shadow/pcf_opt.js +182 -0
  201. package/dist/shadow/pcf_opt.js.map +1 -0
  202. package/dist/shadow/pcf_pd.js +190 -0
  203. package/dist/shadow/pcf_pd.js.map +1 -0
  204. package/dist/shadow/shadow_impl.js +15 -0
  205. package/dist/shadow/shadow_impl.js.map +1 -0
  206. package/dist/shadow/shadowmapper.js +709 -0
  207. package/dist/shadow/shadowmapper.js.map +1 -0
  208. package/dist/shadow/ssm.js +194 -0
  209. package/dist/shadow/ssm.js.map +1 -0
  210. package/dist/shadow/vsm.js +298 -0
  211. package/dist/shadow/vsm.js.map +1 -0
  212. package/dist/shapes/box.js +313 -0
  213. package/dist/shapes/box.js.map +1 -0
  214. package/dist/shapes/cylinder.js +74 -0
  215. package/dist/shapes/cylinder.js.map +1 -0
  216. package/dist/shapes/plane.js +48 -0
  217. package/dist/shapes/plane.js.map +1 -0
  218. package/dist/shapes/shape.js +33 -0
  219. package/dist/shapes/shape.js.map +1 -0
  220. package/dist/shapes/sphere.js +91 -0
  221. package/dist/shapes/sphere.js.map +1 -0
  222. package/dist/shapes/torus.js +100 -0
  223. package/dist/shapes/torus.js.map +1 -0
  224. package/dist/utility/aabbtree.js +390 -0
  225. package/dist/utility/aabbtree.js.map +1 -0
  226. package/dist/utility/bounding_volume.js +78 -0
  227. package/dist/utility/bounding_volume.js.map +1 -0
  228. package/dist/utility/panorama.js +163 -0
  229. package/dist/utility/panorama.js.map +1 -0
  230. package/dist/utility/pmrem.js +345 -0
  231. package/dist/utility/pmrem.js.map +1 -0
  232. package/dist/utility/shprojection.js +448 -0
  233. package/dist/utility/shprojection.js.map +1 -0
  234. package/dist/values.js +48 -0
  235. package/dist/values.js.map +1 -0
  236. package/package.json +70 -0
@@ -0,0 +1,981 @@
1
+ import { Matrix4x4, Vector3, Quaternion, Interpolator, Vector4 } from '@zephyr3d/base';
2
+ import { AssetScene, AssetSkeleton, SharedModel } from '../../model.js';
3
+ import { BoundingBox } from '../../../utility/bounding_volume.js';
4
+ import { Primitive } from '../../../render/primitive.js';
5
+ import '../../../material/material.js';
6
+ import '@zephyr3d/device';
7
+ import '../../../shaders/framework.js';
8
+ import { Application } from '../../../app.js';
9
+ import '../../../render/scatteringlut.js';
10
+ import '../../../material/lambert.js';
11
+ import '../../../material/blinn.js';
12
+ import { UnlitMaterial } from '../../../material/unlit.js';
13
+ import { PBRSpecularGlossinessMaterial, PBRMetallicRoughnessMaterial } from '../../../material/pbr.js';
14
+ import '../../../material/lightmodel.js';
15
+ import { GLTFAccessor, ComponentType } from './helpers.js';
16
+ import { AbstractModelLoader } from '../loader.js';
17
+
18
+ /**
19
+ * The GLTF/GLB model loader
20
+ * @internal
21
+ */ class GLTFLoader extends AbstractModelLoader {
22
+ supportExtension(ext) {
23
+ return ext === '.gltf' || ext === '.glb';
24
+ }
25
+ supportMIMEType(mimeType) {
26
+ return mimeType === 'model/gltf+json' || mimeType === 'model/gltf-binary';
27
+ }
28
+ async load(assetManager, url, mimeType, data) {
29
+ const buffer = await data.arrayBuffer();
30
+ if (this.isGLB(buffer)) {
31
+ return this.loadBinary(assetManager, url, buffer);
32
+ }
33
+ const gltf = await new Response(data).json();
34
+ gltf._manager = assetManager;
35
+ gltf._loadedBuffers = null;
36
+ return this.loadJson(url, gltf);
37
+ }
38
+ async loadBinary(assetManager, url, buffer) {
39
+ const jsonChunkType = 0x4e4f534a;
40
+ const binaryChunkType = 0x004e4942;
41
+ let gltf = null;
42
+ const buffers = [];
43
+ const chunkInfos = this.getGLBChunkInfos(buffer);
44
+ for (const info of chunkInfos){
45
+ if (info.type === jsonChunkType && !gltf) {
46
+ const jsonSlice = new Uint8Array(buffer, 20, info.length);
47
+ const stringBuffer = new TextDecoder('utf-8').decode(jsonSlice);
48
+ gltf = JSON.parse(stringBuffer);
49
+ } else if (info.type === binaryChunkType) {
50
+ buffers.push(buffer.slice(info.start, info.start + info.length));
51
+ }
52
+ }
53
+ if (gltf) {
54
+ gltf._manager = assetManager;
55
+ gltf._loadedBuffers = buffers;
56
+ return this.loadJson(url, gltf);
57
+ }
58
+ return null;
59
+ }
60
+ async loadJson(url, gltf) {
61
+ console.log(`GLTF extensions used: ${gltf.extensionsUsed || []}`);
62
+ gltf._accessors = [];
63
+ gltf._bufferCache = {};
64
+ gltf._textureCache = {};
65
+ gltf._primitiveCache = {};
66
+ gltf._materialCache = {};
67
+ gltf._nodes = [];
68
+ gltf._meshes = [];
69
+ // check asset property
70
+ const asset = gltf.asset;
71
+ if (asset) {
72
+ const gltfVersion = asset.version;
73
+ if (gltfVersion !== '2.0') {
74
+ console.error(`Invalid GLTF version: ${gltfVersion}`);
75
+ return null;
76
+ }
77
+ }
78
+ gltf._baseURI = url.substring(0, url.lastIndexOf('/') + 1);
79
+ if (!gltf._loadedBuffers) {
80
+ gltf._loadedBuffers = [];
81
+ const buffers = gltf.buffers;
82
+ if (buffers) {
83
+ for (const buffer of buffers){
84
+ const uri = this._normalizeURI(gltf._baseURI, buffer.uri);
85
+ const buf = await gltf._manager.fetchBinaryData(uri);
86
+ // const buf = (await new FileLoader(null, 'arraybuffer').load(uri)) as ArrayBuffer;
87
+ if (buffer.byteLength !== buf.byteLength) {
88
+ console.error(`Invalid GLTF: buffer byte length error.`);
89
+ return null;
90
+ }
91
+ gltf._loadedBuffers.push(buf);
92
+ }
93
+ }
94
+ }
95
+ const accessors = gltf.accessors;
96
+ if (accessors) {
97
+ for (const accessor of gltf.accessors){
98
+ gltf._accessors.push(new GLTFAccessor(accessor));
99
+ }
100
+ }
101
+ const scenes = gltf.scenes;
102
+ if (scenes) {
103
+ const sharedModel = new SharedModel();
104
+ await this._loadMeshes(gltf, sharedModel);
105
+ this._loadNodes(gltf, sharedModel);
106
+ this._loadSkins(gltf, sharedModel);
107
+ for(let i = 0; i < gltf.nodes?.length; i++){
108
+ if (typeof gltf.nodes[i].skin === 'number' && gltf.nodes[i].skin >= 0) {
109
+ gltf._nodes[i].skeleton = sharedModel.skeletons[gltf.nodes[i].skin];
110
+ }
111
+ }
112
+ this._loadAnimations(gltf, sharedModel);
113
+ for (const scene of scenes){
114
+ const assetScene = new AssetScene(scene.name);
115
+ for (const node of scene.nodes){
116
+ assetScene.rootNodes.push(gltf._nodes[node]);
117
+ }
118
+ sharedModel.scenes.push(assetScene);
119
+ }
120
+ if (typeof gltf.scene === 'number') {
121
+ sharedModel.activeScene = gltf.scene;
122
+ }
123
+ return sharedModel;
124
+ }
125
+ return null;
126
+ }
127
+ /** @internal */ _normalizeURI(baseURI, uri) {
128
+ const s = uri.toLowerCase();
129
+ if (s.startsWith('http://') || s.startsWith('https://') || s.startsWith('blob:') || s.startsWith('data:')) {
130
+ // absolute path
131
+ return encodeURI(uri);
132
+ }
133
+ uri = uri.replace(/\.\//g, '');
134
+ uri = decodeURIComponent(uri);
135
+ if (uri[0] === '/') {
136
+ uri = uri.slice(1);
137
+ }
138
+ uri = uri.split('/').map((val)=>encodeURIComponent(val)).join('/');
139
+ return baseURI + uri;
140
+ }
141
+ /** @internal */ _loadNodes(gltf, model) {
142
+ if (gltf.nodes) {
143
+ for(let i = 0; i < gltf.nodes.length; i++){
144
+ this._loadNode(gltf, i, null, model);
145
+ }
146
+ for (const node of gltf._nodes){
147
+ if (!node.parent) {
148
+ node.computeTransforms(null);
149
+ }
150
+ }
151
+ }
152
+ }
153
+ /** @internal */ _loadSkins(gltf, model) {
154
+ if (gltf.skins) {
155
+ for(let i = 0; i < gltf.skins.length; i++){
156
+ const skinInfo = gltf.skins[i];
157
+ const skeleton = new AssetSkeleton(skinInfo.name);
158
+ if (typeof skinInfo.skeleton === 'number') {
159
+ skeleton.pivot = gltf._nodes[skinInfo.skeleton];
160
+ }
161
+ const accessor = gltf._accessors[skinInfo.inverseBindMatrices];
162
+ if (!accessor || accessor.type !== 'MAT4' || accessor.componentType !== ComponentType.FLOAT) {
163
+ throw new Error('Invalid GLTF inverse bind matricies accessor');
164
+ }
165
+ const matrices = typeof skinInfo.inverseBindMatrices === 'number' ? accessor.getDeinterlacedView(gltf) : null;
166
+ skinInfo.joints.forEach((joint, index)=>{
167
+ const m = index * 16;
168
+ skeleton.addJoint(gltf._nodes[joint], matrices ? new Matrix4x4(matrices.subarray(m, m + 16)) : Matrix4x4.identity());
169
+ });
170
+ model.addSkeleton(skeleton);
171
+ }
172
+ }
173
+ }
174
+ /** @internal */ _loadAnimations(gltf, model) {
175
+ if (gltf.animations) {
176
+ for(let i = 0; i < gltf.animations.length; i++){
177
+ const animation = this._loadAnimation(gltf, i, model);
178
+ model.addAnimation(animation);
179
+ }
180
+ }
181
+ }
182
+ /** @internal */ collectNodes(gltf) {
183
+ const collect = new Map();
184
+ for (const node of gltf._nodes){
185
+ collect.set(node, {
186
+ translate: node.position || Vector3.zero(),
187
+ rotation: node.rotation || Quaternion.identity(),
188
+ scale: node.scaling || Vector3.one(),
189
+ worldTransform: null
190
+ });
191
+ }
192
+ return collect;
193
+ }
194
+ /** @internal */ updateNodeTransform(nodeTransforms, node) {
195
+ const transform = nodeTransforms.get(node);
196
+ if (!transform.worldTransform) {
197
+ transform.worldTransform = Matrix4x4.scaling(transform.scale).rotateLeft(transform.rotation).translateLeft(transform.translate);
198
+ if (node.parent) {
199
+ this.updateNodeTransform(nodeTransforms, node.parent);
200
+ transform.worldTransform.multiplyLeft(nodeTransforms.get(node.parent).worldTransform);
201
+ }
202
+ }
203
+ }
204
+ /** @internal */ getAnimationInfo(gltf, index) {
205
+ const animationInfo = gltf.animations[index];
206
+ const name = animationInfo.name || null;
207
+ const channels = animationInfo.channels;
208
+ const samplers = animationInfo.samplers;
209
+ const interpolators = [];
210
+ const interpolatorTypes = [];
211
+ const nodes = this.collectNodes(gltf);
212
+ let maxTime = 0;
213
+ for(let i = 0; i < channels.length; i++){
214
+ const channel = channels[i];
215
+ const sampler = samplers[channel.sampler];
216
+ const input = gltf._accessors[sampler.input].getNormalizedDeinterlacedView(gltf);
217
+ const output = gltf._accessors[sampler.output].getNormalizedDeinterlacedView(gltf);
218
+ const mode = sampler.interpolation === 'STEP' ? 'step' : sampler.interpolation === 'CUBICSPLINE' ? 'cubicspline' : 'linear';
219
+ if (channel.target.path === 'rotation') {
220
+ interpolators.push(new Interpolator(mode, 'quat', input, output));
221
+ interpolatorTypes.push('rotation');
222
+ } else if (channel.target.path === 'translation') {
223
+ interpolators.push(new Interpolator(mode, 'vec3', input, output));
224
+ interpolatorTypes.push('translation');
225
+ } else if (channel.target.path === 'scale') {
226
+ interpolators.push(new Interpolator(mode, 'vec3', input, output));
227
+ interpolatorTypes.push('scale');
228
+ } else {
229
+ continue;
230
+ }
231
+ const max = input[input.length - 1];
232
+ if (max > maxTime) {
233
+ maxTime = max;
234
+ }
235
+ }
236
+ return {
237
+ name,
238
+ channels,
239
+ samplers,
240
+ interpolators,
241
+ interpolatorTypes,
242
+ maxTime,
243
+ nodes
244
+ };
245
+ }
246
+ /** @internal */ _loadAnimation(gltf, index, model) {
247
+ const animationInfo = this.getAnimationInfo(gltf, index);
248
+ const animationData = {
249
+ name: animationInfo.name,
250
+ tracks: [],
251
+ skeletons: [],
252
+ nodes: []
253
+ };
254
+ for(let i = 0; i < animationInfo.channels.length; i++){
255
+ const targetNode = gltf._nodes[animationInfo.channels[i].target.node];
256
+ animationData.tracks.push({
257
+ node: targetNode,
258
+ type: animationInfo.interpolatorTypes[i],
259
+ interpolator: animationInfo.interpolators[i]
260
+ });
261
+ if (animationData.nodes.indexOf(targetNode) < 0) {
262
+ animationData.nodes.push(targetNode);
263
+ }
264
+ if (targetNode.skeletonAttached && animationData.skeletons.indexOf(targetNode.skeletonAttached) < 0) {
265
+ animationData.skeletons.push(targetNode.skeletonAttached);
266
+ }
267
+ }
268
+ return animationData;
269
+ }
270
+ /** @internal */ _loadNode(gltf, nodeIndex, parent, model) {
271
+ let node = gltf._nodes[nodeIndex];
272
+ if (node) {
273
+ if (parent) {
274
+ if (node.parent) {
275
+ throw new Error('invalid node hierarchy');
276
+ }
277
+ parent.addChild(node);
278
+ }
279
+ return node;
280
+ }
281
+ const nodeInfo = gltf.nodes?.[nodeIndex];
282
+ if (nodeInfo) {
283
+ node = model.addNode(parent, nodeIndex, nodeInfo.name);
284
+ if (typeof nodeInfo.mesh === 'number') {
285
+ node.mesh = gltf._meshes[nodeInfo.mesh];
286
+ }
287
+ if (!(typeof nodeInfo.skin === 'number') || nodeInfo.skin < 0) {
288
+ // GLTF spec: Only the joint transforms are applied to the skinned mesh; the transform of the skinned mesh node MUST be ignored.
289
+ if (nodeInfo.matrix) {
290
+ const matrix = new Matrix4x4(nodeInfo.matrix);
291
+ matrix.decompose(node.scaling, node.rotation, node.position);
292
+ } else {
293
+ if (nodeInfo.rotation) {
294
+ node.rotation.set(nodeInfo.rotation);
295
+ }
296
+ if (nodeInfo.scale) {
297
+ node.scaling.set(nodeInfo.scale);
298
+ }
299
+ if (nodeInfo.translation) {
300
+ node.position.set(nodeInfo.translation);
301
+ }
302
+ }
303
+ }
304
+ gltf._nodes[nodeIndex] = node;
305
+ if (nodeInfo.children) {
306
+ for (const childIndex of nodeInfo.children){
307
+ this._loadNode(gltf, childIndex, node, model);
308
+ }
309
+ }
310
+ } else {
311
+ throw new Error(`invalid GLTF node: ${nodeIndex}`);
312
+ }
313
+ return node;
314
+ }
315
+ /** @internal */ async _loadMeshes(gltf, model) {
316
+ if (gltf.meshes) {
317
+ for(let i = 0; i < gltf.meshes.length; i++){
318
+ gltf._meshes[i] = await this._loadMesh(gltf, i);
319
+ }
320
+ }
321
+ }
322
+ /** @internal */ async _loadMesh(gltf, meshIndex) {
323
+ const meshInfo = gltf.meshes && gltf.meshes[meshIndex];
324
+ let mesh = null;
325
+ if (meshInfo) {
326
+ mesh = {
327
+ subMeshes: []
328
+ };
329
+ const primitives = meshInfo.primitives;
330
+ const meshName = meshInfo.name || null;
331
+ if (primitives) {
332
+ for(let i = 0; i < primitives.length; i++){
333
+ const p = primitives[i];
334
+ const subMeshData = {
335
+ name: `${meshName}-${i}`,
336
+ primitive: null,
337
+ material: null,
338
+ rawPositions: null,
339
+ rawBlendIndices: null,
340
+ rawJointWeights: null
341
+ };
342
+ const hash = `(${Object.getOwnPropertyNames(p.attributes).sort().map((k)=>`${k}:${p.attributes[k]}`).join(',')})-(${p.indices})-(${p.mode})`;
343
+ let primitive = p.targets ? null : gltf._primitiveCache[hash];
344
+ if (!primitive) {
345
+ primitive = new Primitive();
346
+ const attributes = p.attributes;
347
+ for(const attrib in attributes){
348
+ this._loadVertexBuffer(gltf, attrib, attributes[attrib], primitive, subMeshData);
349
+ }
350
+ const indices = p.indices;
351
+ if (typeof indices === 'number') {
352
+ this._loadIndexBuffer(gltf, indices, primitive, subMeshData);
353
+ }
354
+ let primitiveType = p.mode;
355
+ if (typeof primitiveType !== 'number') {
356
+ primitiveType = 4;
357
+ }
358
+ primitive.primitiveType = this._primitiveType(primitiveType);
359
+ gltf._primitiveCache[hash] = primitive;
360
+ }
361
+ const hasVertexNormal = !!primitive.getVertexBuffer('normal');
362
+ const hasVertexColor = !!primitive.getVertexBuffer('diffuse');
363
+ const hasVertexTangent = !!primitive.getVertexBuffer('tangent');
364
+ const materialHash = `${p.material}.${Number(hasVertexNormal)}.${Number(hasVertexColor)}.${Number(hasVertexTangent)}`;
365
+ let material = gltf._materialCache[materialHash];
366
+ if (!material) {
367
+ const materialInfo = p.material !== undefined ? gltf.materials[p.material] : null;
368
+ material = await this._loadMaterial(gltf, materialInfo, hasVertexColor, hasVertexNormal, hasVertexTangent);
369
+ gltf._materialCache[materialHash] = material;
370
+ }
371
+ subMeshData.primitive = primitive;
372
+ subMeshData.material = material;
373
+ mesh.subMeshes.push(subMeshData);
374
+ }
375
+ }
376
+ }
377
+ return mesh;
378
+ }
379
+ async _createMaterial(assetManager, assetMaterial) {
380
+ if (assetMaterial.type === 'unlit') {
381
+ const unlitAssetMaterial = assetMaterial;
382
+ const unlitMaterial = new UnlitMaterial; //new NewLambertMaterial();// new TestLitMaterial();// new UnlitMaterial();
383
+ unlitMaterial.albedoColor = unlitAssetMaterial.diffuse ?? Vector4.one();
384
+ if (unlitAssetMaterial.diffuseMap) {
385
+ unlitMaterial.albedoTexture = unlitAssetMaterial.diffuseMap.texture;
386
+ unlitMaterial.albedoTextureSampler = unlitAssetMaterial.diffuseMap.sampler;
387
+ unlitMaterial.albedoTexCoordIndex = unlitAssetMaterial.diffuseMap.texCoord;
388
+ unlitMaterial.albedoTexMatrix = unlitAssetMaterial.diffuseMap.transform;
389
+ }
390
+ unlitMaterial.vertexColor = unlitAssetMaterial.common.vertexColor;
391
+ if (assetMaterial.common.alphaMode === 'blend') {
392
+ unlitMaterial.blendMode = 'blend';
393
+ } else if (assetMaterial.common.alphaMode === 'mask') {
394
+ unlitMaterial.alphaCutoff = assetMaterial.common.alphaCutoff;
395
+ }
396
+ if (assetMaterial.common.doubleSided) {
397
+ const rasterizerState = unlitMaterial.stateSet.useRasterizerState();
398
+ rasterizerState.setCullMode('none');
399
+ }
400
+ return unlitMaterial;
401
+ } else if (assetMaterial.type === 'pbrSpecularGlossiness') {
402
+ const assetPBRMaterial = assetMaterial;
403
+ const pbrMaterial = new PBRSpecularGlossinessMaterial();
404
+ pbrMaterial.lightModel.ior = assetPBRMaterial.ior;
405
+ pbrMaterial.lightModel.albedo = assetPBRMaterial.diffuse;
406
+ pbrMaterial.lightModel.specularFactor = new Vector4(assetPBRMaterial.specular.x, assetPBRMaterial.specular.y, assetPBRMaterial.specular.z, 1);
407
+ pbrMaterial.lightModel.glossinessFactor = assetPBRMaterial.glossness;
408
+ if (assetPBRMaterial.diffuseMap) {
409
+ pbrMaterial.lightModel.setAlbedoMap(assetPBRMaterial.diffuseMap.texture, assetPBRMaterial.diffuseMap.sampler, assetPBRMaterial.diffuseMap.texCoord, assetPBRMaterial.diffuseMap.transform);
410
+ }
411
+ if (assetPBRMaterial.common.normalMap) {
412
+ pbrMaterial.lightModel.setNormalMap(assetPBRMaterial.common.normalMap.texture, assetPBRMaterial.common.normalMap.sampler, assetPBRMaterial.common.normalMap.texCoord, assetPBRMaterial.common.normalMap.transform);
413
+ }
414
+ pbrMaterial.lightModel.normalScale = assetPBRMaterial.common.bumpScale;
415
+ if (assetPBRMaterial.common.emissiveMap) {
416
+ pbrMaterial.lightModel.setEmissiveMap(assetPBRMaterial.common.emissiveMap.texture, assetPBRMaterial.common.emissiveMap.sampler, assetPBRMaterial.common.emissiveMap.texCoord, assetPBRMaterial.common.emissiveMap.transform);
417
+ }
418
+ pbrMaterial.lightModel.emissiveColor = assetPBRMaterial.common.emissiveColor;
419
+ pbrMaterial.lightModel.emissiveStrength = assetPBRMaterial.common.emissiveStrength;
420
+ if (assetPBRMaterial.common.occlusionMap) {
421
+ pbrMaterial.lightModel.setOcclusionMap(assetPBRMaterial.common.occlusionMap.texture, assetPBRMaterial.common.occlusionMap.sampler, assetPBRMaterial.common.occlusionMap.texCoord, assetPBRMaterial.common.occlusionMap.transform);
422
+ }
423
+ pbrMaterial.lightModel.occlusionStrength = assetPBRMaterial.common.occlusionStrength;
424
+ if (assetPBRMaterial.specularGlossnessMap) {
425
+ pbrMaterial.lightModel.setSpecularMap(assetPBRMaterial.specularGlossnessMap.texture, assetPBRMaterial.specularGlossnessMap.sampler, assetPBRMaterial.specularGlossnessMap.texCoord, assetPBRMaterial.specularGlossnessMap.transform);
426
+ }
427
+ pbrMaterial.vertexTangent = assetPBRMaterial.common.useTangent;
428
+ pbrMaterial.vertexColor = assetPBRMaterial.common.vertexColor;
429
+ if (assetPBRMaterial.common.alphaMode === 'blend') {
430
+ pbrMaterial.alphaBlend = true;
431
+ } else if (assetPBRMaterial.common.alphaMode === 'mask') {
432
+ pbrMaterial.alphaCutoff = assetPBRMaterial.common.alphaCutoff;
433
+ }
434
+ if (assetPBRMaterial.common.doubleSided) {
435
+ const rasterizerState = pbrMaterial.stateSet.useRasterizerState();
436
+ rasterizerState.setCullMode('none');
437
+ }
438
+ pbrMaterial.vertexNormal = !!assetMaterial.common.vertexNormal;
439
+ return pbrMaterial;
440
+ } else if (assetMaterial.type === 'pbrMetallicRoughness') {
441
+ const assetPBRMaterial = assetMaterial;
442
+ const pbrMaterial = new PBRMetallicRoughnessMaterial();
443
+ pbrMaterial.lightModel.ior = assetPBRMaterial.ior;
444
+ pbrMaterial.lightModel.albedo = assetPBRMaterial.diffuse;
445
+ pbrMaterial.lightModel.metallic = assetPBRMaterial.metallic;
446
+ pbrMaterial.lightModel.roughness = assetPBRMaterial.roughness;
447
+ if (assetPBRMaterial.diffuseMap) {
448
+ pbrMaterial.lightModel.setAlbedoMap(assetPBRMaterial.diffuseMap.texture, assetPBRMaterial.diffuseMap.sampler, assetPBRMaterial.diffuseMap.texCoord, assetPBRMaterial.diffuseMap.transform);
449
+ }
450
+ if (assetPBRMaterial.common.normalMap) {
451
+ pbrMaterial.lightModel.setNormalMap(assetPBRMaterial.common.normalMap.texture, assetPBRMaterial.common.normalMap.sampler, assetPBRMaterial.common.normalMap.texCoord, assetPBRMaterial.common.normalMap.transform);
452
+ }
453
+ pbrMaterial.lightModel.normalScale = assetPBRMaterial.common.bumpScale;
454
+ if (assetPBRMaterial.common.emissiveMap) {
455
+ pbrMaterial.lightModel.setEmissiveMap(assetPBRMaterial.common.emissiveMap.texture, assetPBRMaterial.common.emissiveMap.sampler, assetPBRMaterial.common.emissiveMap.texCoord, assetPBRMaterial.common.emissiveMap.transform);
456
+ }
457
+ pbrMaterial.lightModel.emissiveColor = assetPBRMaterial.common.emissiveColor;
458
+ pbrMaterial.lightModel.emissiveStrength = assetPBRMaterial.common.emissiveStrength;
459
+ if (assetPBRMaterial.common.occlusionMap) {
460
+ pbrMaterial.lightModel.setOcclusionMap(assetPBRMaterial.common.occlusionMap.texture, assetPBRMaterial.common.occlusionMap.sampler, assetPBRMaterial.common.occlusionMap.texCoord, assetPBRMaterial.common.occlusionMap.transform);
461
+ }
462
+ pbrMaterial.lightModel.occlusionStrength = assetPBRMaterial.common.occlusionStrength;
463
+ if (assetPBRMaterial.metallicMap) {
464
+ pbrMaterial.lightModel.setMetallicMap(assetPBRMaterial.metallicMap.texture, assetPBRMaterial.metallicMap.sampler, assetPBRMaterial.metallicMap.texCoord, assetPBRMaterial.metallicMap.transform);
465
+ }
466
+ pbrMaterial.lightModel.metallicIndex = assetPBRMaterial.metallicIndex;
467
+ pbrMaterial.lightModel.roughnessIndex = assetPBRMaterial.roughnessIndex;
468
+ pbrMaterial.lightModel.specularFactor = assetPBRMaterial.specularFactor;
469
+ if (assetPBRMaterial.specularMap) {
470
+ pbrMaterial.lightModel.setSpecularMap(assetPBRMaterial.specularMap.texture, assetPBRMaterial.specularMap.sampler, assetPBRMaterial.specularMap.texCoord, assetPBRMaterial.specularMap.transform);
471
+ }
472
+ if (assetPBRMaterial.specularColorMap) {
473
+ pbrMaterial.lightModel.setSpecularColorMap(assetPBRMaterial.specularColorMap.texture, assetPBRMaterial.specularColorMap.sampler, assetPBRMaterial.specularColorMap.texCoord, assetPBRMaterial.specularColorMap.transform);
474
+ }
475
+ if (assetPBRMaterial.sheen) {
476
+ const sheen = assetPBRMaterial.sheen;
477
+ pbrMaterial.lightModel.useSheen = true;
478
+ pbrMaterial.lightModel.sheenColorFactor = sheen.sheenColorFactor;
479
+ pbrMaterial.lightModel.sheenRoughnessFactor = sheen.sheenRoughnessFactor;
480
+ /*
481
+ pbrMaterial.lightModel.setSheenLut(
482
+ await assetManager.fetchBuiltinTexture(BUILTIN_ASSET_TEXTURE_SHEEN_LUT)
483
+ );
484
+ */ if (sheen.sheenColorMap) {
485
+ pbrMaterial.lightModel.setSheenColorMap(sheen.sheenColorMap.texture, sheen.sheenColorMap.sampler, sheen.sheenColorMap.texCoord, sheen.sheenColorMap.transform);
486
+ }
487
+ if (sheen.sheenRoughnessMap) {
488
+ pbrMaterial.lightModel.setSheenRoughnessMap(sheen.sheenRoughnessMap.texture, sheen.sheenRoughnessMap.sampler, sheen.sheenRoughnessMap.texCoord, sheen.sheenRoughnessMap.transform);
489
+ }
490
+ }
491
+ if (assetPBRMaterial.clearcoat) {
492
+ const cc = assetPBRMaterial.clearcoat;
493
+ pbrMaterial.lightModel.useClearcoat = true;
494
+ pbrMaterial.lightModel.clearcoatIntensity = cc.clearCoatFactor;
495
+ pbrMaterial.lightModel.clearcoatRoughnessFactor = cc.clearCoatRoughnessFactor;
496
+ if (cc.clearCoatIntensityMap) {
497
+ pbrMaterial.lightModel.setClearcoatIntensityMap(cc.clearCoatIntensityMap.texture, cc.clearCoatIntensityMap.sampler, cc.clearCoatIntensityMap.texCoord, cc.clearCoatIntensityMap.transform);
498
+ }
499
+ if (cc.clearCoatRoughnessMap) {
500
+ pbrMaterial.lightModel.setClearcoatRoughnessMap(cc.clearCoatRoughnessMap.texture, cc.clearCoatRoughnessMap.sampler, cc.clearCoatRoughnessMap.texCoord, cc.clearCoatRoughnessMap.transform);
501
+ }
502
+ if (cc.clearCoatNormalMap) {
503
+ pbrMaterial.lightModel.setClearcoatNormalMap(cc.clearCoatNormalMap.texture, cc.clearCoatNormalMap.sampler, cc.clearCoatNormalMap.texCoord, cc.clearCoatNormalMap.transform);
504
+ }
505
+ }
506
+ pbrMaterial.vertexTangent = assetPBRMaterial.common.useTangent;
507
+ pbrMaterial.vertexColor = assetPBRMaterial.common.vertexColor;
508
+ if (assetPBRMaterial.common.alphaMode === 'blend') {
509
+ pbrMaterial.alphaBlend = true;
510
+ } else if (assetPBRMaterial.common.alphaMode === 'mask') {
511
+ pbrMaterial.alphaCutoff = assetPBRMaterial.common.alphaCutoff;
512
+ }
513
+ if (assetPBRMaterial.common.doubleSided) {
514
+ const rasterizerState = pbrMaterial.stateSet.useRasterizerState();
515
+ rasterizerState.setCullMode('none');
516
+ }
517
+ pbrMaterial.vertexNormal = !!assetMaterial.common.vertexNormal;
518
+ return pbrMaterial;
519
+ }
520
+ }
521
+ /** @internal */ async _loadMaterial(gltf, materialInfo, vertexColor, vertexNormal, useTangent) {
522
+ let assetMaterial = null;
523
+ let pbrMetallicRoughness = null;
524
+ let pbrSpecularGlossness = null;
525
+ const pbrCommon = {
526
+ useTangent,
527
+ vertexColor,
528
+ vertexNormal,
529
+ bumpScale: 1,
530
+ emissiveColor: Vector3.zero(),
531
+ emissiveStrength: 1,
532
+ occlusionStrength: 1
533
+ };
534
+ switch(materialInfo?.alphaMode){
535
+ case 'BLEND':
536
+ {
537
+ pbrCommon.alphaMode = 'blend';
538
+ break;
539
+ }
540
+ case 'MASK':
541
+ {
542
+ pbrCommon.alphaMode = 'mask';
543
+ pbrCommon.alphaCutoff = materialInfo.alphaCutoff ?? 0.5;
544
+ break;
545
+ }
546
+ }
547
+ if (materialInfo?.doubleSided) {
548
+ pbrCommon.doubleSided = true;
549
+ }
550
+ if (materialInfo?.pbrMetallicRoughness || materialInfo?.extensions?.KHR_materials_pbrSpecularGlossiness) {
551
+ pbrCommon.normalMap = materialInfo.normalTexture ? await this._loadTexture(gltf, materialInfo.normalTexture, false) : null;
552
+ pbrCommon.bumpScale = materialInfo.normalTexture?.scale ?? 1;
553
+ pbrCommon.occlusionMap = materialInfo.occlusionTexture ? await this._loadTexture(gltf, materialInfo.occlusionTexture, false) : null;
554
+ pbrCommon.occlusionStrength = materialInfo.occlusionTexture?.strength ?? 1;
555
+ pbrCommon.emissiveMap = materialInfo.emissiveTexture ? await this._loadTexture(gltf, materialInfo.emissiveTexture, false) : null;
556
+ pbrCommon.emissiveStrength = materialInfo?.extensions?.KHR_materials_emissive_strength?.emissiveStrength ?? 1;
557
+ pbrCommon.emissiveColor = materialInfo.emissiveFactor ? new Vector3(materialInfo.emissiveFactor) : Vector3.zero();
558
+ }
559
+ if (materialInfo?.pbrMetallicRoughness) {
560
+ pbrMetallicRoughness = {
561
+ type: 'pbrMetallicRoughness',
562
+ ior: 1.5,
563
+ common: pbrCommon
564
+ };
565
+ pbrMetallicRoughness.diffuse = new Vector4(materialInfo.pbrMetallicRoughness.baseColorFactor ?? [
566
+ 1,
567
+ 1,
568
+ 1,
569
+ 1
570
+ ]);
571
+ pbrMetallicRoughness.metallic = materialInfo.pbrMetallicRoughness.metallicFactor ?? 1;
572
+ pbrMetallicRoughness.roughness = materialInfo.pbrMetallicRoughness.roughnessFactor ?? 1;
573
+ pbrMetallicRoughness.diffuseMap = materialInfo.pbrMetallicRoughness.baseColorTexture ? await this._loadTexture(gltf, materialInfo.pbrMetallicRoughness.baseColorTexture, true) : null;
574
+ pbrMetallicRoughness.metallicMap = materialInfo.pbrMetallicRoughness.metallicRoughnessTexture ? await this._loadTexture(gltf, materialInfo.pbrMetallicRoughness.metallicRoughnessTexture, false) : null;
575
+ pbrMetallicRoughness.metallicIndex = 2;
576
+ pbrMetallicRoughness.roughnessIndex = 1;
577
+ }
578
+ if (materialInfo?.extensions?.KHR_materials_pbrSpecularGlossiness) {
579
+ const sg = materialInfo.extensions?.KHR_materials_pbrSpecularGlossiness;
580
+ pbrSpecularGlossness = {
581
+ type: 'pbrSpecularGlossiness',
582
+ ior: 1.5,
583
+ common: pbrCommon
584
+ };
585
+ pbrSpecularGlossness.diffuse = new Vector4(sg.diffuseFactor ?? [
586
+ 1,
587
+ 1,
588
+ 1,
589
+ 1
590
+ ]);
591
+ pbrSpecularGlossness.specular = new Vector3(sg.specularFactor ?? [
592
+ 1,
593
+ 1,
594
+ 1
595
+ ]);
596
+ pbrSpecularGlossness.glossness = sg.glossnessFactor ?? 1;
597
+ pbrSpecularGlossness.diffuseMap = sg.diffuseTexture ? await this._loadTexture(gltf, sg.diffuseTexture, true) : null;
598
+ pbrSpecularGlossness.specularGlossnessMap = sg.specularGlossinessTexture ? await this._loadTexture(gltf, sg.specularGlossinessTexture, true) : null;
599
+ }
600
+ assetMaterial = pbrSpecularGlossness || pbrMetallicRoughness;
601
+ if (!assetMaterial || materialInfo?.extensions?.KHR_materials_unlit) {
602
+ if (materialInfo?.extensions?.KHR_materials_unlit) {
603
+ assetMaterial = {
604
+ type: 'unlit',
605
+ common: pbrCommon,
606
+ diffuse: pbrMetallicRoughness?.diffuse ?? Vector4.one(),
607
+ diffuseMap: pbrMetallicRoughness?.diffuseMap ?? null
608
+ };
609
+ } else {
610
+ assetMaterial = {
611
+ type: 'pbrMetallicRoughness',
612
+ common: pbrCommon,
613
+ diffuse: Vector4.one(),
614
+ metallic: 1,
615
+ roughness: 1,
616
+ diffuseMap: null,
617
+ metallicMap: null,
618
+ metallicIndex: 2,
619
+ roughnessIndex: 1
620
+ };
621
+ }
622
+ }
623
+ if (assetMaterial.type !== 'unlit' && materialInfo?.extensions?.KHR_materials_ior) {
624
+ assetMaterial.ior = materialInfo.extensions.KHR_materials_ior.ior ?? 1.5;
625
+ }
626
+ if (assetMaterial.type === 'pbrMetallicRoughness') {
627
+ pbrMetallicRoughness = assetMaterial;
628
+ // KHR_materials_specular extension
629
+ const specularColorFactor = materialInfo?.extensions?.KHR_materials_specular?.specularColorFactor ?? [
630
+ 1,
631
+ 1,
632
+ 1
633
+ ];
634
+ pbrMetallicRoughness.specularFactor = new Vector4(...specularColorFactor, materialInfo?.extensions?.KHR_materials_specular?.specularFactor ?? 1);
635
+ pbrMetallicRoughness.specularMap = materialInfo?.extensions?.KHR_materials_specular?.specularTexture ? await this._loadTexture(gltf, materialInfo.extensions.KHR_materials_specular.specularTexture, false) : null;
636
+ pbrMetallicRoughness.specularColorMap = materialInfo?.extensions?.KHR_materials_specular?.specularColorTexture ? await this._loadTexture(gltf, materialInfo.extensions.KHR_materials_specular.specularColorTexture, true) : null;
637
+ // KHR_materials_sheen
638
+ const sheen = materialInfo?.extensions?.KHR_materials_sheen;
639
+ if (sheen) {
640
+ pbrMetallicRoughness.sheen = {
641
+ sheenColorFactor: new Vector3(sheen.sheenColorFactor ?? [
642
+ 0,
643
+ 0,
644
+ 0
645
+ ]),
646
+ sheenColorMap: sheen.sheenColorTexture ? await this._loadTexture(gltf, sheen.sheenColorTexture, true) : null,
647
+ sheenRoughnessFactor: sheen.sheenRoughnessFactor ?? 0,
648
+ sheenRoughnessMap: sheen.sheenRoughnessTexture ? await this._loadTexture(gltf, sheen.sheenRoughnessTexture, true) : null
649
+ };
650
+ }
651
+ // KHR_materials_clearcoat
652
+ const cc = materialInfo?.extensions?.KHR_materials_clearcoat;
653
+ if (cc) {
654
+ pbrMetallicRoughness.clearcoat = {
655
+ clearCoatFactor: cc.clearcoatFactor ?? 0,
656
+ clearCoatIntensityMap: cc.clearcoatTexture ? await this._loadTexture(gltf, cc.clearcoatTexture, false) : null,
657
+ clearCoatRoughnessFactor: cc.clearcoatRoughnessFactor ?? 0,
658
+ clearCoatRoughnessMap: cc.clearcoatRoughnessTexture ? await this._loadTexture(gltf, cc.clearcoatRoughnessTexture, false) : null,
659
+ clearCoatNormalMap: cc.clearcoatNormalTexture ? await this._loadTexture(gltf, cc.clearcoatNormalTexture, false) : null
660
+ };
661
+ }
662
+ }
663
+ return await this._createMaterial(gltf._manager, assetMaterial);
664
+ }
665
+ /** @internal */ async _loadTexture(gltf, info, sRGB) {
666
+ const mt = {
667
+ texture: null,
668
+ sampler: null,
669
+ texCoord: info.texCoord ?? 0,
670
+ transform: null
671
+ };
672
+ const textureInfo = gltf.textures[info.index];
673
+ if (textureInfo) {
674
+ if (info.extensions?.KHR_texture_transform) {
675
+ const uvTransform = info.extensions.KHR_texture_transform;
676
+ if (uvTransform.texCoord !== undefined) {
677
+ mt.texCoord = uvTransform.texCoord;
678
+ }
679
+ const rotation = uvTransform.rotation !== undefined ? Matrix4x4.rotationZ(-uvTransform.rotation) : Matrix4x4.identity();
680
+ const scale = uvTransform.scale !== undefined ? new Vector3(uvTransform.scale[0], uvTransform.scale[1], 1) : Vector3.one();
681
+ const translation = uvTransform.offset !== undefined ? new Vector3(uvTransform.offset[0], uvTransform.offset[1], 0) : Vector3.zero();
682
+ mt.transform = Matrix4x4.scaling(scale).multiplyLeft(rotation).translateLeft(translation);
683
+ }
684
+ let wrapS = 'repeat';
685
+ let wrapT = 'repeat';
686
+ let magFilter = 'linear';
687
+ let minFilter = 'linear';
688
+ let mipFilter = 'linear';
689
+ const samplerIndex = textureInfo.sampler;
690
+ const sampler = gltf.samplers && gltf.samplers[samplerIndex];
691
+ if (sampler) {
692
+ switch(sampler.wrapS){
693
+ case 0x2901:
694
+ wrapS = 'repeat';
695
+ break;
696
+ case 0x8370:
697
+ wrapS = 'mirrored-repeat';
698
+ break;
699
+ case 0x812f:
700
+ wrapS = 'clamp';
701
+ break;
702
+ }
703
+ switch(sampler.wrapT){
704
+ case 0x2901:
705
+ wrapT = 'repeat';
706
+ break;
707
+ case 0x8370:
708
+ wrapT = 'mirrored-repeat';
709
+ break;
710
+ case 0x812f:
711
+ wrapT = 'clamp';
712
+ break;
713
+ }
714
+ switch(sampler.magFilter){
715
+ case 0x2600:
716
+ magFilter = 'nearest';
717
+ break;
718
+ case 0x2601:
719
+ magFilter = 'linear';
720
+ break;
721
+ }
722
+ switch(sampler.minFilter){
723
+ case 0x2600:
724
+ minFilter = 'nearest';
725
+ mipFilter = 'none';
726
+ break;
727
+ case 0x2601:
728
+ minFilter = 'linear';
729
+ mipFilter = 'none';
730
+ break;
731
+ case 0x2700:
732
+ minFilter = 'nearest';
733
+ mipFilter = 'nearest';
734
+ break;
735
+ case 0x2701:
736
+ minFilter = 'linear';
737
+ mipFilter = 'nearest';
738
+ break;
739
+ case 0x2702:
740
+ minFilter = 'nearest';
741
+ mipFilter = 'linear';
742
+ break;
743
+ case 0x2703:
744
+ minFilter = 'linear';
745
+ mipFilter = 'linear';
746
+ break;
747
+ }
748
+ }
749
+ const imageIndex = textureInfo.source;
750
+ const hash = `${imageIndex}:${!!sRGB}:${wrapS}:${wrapT}:${minFilter}:${magFilter}:${mipFilter}`;
751
+ mt.texture = gltf._textureCache[hash];
752
+ if (!mt.texture) {
753
+ const image = gltf.images[imageIndex];
754
+ if (image) {
755
+ if (image.uri) {
756
+ const imageUrl = this._normalizeURI(gltf._baseURI, image.uri);
757
+ mt.texture = await gltf._manager.fetchTexture(imageUrl, {
758
+ linearColorSpace: !sRGB
759
+ });
760
+ mt.texture.name = imageUrl;
761
+ } else if (typeof image.bufferView === 'number' && image.mimeType) {
762
+ const bufferView = gltf.bufferViews && gltf.bufferViews[image.bufferView];
763
+ if (bufferView) {
764
+ const arrayBuffer = gltf._loadedBuffers && gltf._loadedBuffers[bufferView.buffer];
765
+ if (arrayBuffer) {
766
+ const view = new Uint8Array(arrayBuffer, bufferView.byteOffset || 0, bufferView.byteLength);
767
+ const mimeType = image.mimeType;
768
+ const blob = new Blob([
769
+ view
770
+ ], {
771
+ type: mimeType
772
+ });
773
+ const sourceURI = URL.createObjectURL(blob);
774
+ mt.texture = await gltf._manager.fetchTexture(sourceURI, {
775
+ mimeType,
776
+ linearColorSpace: !sRGB
777
+ });
778
+ URL.revokeObjectURL(sourceURI);
779
+ }
780
+ }
781
+ }
782
+ }
783
+ if (mt.texture) {
784
+ gltf._textureCache[hash] = mt.texture;
785
+ }
786
+ }
787
+ if (mt.texture) {
788
+ mt.sampler = Application.instance.device.createSampler({
789
+ addressU: wrapS,
790
+ addressV: wrapT,
791
+ magFilter: magFilter,
792
+ minFilter: minFilter,
793
+ mipFilter: mipFilter
794
+ });
795
+ }
796
+ }
797
+ return mt;
798
+ }
799
+ /** @internal */ _primitiveType(type) {
800
+ switch(type){
801
+ case 0:
802
+ return 'point-list';
803
+ case 1:
804
+ return 'line-list';
805
+ /* FIXME:
806
+ case 2: // GL_LINE_LOOP
807
+ return PrimitiveType.LineLoop;
808
+ */ case 3:
809
+ return 'line-strip';
810
+ case 4:
811
+ return 'triangle-list';
812
+ case 5:
813
+ return 'triangle-strip';
814
+ case 6:
815
+ return 'triangle-fan';
816
+ default:
817
+ return null;
818
+ }
819
+ }
820
+ /** @internal */ _loadIndexBuffer(gltf, accessorIndex, primitive, meshData) {
821
+ this._setBuffer(gltf, accessorIndex, primitive, null, meshData);
822
+ }
823
+ /** @internal */ _loadVertexBuffer(gltf, attribName, accessorIndex, primitive, subMeshData) {
824
+ let semantic = null;
825
+ switch(attribName){
826
+ case 'POSITION':
827
+ semantic = 'position';
828
+ break;
829
+ case 'NORMAL':
830
+ semantic = 'normal';
831
+ break;
832
+ case 'TANGENT':
833
+ semantic = 'tangent';
834
+ break;
835
+ case 'TEXCOORD_0':
836
+ semantic = 'texCoord0';
837
+ break;
838
+ case 'TEXCOORD_1':
839
+ semantic = 'texCoord1';
840
+ break;
841
+ case 'TEXCOORD_2':
842
+ semantic = 'texCoord2';
843
+ break;
844
+ case 'TEXCOORD_3':
845
+ semantic = 'texCoord3';
846
+ break;
847
+ case 'TEXCOORD_4':
848
+ semantic = 'texCoord4';
849
+ break;
850
+ case 'TEXCOORD_5':
851
+ semantic = 'texCoord5';
852
+ break;
853
+ case 'TEXCOORD_6':
854
+ semantic = 'texCoord6';
855
+ break;
856
+ case 'TEXCOORD_7':
857
+ semantic = 'texCoord7';
858
+ break;
859
+ case 'COLOR_0':
860
+ semantic = 'diffuse';
861
+ break;
862
+ case 'JOINTS_0':
863
+ semantic = 'blendIndices';
864
+ break;
865
+ case 'WEIGHTS_0':
866
+ semantic = 'blendWeights';
867
+ break;
868
+ default:
869
+ return;
870
+ }
871
+ this._setBuffer(gltf, accessorIndex, primitive, semantic, subMeshData);
872
+ }
873
+ /** @internal */ _setBuffer(gltf, accessorIndex, primitive, semantic, subMeshData) {
874
+ const device = Application.instance.device;
875
+ const accessor = gltf._accessors[accessorIndex];
876
+ const componentCount = accessor.getComponentCount(accessor.type);
877
+ const normalized = !!accessor.normalized;
878
+ const hash = `${accessorIndex}:${!!semantic}:${Number(normalized)}`;
879
+ let buffer = gltf._bufferCache[hash];
880
+ if (!buffer) {
881
+ let data = accessor.getNormalizedDeinterlacedView(gltf);
882
+ if (semantic && !(data instanceof Float32Array)) {
883
+ const floatData = new Float32Array(data.length);
884
+ floatData.set(data);
885
+ data = floatData;
886
+ }
887
+ if (!semantic) {
888
+ if (!(data instanceof Uint8Array) && !(data instanceof Uint16Array) && !(data instanceof Uint32Array)) {
889
+ console.error('Invalid index buffer component type');
890
+ return;
891
+ }
892
+ if (data instanceof Uint32Array && !device.getDeviceCaps().miscCaps.support32BitIndex) {
893
+ console.error('Device does not support 32bit vertex index');
894
+ return;
895
+ }
896
+ if (data instanceof Uint8Array) {
897
+ const uint16Data = new Uint16Array(data.length);
898
+ uint16Data.set(data);
899
+ data = uint16Data;
900
+ }
901
+ }
902
+ if (!semantic) {
903
+ buffer = device.createIndexBuffer(data, {
904
+ managed: true
905
+ });
906
+ } else {
907
+ const attribFormat = device.getVertexAttribFormat(semantic, 'f32', componentCount);
908
+ buffer = device.createVertexBuffer(attribFormat, data);
909
+ }
910
+ gltf._bufferCache[hash] = buffer;
911
+ }
912
+ if (buffer) {
913
+ if (!semantic) {
914
+ primitive.setIndexBuffer(buffer);
915
+ primitive.indexCount = buffer.length;
916
+ } else {
917
+ primitive.setVertexBuffer(buffer);
918
+ if (semantic === 'position') {
919
+ if (!primitive.getIndexBuffer()) {
920
+ primitive.indexCount = Math.floor(buffer.byteLength / 12);
921
+ }
922
+ const data = accessor.getNormalizedDeinterlacedView(gltf);
923
+ subMeshData.rawPositions = data;
924
+ const min = accessor.min;
925
+ const max = accessor.max;
926
+ if (min && max) {
927
+ primitive.setBoundingVolume(new BoundingBox(new Vector3(min), new Vector3(max)));
928
+ } else {
929
+ const bbox = new BoundingBox();
930
+ bbox.beginExtend();
931
+ for(let i = 0; i < data.length; i++){
932
+ const v = new Vector3(data[i * componentCount], data[i * componentCount + 1], data[i * componentCount + 2]);
933
+ bbox.extend(v);
934
+ }
935
+ if (bbox.isValid()) {
936
+ primitive.setBoundingVolume(bbox);
937
+ }
938
+ }
939
+ } else if (semantic === 'blendIndices') {
940
+ subMeshData.rawBlendIndices = accessor.getNormalizedDeinterlacedView(gltf);
941
+ } else if (semantic === 'blendWeights') {
942
+ subMeshData.rawJointWeights = accessor.getNormalizedDeinterlacedView(gltf);
943
+ }
944
+ }
945
+ }
946
+ return buffer;
947
+ }
948
+ /** @internal */ isGLB(data) {
949
+ if (data.byteLength > 12) {
950
+ const p = new Uint32Array(data, 0, 3);
951
+ if (p[0] === 0x46546c67 && p[1] === 2 && p[2] === data.byteLength) {
952
+ return true;
953
+ }
954
+ }
955
+ return false;
956
+ }
957
+ /** @internal */ getGLBChunkInfo(data, offset) {
958
+ const header = new Uint32Array(data, offset, 2);
959
+ const start = offset + 8;
960
+ const length = header[0];
961
+ const type = header[1];
962
+ return {
963
+ start,
964
+ length,
965
+ type
966
+ };
967
+ }
968
+ /** @internal */ getGLBChunkInfos(data) {
969
+ const infos = [];
970
+ let offset = 12;
971
+ while(offset < data.byteLength){
972
+ const info = this.getGLBChunkInfo(data, offset);
973
+ infos.push(info);
974
+ offset += info.length + 8;
975
+ }
976
+ return infos;
977
+ }
978
+ }
979
+
980
+ export { GLTFLoader };
981
+ //# sourceMappingURL=gltf_loader.js.map