@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
package/dist/app.js ADDED
@@ -0,0 +1,173 @@
1
+ import { InputManager } from './input/inputmgr.js';
2
+ import { makeEventTarget } from '@zephyr3d/base';
3
+
4
+ /**
5
+ * Event that will be fired every frame
6
+ *
7
+ * @remarks
8
+ * This is where all the rendering work is done.
9
+ *
10
+ * @public
11
+ */ class AppTickEvent {
12
+ type = 'tick';
13
+ }
14
+ /**
15
+ * This event will be fired whenever the device size changes
16
+ * @public
17
+ */ class AppResizeEvent {
18
+ width;
19
+ height;
20
+ type;
21
+ constructor(width, height){
22
+ this.type = 'resize';
23
+ this.width = width;
24
+ this.height = height;
25
+ }
26
+ }
27
+ /**
28
+ * Application class
29
+ *
30
+ * @remarks
31
+ * This is the entry point of your application.
32
+ * The Application is responsible for initializing the rendering device
33
+ * and doing the rendering loop.
34
+ * The Application can not be created more than once. You can get the
35
+ * instance by calling the 'Application.instance' static method.
36
+ *
37
+ * @public
38
+ */ class Application extends makeEventTarget(Object)() {
39
+ _options;
40
+ _device;
41
+ _inputManager;
42
+ _running;
43
+ _ready;
44
+ _canRender;
45
+ _drawEvent;
46
+ _logger;
47
+ _elapsed;
48
+ static _instance;
49
+ /**
50
+ * Creates an instance of Application
51
+ * @param opt - The creation options
52
+ */ constructor(opt){
53
+ super();
54
+ if (Application._instance) {
55
+ throw new Error('It is not allowed to have multiple Application instances');
56
+ }
57
+ Application._instance = this;
58
+ this._options = {
59
+ backend: opt.backend,
60
+ enableMSAA: opt.enableMSAA ?? false,
61
+ pixelRatio: opt.pixelRatio ?? window.devicePixelRatio ?? 1,
62
+ canvas: opt.canvas
63
+ };
64
+ this._inputManager = new InputManager(this);
65
+ this._running = null;
66
+ this._ready = false;
67
+ this._canRender = false;
68
+ this._elapsed = 0;
69
+ this._drawEvent = new AppTickEvent();
70
+ this._logger = {
71
+ log (text, mode) {
72
+ if (mode === 'warn') {
73
+ console.warn(text);
74
+ } else if (mode === 'error') {
75
+ console.error(text);
76
+ } else if (mode === 'debug') {
77
+ console.debug(text);
78
+ } else if (mode === 'info') {
79
+ console.info(text);
80
+ } else {
81
+ console.log(text);
82
+ }
83
+ }
84
+ };
85
+ }
86
+ /** The input manager instance */ get inputManager() {
87
+ return this._inputManager;
88
+ }
89
+ /** The options that was used to create the application */ get options() {
90
+ return this._options;
91
+ }
92
+ /**
93
+ * Query if the device is ok to render objects now.
94
+ *
95
+ * @remarks
96
+ * False will be returned if the device is lost.
97
+ */ get canRender() {
98
+ return this._canRender;
99
+ }
100
+ /**
101
+ * Query time elapsed since last frame in seconds
102
+ */ get timeElapsedInSeconds() {
103
+ return this._elapsed;
104
+ }
105
+ /** Gets the singleton instance of the application */ static get instance() {
106
+ return this._instance;
107
+ }
108
+ /** The rendering device that was initialized by the application */ get device() {
109
+ return this._device;
110
+ }
111
+ /** Gets the device type */ get deviceType() {
112
+ return this._options.backend.typeName();
113
+ }
114
+ /** The logger object */ get logger() {
115
+ return this._logger;
116
+ }
117
+ set logger(val) {
118
+ this._logger = val;
119
+ }
120
+ /** Set focus */ focus() {
121
+ this._device.canvas.focus();
122
+ }
123
+ /** Wait until the application is ready. */ async ready() {
124
+ if (!this._ready) {
125
+ this._device = await this._options.backend.createDevice(this._options.canvas, {
126
+ dpr: this._options.pixelRatio,
127
+ msaa: !!this._options.enableMSAA
128
+ });
129
+ if (!this._device) {
130
+ throw new Error('App.init(): create device failed');
131
+ }
132
+ this._device.canvas.focus();
133
+ this._inputManager.start();
134
+ this._device.on('resize', (ev)=>{
135
+ this.dispatchEvent(new AppResizeEvent(ev.width, ev.height));
136
+ });
137
+ this._ready = true;
138
+ }
139
+ }
140
+ /** Render one frame */ frame() {
141
+ if (this._ready) {
142
+ this._canRender = this.device.beginFrame();
143
+ this._elapsed = this.device.frameInfo.elapsedFrame * 0.001;
144
+ this.device.setFramebuffer(null);
145
+ this.device.setViewport(null);
146
+ this.device.setScissor(null);
147
+ this.dispatchEvent(this._drawEvent);
148
+ this.device.endFrame();
149
+ }
150
+ }
151
+ /** Start running the rendering loop */ run() {
152
+ if (this._running) {
153
+ return;
154
+ }
155
+ const that = this;
156
+ (function entry() {
157
+ that._running = requestAnimationFrame(entry);
158
+ that.frame();
159
+ })();
160
+ }
161
+ /** Stop running the rendering loop */ stop() {
162
+ if (this._running) {
163
+ cancelAnimationFrame(this._running);
164
+ this._running = null;
165
+ }
166
+ }
167
+ /** Message log */ log(text, mode) {
168
+ this._logger?.log(text, mode);
169
+ }
170
+ }
171
+
172
+ export { AppResizeEvent, AppTickEvent, Application };
173
+ //# sourceMappingURL=app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,476 @@
1
+ import { HttpRequest, isPowerOf2, nextPowerOf2, Vector3 } from '@zephyr3d/base';
2
+ import { GLTFLoader } from './loaders/gltf/gltf_loader.js';
3
+ import { WebImageLoader } from './loaders/image/webimage_loader.js';
4
+ import { DDSLoader } from './loaders/dds/dds_loader.js';
5
+ import { HDRLoader } from './loaders/hdr/hdr.js';
6
+ import { SceneNode } from '../scene/scene_node.js';
7
+ import { Mesh } from '../scene/mesh.js';
8
+ import { AnimationClip } from '../animation/animation.js';
9
+ import { AnimationSet } from '../animation/animationset.js';
10
+ import { TranslationTrack } from '../animation/translationtrack.js';
11
+ import { RotationTrack } from '../animation/rotationtrack.js';
12
+ import '../animation/eulerrotationtrack.js';
13
+ import { ScaleTrack } from '../animation/scaletrack.js';
14
+ import { Skeleton } from '../animation/skeleton.js';
15
+ import { BoundingBox } from '../utility/bounding_volume.js';
16
+ import { Application } from '../app.js';
17
+ import '../shaders/framework.js';
18
+ import '@zephyr3d/device';
19
+ import { CopyBlitter } from '../blitter/copy.js';
20
+ import { getSheenLutLoader, getTestCubemapLoader } from './builtin.js';
21
+ import { GraphNode } from '../scene/graph_node.js';
22
+ import { BUILTIN_ASSET_TEXTURE_SHEEN_LUT, BUILTIN_ASSET_TEST_CUBEMAP } from '../values.js';
23
+ import { TGALoader } from './loaders/image/tga_Loader.js';
24
+
25
+ /**
26
+ * The asset manager
27
+ * @public
28
+ */ class AssetManager {
29
+ /** @internal */ static _builtinTextures = {};
30
+ /** @internal */ static _builtinTextureLoaders = {
31
+ [BUILTIN_ASSET_TEXTURE_SHEEN_LUT]: getSheenLutLoader(64),
32
+ [BUILTIN_ASSET_TEST_CUBEMAP]: getTestCubemapLoader()
33
+ };
34
+ /** @internal */ _httpRequest;
35
+ /** @internal */ _textureLoaders;
36
+ /** @internal */ _modelLoaders;
37
+ /** @internal */ _textures;
38
+ /** @internal */ _models;
39
+ /** @internal */ _binaryDatas;
40
+ /** @internal */ _textDatas;
41
+ /**
42
+ * Creates an instance of AssetManager
43
+ */ constructor(){
44
+ this._httpRequest = new HttpRequest();
45
+ this._textureLoaders = [
46
+ new WebImageLoader(),
47
+ new DDSLoader(),
48
+ new HDRLoader(),
49
+ new TGALoader()
50
+ ];
51
+ this._modelLoaders = [
52
+ new GLTFLoader()
53
+ ];
54
+ this._textures = {};
55
+ this._models = {};
56
+ this._binaryDatas = {};
57
+ this._textDatas = {};
58
+ }
59
+ /**
60
+ * HttpRequest instance of the asset manager
61
+ */ get httpRequest() {
62
+ return this._httpRequest;
63
+ }
64
+ /**
65
+ * Removes all cached assets
66
+ */ clearCache() {
67
+ this._textures = {};
68
+ this._models = {};
69
+ this._binaryDatas = {};
70
+ this._textDatas = {};
71
+ }
72
+ /**
73
+ * Adds a texture loader to the asset manager
74
+ *
75
+ * @remarks
76
+ * TODO: this should be a static method
77
+ *
78
+ * @param loader - The texture loader to be added
79
+ */ addTextureLoader(loader) {
80
+ if (loader) {
81
+ this._textureLoaders.unshift(loader);
82
+ }
83
+ }
84
+ /**
85
+ * Adds a model loader to the asset manager
86
+ *
87
+ * @remarks
88
+ * TODO: this should be a static method
89
+ *
90
+ * @param loader - The model loader to be added
91
+ */ addModelLoader(loader) {
92
+ if (loader) {
93
+ this._modelLoaders.unshift(loader);
94
+ }
95
+ }
96
+ /**
97
+ * Fetches a text resource from a given URL
98
+ * @param url - The URL from where to fetch the resource
99
+ * @returns The fetched text
100
+ */ async fetchTextData(url) {
101
+ let P = this._textDatas[url];
102
+ if (!P) {
103
+ P = this.loadTextData(url);
104
+ this._textDatas[url] = P;
105
+ }
106
+ return P;
107
+ }
108
+ /**
109
+ * Fetches a binary resource from a given URL
110
+ * @param url - The URL from where to fetch the resource
111
+ * @returns
112
+ */ async fetchBinaryData(url) {
113
+ let P = this._binaryDatas[url];
114
+ if (!P) {
115
+ P = this.loadBinaryData(url);
116
+ this._binaryDatas[url] = P;
117
+ }
118
+ return P;
119
+ }
120
+ /**
121
+ * Fetches a texture resource from a given URL
122
+ * @param url - The URL from where to fetch the resource
123
+ * @param options - Options for texture fetching
124
+ * @returns The fetched texture
125
+ */ async fetchTexture(url, options) {
126
+ if (options?.texture) {
127
+ return this.loadTexture(url, options.mimeType ?? null, !options.linearColorSpace, options.samplerOptions, options.texture);
128
+ } else {
129
+ const hash = this.getHash('2d', url, options);
130
+ let P = this._textures[hash];
131
+ if (!P) {
132
+ P = this.loadTexture(url, options?.mimeType ?? null, !options?.linearColorSpace, options?.samplerOptions);
133
+ this._textures[hash] = P;
134
+ } else {
135
+ const tex = await P;
136
+ if (tex.disposed) {
137
+ await tex.reload();
138
+ return tex;
139
+ }
140
+ }
141
+ return P;
142
+ }
143
+ }
144
+ /** @internal */ async fetchModelData(scene, url, mimeType) {
145
+ let P = this._models[url];
146
+ if (!P) {
147
+ P = this.loadModel(url, mimeType);
148
+ this._models[url] = P;
149
+ }
150
+ return P;
151
+ }
152
+ /**
153
+ * Fetches a model resource from a given URL and adds it to a scene
154
+ * @param scene - The scene to which the model node belongs
155
+ * @param url - The URL from where to fetch the resource
156
+ * @param mimeType - The MIME type of the model resource
157
+ * @returns The created model node
158
+ */ async fetchModel(scene, url, mimeType) {
159
+ const sharedModel = await this.fetchModelData(scene, url, mimeType);
160
+ return this.createSceneNode(scene, sharedModel);
161
+ }
162
+ /** @internal */ async loadTextData(url) {
163
+ return this._httpRequest.requestText(url);
164
+ }
165
+ /** @internal */ async loadBinaryData(url) {
166
+ return this._httpRequest.requestArrayBuffer(url);
167
+ }
168
+ /** @internal */ async loadTexture(url, mimeType, srgb, samplerOptions, texture) {
169
+ const data = await this._httpRequest.requestArrayBuffer(url);
170
+ let ext = '';
171
+ let filename = '';
172
+ const dataUriMatchResult = url.match(/^data:([^;]+)/);
173
+ if (dataUriMatchResult) {
174
+ mimeType = mimeType || dataUriMatchResult[1];
175
+ } else {
176
+ filename = new URL(url, new URL(location.href).origin).pathname.split('/').filter((val)=>!!val).slice(-1)[0];
177
+ const p = filename ? filename.lastIndexOf('.') : -1;
178
+ ext = p >= 0 ? filename.substring(p).toLowerCase() : null;
179
+ if (!mimeType) {
180
+ if (ext === '.jpg' || ext === '.jpeg') {
181
+ mimeType = 'image/jpg';
182
+ } else if (ext === '.png') {
183
+ mimeType = 'image/png';
184
+ }
185
+ }
186
+ }
187
+ for (const loader of this._textureLoaders){
188
+ if ((!ext || !loader.supportExtension(ext)) && (!mimeType || !loader.supportMIMEType(mimeType))) {
189
+ continue;
190
+ }
191
+ const tex = await this.doLoadTexture(loader, filename, mimeType, data, !!srgb, samplerOptions, texture);
192
+ tex.name = filename;
193
+ if (url.match(/^blob:/)) {
194
+ tex.restoreHandler = async (tex)=>{
195
+ await this.doLoadTexture(loader, filename, mimeType, data, !!srgb, samplerOptions, tex);
196
+ };
197
+ } else {
198
+ const so = samplerOptions ? null : {
199
+ ...samplerOptions
200
+ };
201
+ tex.restoreHandler = async (tex)=>{
202
+ await this.loadTexture(url, mimeType, srgb, so, tex);
203
+ };
204
+ }
205
+ return tex;
206
+ }
207
+ throw new Error(`Can not find loader for asset ${url}`);
208
+ }
209
+ /** @internal */ async doLoadTexture(loader, url, mimeType, data, srgb, samplerOptions, texture) {
210
+ const device = Application.instance.device;
211
+ if (device.type !== 'webgl') {
212
+ return await loader.load(this, url, mimeType, data, srgb, samplerOptions, texture);
213
+ } else {
214
+ let tex = await loader.load(this, url, mimeType, data, srgb, samplerOptions);
215
+ if (texture) {
216
+ const magFilter = tex.width !== texture.width || tex.height !== texture.height ? 'linear' : 'nearest';
217
+ const minFilter = magFilter;
218
+ const mipFilter = 'none';
219
+ const sampler = device.createSampler({
220
+ addressU: 'clamp',
221
+ addressV: 'clamp',
222
+ magFilter,
223
+ minFilter,
224
+ mipFilter
225
+ });
226
+ const blitter = new CopyBlitter();
227
+ blitter.blit(tex, texture, sampler);
228
+ tex = texture;
229
+ } else {
230
+ const po2_w = isPowerOf2(tex.width);
231
+ const po2_h = isPowerOf2(tex.height);
232
+ const srgb = tex.isSRGBFormat();
233
+ if (srgb || !po2_w || !po2_h) {
234
+ const newWidth = po2_w ? tex.width : nextPowerOf2(tex.width);
235
+ const newHeight = po2_h ? tex.height : nextPowerOf2(tex.height);
236
+ const magFilter = newWidth !== tex.width || newHeight !== tex.height ? 'linear' : 'nearest';
237
+ const minFilter = magFilter;
238
+ const mipFilter = 'none';
239
+ const sampler = device.createSampler({
240
+ addressU: 'clamp',
241
+ addressV: 'clamp',
242
+ magFilter,
243
+ minFilter,
244
+ mipFilter
245
+ });
246
+ const destFormat = srgb ? 'rgba8unorm' : tex.format;
247
+ const blitter = new CopyBlitter();
248
+ const newTexture = tex.isTexture2D() ? device.createTexture2D(destFormat, newWidth, newHeight) : device.createCubeTexture(destFormat, newWidth);
249
+ blitter.blit(tex, newTexture, sampler);
250
+ tex.dispose();
251
+ tex = newTexture;
252
+ }
253
+ }
254
+ return tex;
255
+ }
256
+ }
257
+ /** @internal */ async loadModel(url, mimeType, name) {
258
+ const data = await this.httpRequest.requestBlob(url);
259
+ const filename = new URL(url, new URL(location.href).origin).pathname.split('/').filter((val)=>!!val).slice(-1)[0];
260
+ const p = filename ? filename.lastIndexOf('.') : -1;
261
+ const ext = p >= 0 ? filename.substring(p) : null;
262
+ for (const loader of this._modelLoaders){
263
+ if (!loader.supportExtension(ext) && !loader.supportMIMEType(mimeType || data.type)) {
264
+ continue;
265
+ }
266
+ const model = await loader.load(this, url, mimeType || data.type, data);
267
+ if (!model) {
268
+ throw new Error(`Load asset failed: ${url}`);
269
+ }
270
+ model.name = name || filename;
271
+ return model;
272
+ }
273
+ throw new Error(`Can not find loader for asset ${url}`);
274
+ }
275
+ /**
276
+ * Fetches a built-in texture
277
+ * @param name - Name of the built-in texture
278
+ * @returns The built-in texture
279
+ */ async fetchBuiltinTexture(name, texture) {
280
+ const loader = AssetManager._builtinTextureLoaders[name];
281
+ if (!loader) {
282
+ throw new Error(`Unknown builtin texture name: ${name}`);
283
+ }
284
+ if (texture) {
285
+ return loader(this, texture);
286
+ } else {
287
+ let P = AssetManager._builtinTextures[name];
288
+ if (!P) {
289
+ P = loader(this);
290
+ AssetManager._builtinTextures[name] = P;
291
+ }
292
+ const tex = await P;
293
+ tex.restoreHandler = async (tex)=>{
294
+ await loader(this, tex);
295
+ };
296
+ return tex;
297
+ }
298
+ }
299
+ /** @internal */ createSceneNode(scene, model, sceneIndex) {
300
+ const group = new SceneNode(scene);
301
+ group.name = model.name;
302
+ let animationSet = new AnimationSet(scene);
303
+ for(let i = 0; i < model.scenes.length; i++){
304
+ if (typeof sceneIndex === 'number' && sceneIndex >= 0 && i !== sceneIndex) {
305
+ continue;
306
+ } else if ((sceneIndex === undefined || sceneIndex === null) && model.activeScene >= 0 && i !== model.activeScene) {
307
+ continue;
308
+ }
309
+ const assetScene = model.scenes[i];
310
+ const skeletonMeshMap = new Map();
311
+ const nodeMap = new Map();
312
+ for(let k = 0; k < assetScene.rootNodes.length; k++){
313
+ this.setAssetNodeToSceneNode(scene, group, model, assetScene.rootNodes[k], skeletonMeshMap, nodeMap);
314
+ }
315
+ for (const animationData of model.animations){
316
+ const animation = new AnimationClip(animationData.name, group);
317
+ animationSet.add(animation);
318
+ for (const track of animationData.tracks){
319
+ if (track.type === 'translation') {
320
+ animation.addTrack(nodeMap.get(track.node), new TranslationTrack(track.interpolator));
321
+ } else if (track.type === 'scale') {
322
+ animation.addTrack(nodeMap.get(track.node), new ScaleTrack(track.interpolator));
323
+ } else if (track.type === 'rotation') {
324
+ animation.addTrack(nodeMap.get(track.node), new RotationTrack(track.interpolator));
325
+ } else {
326
+ throw new Error(`Could not load model: invalid animation track type: ${track.type}`);
327
+ }
328
+ }
329
+ for (const sk of animationData.skeletons){
330
+ const nodes = skeletonMeshMap.get(sk);
331
+ if (nodes) {
332
+ const skeleton = new Skeleton(sk.joints.map((val)=>nodeMap.get(val)), sk.inverseBindMatrices, sk.bindPoseMatrices);
333
+ skeleton.updateJointMatrices();
334
+ animation.addSkeleton(skeleton, nodes.mesh, nodes.bounding.map((val)=>this.getBoundingInfo(skeleton, val)));
335
+ }
336
+ }
337
+ animation.stop();
338
+ }
339
+ }
340
+ if (animationSet.numAnimations === 0) {
341
+ animationSet.dispose();
342
+ animationSet = null;
343
+ }
344
+ return {
345
+ group,
346
+ animationSet
347
+ };
348
+ }
349
+ /**
350
+ * Sets the loader for a given builtin-texture
351
+ * @param name - Name of the builtin texture
352
+ * @param loader - Loader for the builtin texture
353
+ */ static setBuiltinTextureLoader(name, loader) {
354
+ if (loader) {
355
+ this._builtinTextureLoaders[name] = loader;
356
+ } else {
357
+ delete this._builtinTextureLoaders[name];
358
+ }
359
+ }
360
+ /** @internal */ getBoundingInfo(skeleton, meshData) {
361
+ const indices = [
362
+ 0,
363
+ 0,
364
+ 0,
365
+ 0,
366
+ 0,
367
+ 0
368
+ ];
369
+ let minx = Number.MAX_VALUE;
370
+ let maxx = -Number.MAX_VALUE;
371
+ let miny = Number.MAX_VALUE;
372
+ let maxy = -Number.MAX_VALUE;
373
+ let minz = Number.MAX_VALUE;
374
+ let maxz = -Number.MAX_VALUE;
375
+ const v = meshData.rawPositions;
376
+ const vert = new Vector3();
377
+ const tmpV0 = new Vector3();
378
+ const tmpV1 = new Vector3();
379
+ const tmpV2 = new Vector3();
380
+ const tmpV3 = new Vector3();
381
+ const numVertices = Math.floor(v.length / 3);
382
+ for(let i = 0; i < numVertices; i++){
383
+ vert.setXYZ(v[i * 3], v[i * 3 + 1], v[i * 3 + 2]);
384
+ skeleton.jointMatrices[meshData.rawBlendIndices[i * 4 + 0]].transformPointAffine(vert, tmpV0).scaleBy(meshData.rawJointWeights[i * 4 + 0]);
385
+ skeleton.jointMatrices[meshData.rawBlendIndices[i * 4 + 1]].transformPointAffine(vert, tmpV1).scaleBy(meshData.rawJointWeights[i * 4 + 1]);
386
+ skeleton.jointMatrices[meshData.rawBlendIndices[i * 4 + 2]].transformPointAffine(vert, tmpV2).scaleBy(meshData.rawJointWeights[i * 4 + 2]);
387
+ skeleton.jointMatrices[meshData.rawBlendIndices[i * 4 + 3]].transformPointAffine(vert, tmpV3).scaleBy(meshData.rawJointWeights[i * 4 + 3]);
388
+ tmpV0.addBy(tmpV1).addBy(tmpV2).addBy(tmpV3);
389
+ if (tmpV0.x < minx) {
390
+ minx = tmpV0.x;
391
+ indices[0] = i;
392
+ }
393
+ if (tmpV0.x > maxx) {
394
+ maxx = tmpV0.x;
395
+ indices[1] = i;
396
+ }
397
+ if (tmpV0.y < miny) {
398
+ miny = tmpV0.y;
399
+ indices[2] = i;
400
+ }
401
+ if (tmpV0.y > maxy) {
402
+ maxy = tmpV0.y;
403
+ indices[3] = i;
404
+ }
405
+ if (tmpV0.z < minz) {
406
+ minz = tmpV0.z;
407
+ indices[4] = i;
408
+ }
409
+ if (tmpV0.z > maxz) {
410
+ maxz = tmpV0.z;
411
+ indices[5] = i;
412
+ }
413
+ }
414
+ const info = {
415
+ boundingVertexBlendIndices: new Float32Array(Array.from({
416
+ length: 6 * 4
417
+ }).map((val, index)=>meshData.rawBlendIndices[indices[index >> 2] * 4 + index % 4])),
418
+ boundingVertexJointWeights: new Float32Array(Array.from({
419
+ length: 6 * 4
420
+ }).map((val, index)=>meshData.rawJointWeights[indices[index >> 2] * 4 + index % 4])),
421
+ boundingVertices: Array.from({
422
+ length: 6
423
+ }).map((val, index)=>new Vector3(meshData.rawPositions[indices[index] * 3], meshData.rawPositions[indices[index] * 3 + 1], meshData.rawPositions[indices[index] * 3 + 2])),
424
+ boundingBox: new BoundingBox()
425
+ };
426
+ return info;
427
+ }
428
+ /** @internal */ setAssetNodeToSceneNode(scene, parent, model, assetNode, skeletonMeshMap, nodeMap) {
429
+ const node = new SceneNode(scene);
430
+ nodeMap.set(assetNode, node);
431
+ node.name = `${assetNode.name}`;
432
+ node.position.set(assetNode.position);
433
+ node.rotation.set(assetNode.rotation);
434
+ node.scale.set(assetNode.scaling);
435
+ if (assetNode.mesh) {
436
+ const meshData = assetNode.mesh;
437
+ const skeleton = assetNode.skeleton;
438
+ for (const subMesh of meshData.subMeshes){
439
+ const meshNode = new Mesh(scene);
440
+ meshNode.name = subMesh.name;
441
+ meshNode.clipMode = GraphNode.CLIP_INHERITED;
442
+ meshNode.showState = GraphNode.SHOW_INHERITED;
443
+ meshNode.pickMode = GraphNode.PICK_INHERITED;
444
+ meshNode.primitive = subMesh.primitive;
445
+ meshNode.material = subMesh.material;
446
+ // meshNode.drawBoundingBox = true;
447
+ meshNode.reparent(node);
448
+ if (skeleton) {
449
+ if (!skeletonMeshMap.has(skeleton)) {
450
+ skeletonMeshMap.set(skeleton, {
451
+ mesh: [
452
+ meshNode
453
+ ],
454
+ bounding: [
455
+ subMesh
456
+ ]
457
+ });
458
+ } else {
459
+ skeletonMeshMap.get(skeleton).mesh.push(meshNode);
460
+ skeletonMeshMap.get(skeleton).bounding.push(subMesh);
461
+ }
462
+ }
463
+ }
464
+ }
465
+ node.reparent(parent);
466
+ for (const child of assetNode.children){
467
+ this.setAssetNodeToSceneNode(scene, node, model, child, skeletonMeshMap, nodeMap);
468
+ }
469
+ }
470
+ getHash(type, url, options) {
471
+ return `${type}:${url}:${!options?.linearColorSpace}`;
472
+ }
473
+ }
474
+
475
+ export { AssetManager };
476
+ //# sourceMappingURL=assetmanager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetmanager.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}