ris-framework 0.2.0-dev.11 → 0.2.0-dev.13

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 (257) hide show
  1. package/CHANGELOG.md +21 -29
  2. package/README.md +99 -150
  3. package/dist/Framework.d.ts +26 -8
  4. package/dist/Framework.d.ts.map +1 -1
  5. package/dist/api/IFramework.d.ts +43 -0
  6. package/dist/api/IFramework.d.ts.map +1 -1
  7. package/dist/api/_export.d.ts +1 -1
  8. package/dist/api/_export.d.ts.map +1 -1
  9. package/dist/api/content/ContentManager.d.ts +5 -57
  10. package/dist/api/content/ContentManager.d.ts.map +1 -1
  11. package/dist/api/content/IContentManager.d.ts +24 -21
  12. package/dist/api/content/IContentManager.d.ts.map +1 -1
  13. package/dist/api/lights/LightsBuffer.d.ts +13 -6
  14. package/dist/api/lights/LightsBuffer.d.ts.map +1 -1
  15. package/dist/api/loaders/ObjGeometryMapper.d.ts +2 -2
  16. package/dist/api/loaders/ObjLoader.d.ts +61 -0
  17. package/dist/api/loaders/ObjLoader.d.ts.map +1 -0
  18. package/dist/api/loaders/_export.d.ts +1 -0
  19. package/dist/api/loaders/_export.d.ts.map +1 -1
  20. package/dist/api/loaders/obj/{ObjLoader.d.ts → ObjParser.d.ts} +20 -5
  21. package/dist/api/loaders/obj/ObjParser.d.ts.map +1 -0
  22. package/dist/api/loaders/obj/ObjTypes.d.ts +17 -1
  23. package/dist/api/loaders/obj/ObjTypes.d.ts.map +1 -1
  24. package/dist/api/loaders/obj/index.d.ts +1 -1
  25. package/dist/api/material/ForwardBlinnPhongMaterial.d.ts +22 -11
  26. package/dist/api/material/ForwardBlinnPhongMaterial.d.ts.map +1 -1
  27. package/dist/api/material/ICameraMaterial.d.ts +18 -0
  28. package/dist/api/material/ICameraMaterial.d.ts.map +1 -0
  29. package/dist/api/material/ILightsMaterial.d.ts +26 -0
  30. package/dist/api/material/ILightsMaterial.d.ts.map +1 -0
  31. package/dist/api/material/IMaterial.d.ts +2 -8
  32. package/dist/api/material/IMaterial.d.ts.map +1 -1
  33. package/dist/api/material/InspectTextureMipsMaterial.d.ts +2 -2
  34. package/dist/api/material/InspectTextureMipsMaterial.d.ts.map +1 -1
  35. package/dist/api/material/SpriteMaterial.d.ts +2 -2
  36. package/dist/api/material/SpriteMaterial.d.ts.map +1 -1
  37. package/dist/api/material/UnlitMaterial.d.ts +4 -3
  38. package/dist/api/material/UnlitMaterial.d.ts.map +1 -1
  39. package/dist/api/material/_export.d.ts +2 -0
  40. package/dist/api/material/_export.d.ts.map +1 -1
  41. package/dist/api/meshes/IMesh.d.ts +29 -34
  42. package/dist/api/meshes/IMesh.d.ts.map +1 -1
  43. package/dist/api/meshes/IMeshFactory.d.ts +13 -8
  44. package/dist/api/meshes/IMeshFactory.d.ts.map +1 -1
  45. package/dist/api/meshes/IRenderableMesh.d.ts +47 -0
  46. package/dist/api/meshes/IRenderableMesh.d.ts.map +1 -0
  47. package/dist/api/meshes/Mesh.d.ts +11 -57
  48. package/dist/api/meshes/Mesh.d.ts.map +1 -1
  49. package/dist/api/meshes/MeshFactory.d.ts +6 -3
  50. package/dist/api/meshes/MeshFactory.d.ts.map +1 -1
  51. package/dist/api/meshes/QuadMesh.d.ts +3 -5
  52. package/dist/api/meshes/QuadMesh.d.ts.map +1 -1
  53. package/dist/api/meshes/RenderableMesh.d.ts +95 -0
  54. package/dist/api/meshes/RenderableMesh.d.ts.map +1 -0
  55. package/dist/api/meshes/_export.d.ts +2 -1
  56. package/dist/api/meshes/_export.d.ts.map +1 -1
  57. package/dist/api/rendering/IGraphicsDeviceFeatures.d.ts +8 -2
  58. package/dist/api/rendering/IGraphicsDeviceFeatures.d.ts.map +1 -1
  59. package/dist/api/rendering/IRenderer.d.ts +28 -1
  60. package/dist/api/rendering/IRenderer.d.ts.map +1 -1
  61. package/dist/api/rendering/enums.d.ts +7 -0
  62. package/dist/api/rendering/enums.d.ts.map +1 -1
  63. package/dist/api/rendering/renderer-interface.d.ts +1 -31
  64. package/dist/api/rendering/renderer-interface.d.ts.map +1 -1
  65. package/dist/api/rendering/renderpass/RenderPassDescriptor.d.ts +2 -6
  66. package/dist/api/rendering/renderpass/RenderPassDescriptor.d.ts.map +1 -1
  67. package/dist/api/rendering/swapchain/ISwapChain.d.ts +1 -3
  68. package/dist/api/rendering/swapchain/ISwapChain.d.ts.map +1 -1
  69. package/dist/api/rendering/texture/TextureFormat.d.ts +88 -14
  70. package/dist/api/rendering/texture/TextureFormat.d.ts.map +1 -1
  71. package/dist/api/rendering/texture/TextureUtilities.d.ts +23 -0
  72. package/dist/api/rendering/texture/TextureUtilities.d.ts.map +1 -1
  73. package/dist/api/scene/Scene.d.ts +30 -21
  74. package/dist/api/scene/Scene.d.ts.map +1 -1
  75. package/dist/api/scene/SceneMesh.d.ts +27 -0
  76. package/dist/api/scene/SceneMesh.d.ts.map +1 -0
  77. package/dist/api/utilities/AlignUtilities.d.ts.map +1 -1
  78. package/dist/api/window/WindowManager.d.ts.map +1 -1
  79. package/dist/core/rendering/ARenderer.d.ts +5 -5
  80. package/dist/core/rendering/ARenderer.d.ts.map +1 -1
  81. package/dist/index.d.ts +0 -1
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +4006 -1355
  84. package/dist/webgl/WebGLGraphicsDeviceFeatures.d.ts +4 -0
  85. package/dist/webgl/WebGLGraphicsDeviceFeatures.d.ts.map +1 -1
  86. package/dist/webgl/WebGlRenderer.d.ts +1 -3
  87. package/dist/webgl/WebGlRenderer.d.ts.map +1 -1
  88. package/dist/webgl/lights/WebGlLightsBuffer.d.ts +8 -4
  89. package/dist/webgl/lights/WebGlLightsBuffer.d.ts.map +1 -1
  90. package/dist/webgl/render-pipelines/WebGlMainRenderTargetRenderPipeline.d.ts +2 -0
  91. package/dist/webgl/render-pipelines/WebGlMainRenderTargetRenderPipeline.d.ts.map +1 -1
  92. package/dist/webgl/swap-chain/WebGlSwapChain.d.ts +3 -2
  93. package/dist/webgl/swap-chain/WebGlSwapChain.d.ts.map +1 -1
  94. package/dist/webgl/texture/WebGlTextureFactory.d.ts +7 -0
  95. package/dist/webgl/texture/WebGlTextureFactory.d.ts.map +1 -1
  96. package/dist/webgl/utilities/WebGlConstants.d.ts +91 -0
  97. package/dist/webgl/utilities/WebGlConstants.d.ts.map +1 -0
  98. package/dist/webgl/utilities/WebGlConverter.d.ts +0 -7
  99. package/dist/webgl/utilities/WebGlConverter.d.ts.map +1 -1
  100. package/dist/webgl/utilities/WebGlErrorUtilities.d.ts +10 -0
  101. package/dist/webgl/utilities/WebGlErrorUtilities.d.ts.map +1 -0
  102. package/dist/webgl/utilities/WebGlTextureUtilities.d.ts.map +1 -1
  103. package/dist/webgl/utilities/WebGlUtilities.d.ts +3 -0
  104. package/dist/webgl/utilities/WebGlUtilities.d.ts.map +1 -1
  105. package/dist/webgpu/WebGpuGpuInfo.d.ts +28 -0
  106. package/dist/webgpu/WebGpuGpuInfo.d.ts.map +1 -0
  107. package/dist/webgpu/WebGpuGraphicsDevice.d.ts +80 -0
  108. package/dist/webgpu/WebGpuGraphicsDevice.d.ts.map +1 -0
  109. package/dist/webgpu/WebGpuGraphicsDeviceFeatures.d.ts +26 -0
  110. package/dist/webgpu/WebGpuGraphicsDeviceFeatures.d.ts.map +1 -0
  111. package/dist/webgpu/WebGpuRenderer.d.ts +26 -0
  112. package/dist/webgpu/WebGpuRenderer.d.ts.map +1 -0
  113. package/dist/webgpu/WebGpuTypes.d.ts +355 -0
  114. package/dist/webgpu/WebGpuTypes.d.ts.map +1 -0
  115. package/dist/webgpu/blending/WebGpuBlendState.d.ts +30 -0
  116. package/dist/webgpu/blending/WebGpuBlendState.d.ts.map +1 -0
  117. package/dist/webgpu/buffers/WebGpuBuffersFactory.d.ts +20 -0
  118. package/dist/webgpu/buffers/WebGpuBuffersFactory.d.ts.map +1 -0
  119. package/dist/webgpu/buffers/WebGpuIndexBuffer.d.ts +46 -0
  120. package/dist/webgpu/buffers/WebGpuIndexBuffer.d.ts.map +1 -0
  121. package/dist/webgpu/buffers/WebGpuUniformBuffer.d.ts +43 -0
  122. package/dist/webgpu/buffers/WebGpuUniformBuffer.d.ts.map +1 -0
  123. package/dist/webgpu/buffers/WebGpuVertexBuffer.d.ts +49 -0
  124. package/dist/webgpu/buffers/WebGpuVertexBuffer.d.ts.map +1 -0
  125. package/dist/webgpu/primitive/WebGpuPrimitiveState.d.ts +32 -0
  126. package/dist/webgpu/primitive/WebGpuPrimitiveState.d.ts.map +1 -0
  127. package/dist/webgpu/render-pass/WebGpuRenderPass.d.ts +28 -0
  128. package/dist/webgpu/render-pass/WebGpuRenderPass.d.ts.map +1 -0
  129. package/dist/webgpu/render-pipelines/AWebGpuRenderPipeline.d.ts +50 -0
  130. package/dist/webgpu/render-pipelines/AWebGpuRenderPipeline.d.ts.map +1 -0
  131. package/dist/webgpu/render-pipelines/WebGpuMainRenderTargetRenderPipeline.d.ts +34 -0
  132. package/dist/webgpu/render-pipelines/WebGpuMainRenderTargetRenderPipeline.d.ts.map +1 -0
  133. package/dist/webgpu/render-pipelines/WebGpuRenderPipelineFactory.d.ts +26 -0
  134. package/dist/webgpu/render-pipelines/WebGpuRenderPipelineFactory.d.ts.map +1 -0
  135. package/dist/webgpu/render-pipelines/material/AWebGpuMeshRenderPipeline.d.ts +72 -0
  136. package/dist/webgpu/render-pipelines/material/AWebGpuMeshRenderPipeline.d.ts.map +1 -0
  137. package/dist/webgpu/render-pipelines/material/WebGpuUnlitRenderPipeline.d.ts +40 -0
  138. package/dist/webgpu/render-pipelines/material/WebGpuUnlitRenderPipeline.d.ts.map +1 -0
  139. package/dist/webgpu/sampler/WebGpuSampler.d.ts +39 -0
  140. package/dist/webgpu/sampler/WebGpuSampler.d.ts.map +1 -0
  141. package/dist/webgpu/shader/WebGpuShaderModule.d.ts +29 -0
  142. package/dist/webgpu/shader/WebGpuShaderModule.d.ts.map +1 -0
  143. package/dist/webgpu/shader/WebGpuShaderModuleLoader.d.ts +21 -0
  144. package/dist/webgpu/shader/WebGpuShaderModuleLoader.d.ts.map +1 -0
  145. package/dist/webgpu/shader/WgslShaderContent.d.ts +9 -0
  146. package/dist/webgpu/shader/WgslShaderContent.d.ts.map +1 -0
  147. package/dist/webgpu/swap-chain/WebGpuSwapChain.d.ts +41 -0
  148. package/dist/webgpu/swap-chain/WebGpuSwapChain.d.ts.map +1 -0
  149. package/dist/webgpu/texture/WebGpuTexture2D.d.ts +47 -0
  150. package/dist/webgpu/texture/WebGpuTexture2D.d.ts.map +1 -0
  151. package/dist/webgpu/texture/WebGpuTextureFactory.d.ts +21 -0
  152. package/dist/webgpu/texture/WebGpuTextureFactory.d.ts.map +1 -0
  153. package/dist/webgpu/texture/WebGpuTextureView.d.ts +25 -0
  154. package/dist/webgpu/texture/WebGpuTextureView.d.ts.map +1 -0
  155. package/dist/webgpu/utilities/WebGpuConverter.d.ts +45 -0
  156. package/dist/webgpu/utilities/WebGpuConverter.d.ts.map +1 -0
  157. package/package.json +2 -2
  158. package/shaders/glsl/main_render_target_flip_y_fs.glsl +35 -1
  159. package/shaders/wgsl/forward_blinn_phong_material.wgsl +150 -0
  160. package/shaders/wgsl/inspect_texture_mips.wgsl +51 -0
  161. package/shaders/wgsl/main_frame_buffer.wgsl +35 -0
  162. package/shaders/wgsl/main_render_target_flip_y.wgsl +35 -0
  163. package/shaders/wgsl/sprite.wgsl +40 -0
  164. package/shaders/wgsl/unlit_material.wgsl +49 -0
  165. package/src/Framework.ts +121 -37
  166. package/src/api/IFramework.ts +55 -0
  167. package/src/api/_export.ts +1 -1
  168. package/src/api/content/ContentManager.ts +46 -180
  169. package/src/api/content/IContentManager.ts +25 -21
  170. package/src/api/lights/LightsBuffer.ts +13 -6
  171. package/src/api/loaders/ObjGeometryMapper.ts +2 -2
  172. package/src/api/loaders/ObjLoader.ts +126 -0
  173. package/src/api/loaders/_export.ts +1 -0
  174. package/src/api/loaders/obj/{ObjLoader.ts → ObjParser.ts} +35 -4
  175. package/src/api/loaders/obj/ObjTypes.ts +19 -1
  176. package/src/api/loaders/obj/index.ts +1 -1
  177. package/src/api/material/ForwardBlinnPhongMaterial.ts +48 -22
  178. package/src/api/material/ICameraMaterial.ts +22 -0
  179. package/src/api/material/ILightsMaterial.ts +32 -0
  180. package/src/api/material/IMaterial.ts +2 -9
  181. package/src/api/material/InspectTextureMipsMaterial.ts +2 -2
  182. package/src/api/material/SpriteMaterial.ts +2 -2
  183. package/src/api/material/UnlitMaterial.ts +4 -3
  184. package/src/api/material/_export.ts +2 -0
  185. package/src/api/meshes/IMesh.ts +32 -37
  186. package/src/api/meshes/IMeshFactory.ts +14 -8
  187. package/src/api/meshes/IRenderableMesh.ts +58 -0
  188. package/src/api/meshes/Mesh.ts +17 -132
  189. package/src/api/meshes/MeshFactory.ts +14 -5
  190. package/src/api/meshes/QuadMesh.ts +4 -6
  191. package/src/api/meshes/RenderableMesh.ts +207 -0
  192. package/src/api/meshes/_export.ts +6 -5
  193. package/src/api/rendering/IGraphicsDeviceFeatures.ts +28 -21
  194. package/src/api/rendering/IRenderer.ts +34 -1
  195. package/src/api/rendering/enums.ts +10 -0
  196. package/src/api/rendering/renderer-interface.ts +1 -36
  197. package/src/api/rendering/renderpass/RenderPassDescriptor.ts +10 -14
  198. package/src/api/rendering/swapchain/ISwapChain.ts +1 -3
  199. package/src/api/rendering/texture/TextureFormat.ts +128 -14
  200. package/src/api/rendering/texture/TextureUtilities.ts +225 -10
  201. package/src/api/scene/Scene.ts +102 -69
  202. package/src/api/scene/SceneMesh.ts +61 -0
  203. package/src/api/sprites/SpriteBatchMesh.ts +1 -1
  204. package/src/api/utilities/AlignUtilities.ts +2 -1
  205. package/src/api/window/WindowManager.ts +1 -1
  206. package/src/core/rendering/ARenderer.ts +24 -15
  207. package/src/index.ts +0 -1
  208. package/src/main.ts +2 -3
  209. package/src/webgl/WebGLGraphicsDeviceFeatures.ts +12 -2
  210. package/src/webgl/WebGlGpuInfo.ts +1 -1
  211. package/src/webgl/WebGlRenderer.ts +2 -5
  212. package/src/webgl/lights/WebGlLightsBuffer.ts +14 -4
  213. package/src/webgl/render-pipelines/WebGlMainRenderTargetRenderPipeline.ts +18 -1
  214. package/src/webgl/swap-chain/WebGlSwapChain.ts +7 -6
  215. package/src/webgl/texture/WebGlTextureFactory.ts +49 -7
  216. package/src/webgl/utilities/WebGlConstants.ts +136 -0
  217. package/src/webgl/utilities/WebGlConverter.ts +91 -22
  218. package/src/webgl/utilities/WebGlErrorUtilities.ts +15 -0
  219. package/src/webgl/utilities/WebGlTextureUtilities.ts +5 -2
  220. package/src/webgl/utilities/WebGlUtilities.ts +4 -0
  221. package/src/webgpu/WebGpuGpuInfo.ts +61 -0
  222. package/src/webgpu/WebGpuGraphicsDevice.ts +199 -0
  223. package/src/webgpu/WebGpuGraphicsDeviceFeatures.ts +41 -0
  224. package/src/webgpu/WebGpuRenderer.ts +49 -0
  225. package/src/webgpu/WebGpuTypes.ts +288 -0
  226. package/src/webgpu/blending/WebGpuBlendState.ts +53 -0
  227. package/src/webgpu/buffers/WebGpuBuffersFactory.ts +46 -0
  228. package/src/webgpu/buffers/WebGpuIndexBuffer.ts +118 -0
  229. package/src/webgpu/buffers/WebGpuUniformBuffer.ts +102 -0
  230. package/src/webgpu/buffers/WebGpuVertexBuffer.ts +119 -0
  231. package/src/webgpu/primitive/WebGpuPrimitiveState.ts +52 -0
  232. package/src/webgpu/render-pass/WebGpuRenderPass.ts +131 -0
  233. package/src/webgpu/render-pipelines/AWebGpuRenderPipeline.ts +123 -0
  234. package/src/webgpu/render-pipelines/WebGpuMainRenderTargetRenderPipeline.ts +119 -0
  235. package/src/webgpu/render-pipelines/WebGpuRenderPipelineFactory.ts +66 -0
  236. package/src/webgpu/render-pipelines/material/AWebGpuMeshRenderPipeline.ts +249 -0
  237. package/src/webgpu/render-pipelines/material/WebGpuUnlitRenderPipeline.ts +101 -0
  238. package/src/webgpu/sampler/WebGpuSampler.ts +84 -0
  239. package/src/webgpu/shader/WebGpuShaderModule.ts +65 -0
  240. package/src/webgpu/shader/WebGpuShaderModuleLoader.ts +38 -0
  241. package/src/webgpu/shader/WgslShaderContent.ts +20 -0
  242. package/src/webgpu/swap-chain/WebGpuSwapChain.ts +93 -0
  243. package/src/webgpu/texture/WebGpuTexture2D.ts +197 -0
  244. package/src/webgpu/texture/WebGpuTextureFactory.ts +118 -0
  245. package/src/webgpu/texture/WebGpuTextureView.ts +43 -0
  246. package/src/webgpu/utilities/WebGpuConverter.ts +299 -0
  247. package/src/wgsl-raw.d.ts +4 -0
  248. package/dist/api/FrameworkConfiguration.d.ts +0 -23
  249. package/dist/api/FrameworkConfiguration.d.ts.map +0 -1
  250. package/dist/api/IFrameworkConfiguration.d.ts +0 -25
  251. package/dist/api/IFrameworkConfiguration.d.ts.map +0 -1
  252. package/dist/api/loaders/obj/ObjLoader.d.ts.map +0 -1
  253. package/dist/api/meshes/SubMesh.d.ts +0 -47
  254. package/dist/api/meshes/SubMesh.d.ts.map +0 -1
  255. package/src/api/FrameworkConfiguration.ts +0 -29
  256. package/src/api/IFrameworkConfiguration.ts +0 -30
  257. package/src/api/meshes/SubMesh.ts +0 -71
@@ -7,6 +7,7 @@ import type { IBufferFactory } from "./rendering/buffers/IBufferFactory.ts";
7
7
  import type { IGeometryBuilder } from "./geometry/IGeometryBuilder.ts";
8
8
  import type { ICameraFactory } from "./camera/ICameraFactory.ts";
9
9
  import type { ITextureFactory } from "./rendering/texture/ITextureFactory.ts";
10
+ import type { ObjLoader } from "./loaders/ObjLoader.ts";
10
11
  import type { IContentManager } from "./content/IContentManager.ts";
11
12
  import type { IImageLoader } from "./loaders/IImageLoader.ts";
12
13
  import type { IMeshFactory } from "./meshes/IMeshFactory.ts";
@@ -19,6 +20,49 @@ import {GameTime} from "./time/GameTime.ts";
19
20
  import type { IImageProcessor } from "./image/IImageProcessor.ts";
20
21
  import type { IKtx2Factory } from "ris-ktx2";
21
22
  import type { IDisposable } from "./core/IDisposable.ts";
23
+ import type {vec2} from "gl-matrix";
24
+ import type {TextureSamplerFilteringPreset} from "../core/rendering/enums.ts";
25
+ import type {PowerPreferenceType} from "./rendering/PowerPreference.ts";
26
+ import type {TextureColorSpace} from "./rendering/enums.ts";
27
+
28
+
29
+ /**
30
+ * The configuration for the framework.
31
+ * @public
32
+ **/
33
+ export class IFrameworkConfiguration {
34
+
35
+ /** If true, creates and makes the KTX2 factory available. */
36
+ useKtx2?: boolean;
37
+
38
+ /** The size of back buffer. By default, if not specified (800, 600). */
39
+ backBufferSize?: vec2;
40
+
41
+ /** The texture filtering to configure */
42
+ textureFiltering?: TextureSamplerFilteringPreset;
43
+
44
+ /** The texture color space to use by default. By default, it is {@link TextureColorSpace.SRGB}. */
45
+ textureColorSpace?: TextureColorSpace;
46
+
47
+ /**
48
+ * The HTMLCanvasElement to use for rendering.
49
+ * If null, a new canvas will be created and added to the document body.
50
+ */
51
+ canvas?: HTMLCanvasElement;
52
+
53
+ /** Should back buffer use alpha. */
54
+ alpha?: boolean;
55
+
56
+ /** The preference when it comes to selecting GPU device. Only makes sense to set on multi-GPU devices. */
57
+ powerPreference ?: PowerPreferenceType;
58
+
59
+ /**
60
+ * The rendering backend. Defaults to WebGL.
61
+ * WebGPU requires `Framework.initializeAsync()`; when `navigator.gpu` is missing or no device is available,
62
+ * the framework falls back to WebGL with a warning.
63
+ */
64
+ renderingBackend?: RenderingBackend;
65
+ }
22
66
 
23
67
  /** The framework interface. */
24
68
  export interface IFramework extends IDisposable {
@@ -87,6 +131,11 @@ export interface IFramework extends IDisposable {
87
131
  */
88
132
  readonly meshFactory: IMeshFactory;
89
133
 
134
+ /**
135
+ * The OBJ loader: `objLoader.loadAsync(path, blinnPhongDescriptor | subMesh => material)`.
136
+ */
137
+ readonly objLoader: ObjLoader;
138
+
90
139
  /**
91
140
  * The material factory.
92
141
  */
@@ -152,4 +201,10 @@ export interface IFramework extends IDisposable {
152
201
  /** Initializes the framework. */
153
202
  initialize(): void;
154
203
 
204
+ /**
205
+ * Initializes the framework asynchronously and starts the event loop.
206
+ * Required for the WebGPU backend; for WebGL it behaves like {@link initialize}.
207
+ */
208
+ initializeAsync(): Promise<void>;
209
+
155
210
  }
@@ -1,5 +1,4 @@
1
1
  export * from "./IFramework.ts";
2
- export * from "./IFrameworkConfiguration.ts";
3
2
  export * from "./rendering/texture/_export-texture.ts";
4
3
  export * from "./rendering/buffers/_export-buffers.ts";
5
4
  export * from "./data/_export.ts";
@@ -24,5 +23,6 @@ export * from "./meshes/_export.ts";
24
23
  export * from "./material/_export.ts";
25
24
  export * from "./lights/_export.ts";
26
25
  export * from "./scene/Scene.ts";
26
+ export * from "./scene/SceneMesh.ts";
27
27
  export * from "./input/_export.ts";
28
28
  export * from "./image/_export.ts";
@@ -9,23 +9,19 @@ import {
9
9
  ContentConfig,
10
10
  TextureUsage,
11
11
  type IMesh,
12
- ObjLoader,
12
+ type IRenderableMesh,
13
+ type GeometryFormat,
13
14
  Color,
14
15
  type ICamera,
15
- type IMaterial,
16
- type ObjMaterialDefinition,
17
- type SubMeshDescriptor,
18
- type ObjLoadResult,
19
- type ObjGeometryDefinition,
20
- type IGeometry,
21
- type LightsBuffer,
22
- type Scene,
23
16
  type IDisposable,
24
17
  } from "../index.ts";
25
18
  import {ObjGeometryMapper} from "../loaders/ObjGeometryMapper.ts";
19
+ import {ObjLoader} from "../loaders/ObjLoader.ts";
26
20
  import {Ktx2Factory} from "ris-ktx2";
27
21
  import type {IKtx2Texture} from "ris-ktx2";
28
22
 
23
+ const KTX2_EXTENSION = ".ktx2";
24
+
29
25
  /**
30
26
  * The content manager.
31
27
  * The content manager is responsible for managing the content modules and loading the content with the given asset file path or identifier.
@@ -33,8 +29,7 @@ import type {IKtx2Texture} from "ris-ktx2";
33
29
  export class ContentManager implements IContentManager {
34
30
 
35
31
  private readonly _ktx2Factory = new Ktx2Factory();
36
- private readonly _ktx2TextureCache: {[key: string]: IKtx2Texture} = {};
37
- private readonly _objLoader = new ObjLoader();
32
+ private readonly _ktx2TextureCache: { [key: string]: IKtx2Texture } = {};
38
33
 
39
34
  /**
40
35
  * The constructor.
@@ -47,13 +42,16 @@ export class ContentManager implements IContentManager {
47
42
  /** @inheritDoc */
48
43
  public async loadKtx2Async(path: string, contentConfig?: ContentConfig): Promise<IKtx2Texture> {
49
44
 
45
+ // it's fine to call it, handled internally if called multiple times.
46
+ await this._ktx2Factory.initializeAsync();
47
+
50
48
  let ktx2Texture = this._ktx2TextureCache[path];
51
- if(ktx2Texture) {
49
+ if (ktx2Texture) {
52
50
  return ktx2Texture;
53
51
  }
54
52
 
55
53
  ktx2Texture = await this._ktx2Factory.loadAsync(path);
56
- if(contentConfig?.keepDataCached == true){
54
+ if (contentConfig?.keepDataCached == true) {
57
55
  this._ktx2TextureCache[path] = ktx2Texture;
58
56
  }
59
57
  return ktx2Texture;
@@ -66,45 +64,53 @@ export class ContentManager implements IContentManager {
66
64
  public dispose(): void {
67
65
  (this.shaderModuleLoader as Partial<IDisposable>).dispose?.();
68
66
  for (const key of Object.keys(this._ktx2TextureCache)) {
67
+ this._ktx2TextureCache[key].delete();
69
68
  delete this._ktx2TextureCache[key];
70
69
  }
71
70
  }
72
71
 
73
72
  /** @inheritDoc */
74
- public loadShaderModule(shaderModuleId: string, keyValueDictionary?: { [id:string]: number}): IShaderModule {
75
- return this.shaderModuleLoader.load(shaderModuleId, keyValueDictionary);
73
+ public loadShaderModule(shaderModuleId: string, keyValueDictionary?: { [id: string]: number }): IShaderModule {
74
+ return this.shaderModuleLoader.load(shaderModuleId, keyValueDictionary);
76
75
  }
77
76
 
78
77
  /** @inheritDoc */
79
78
  public async loadTexture2DAsync(path: string,
80
79
  textureDescriptor?: TextureDescriptor,
81
80
  contentConfig?: ContentConfig,
82
- ): Promise<ITexture2D> {
81
+ ): Promise<ITexture2D> {
83
82
 
84
- if(path.endsWith(".ktx2")) {
85
- const ktx2Texture = await this.loadKtx2Async(path, contentConfig);
83
+ // TODO: check texture cache
84
+ if (path.endsWith(KTX2_EXTENSION)) {
85
+
86
+ const ktx2Texture = await this.loadKtx2Async(path);
86
87
  textureDescriptor = textureDescriptor ?? new TextureDescriptor();
87
- return this._framework.textureFactory.createFromKtx2(ktx2Texture, textureDescriptor);
88
+ const tex = this._framework.textureFactory.createFromKtx2(ktx2Texture, textureDescriptor);
89
+ if (contentConfig?.keepDataCached !== true) {
90
+ ktx2Texture.delete();
91
+ }
92
+ return tex;
88
93
  }
89
94
 
90
- let format = this._framework.renderer.preferredTextureFormat;
95
+ let format = this._framework.renderer.preferredTextureFormat;
91
96
 
92
- if(textureDescriptor && textureDescriptor.textureFormat != TextureFormat.UNDEFINED) {
97
+ if (textureDescriptor && textureDescriptor.textureFormat != TextureFormat.UNDEFINED) {
93
98
  format = textureDescriptor.textureFormat;
94
99
  }
95
100
 
96
- // TODO: pass texture descriptor
97
101
  const imageLoader = this._framework.imageLoader;
98
102
  const data = await imageLoader.loadAsync(path, contentConfig?.keepDataCached);
103
+
104
+ // TODO: pass texture descriptor
99
105
  return this._framework.textureFactory.create(
100
106
  data.baseWidth, data.baseHeight,
101
107
  data.getData(0) as Uint8Array,
102
108
  data.channels,
103
- undefined,
109
+ path,
104
110
  TextureUsage.TEXTURE_BINDING | TextureUsage.COPY_SRC,
105
111
  format,
106
112
  textureDescriptor?.generateMipmaps
107
- );
113
+ );
108
114
  }
109
115
 
110
116
  /** @inheritDoc */
@@ -114,170 +120,30 @@ export class ContentManager implements IContentManager {
114
120
  }
115
121
 
116
122
  /** @inheritDoc */
117
- public async loadMeshAsync(path: string, scene: Scene): Promise<IMesh> {
118
-
119
- const objResult = await this._loadObj(path);
120
- const geometry = this._createGeometry(objResult.geometry);
121
- const subMeshes = this._createSubMeshDescriptors(objResult,
122
- definition => this._createUnlitMaterial(definition, scene.camera));
123
-
124
- return this._framework.meshFactory.createWithSubMeshes(scene, geometry, subMeshes);
123
+ public async loadMeshAsync(path: string, geometryFormat: GeometryFormat): Promise<IMesh> {
124
+ const model = await ObjLoader.parseAsync(path, {ignoreMaterials: true});
125
+ const geometry = this._framework.geometryBuilder.create(ObjGeometryMapper.toDescriptor(model.geometry));
126
+ return this._framework.meshFactory.createMesh(geometry, geometryFormat);
125
127
  }
126
128
 
127
129
  /** @inheritDoc */
128
- public async loadBlinnPhongMeshAsync(path: string, scene: Scene): Promise<IMesh> {
129
- // Checked before loading, so a missing camera fails fast.
130
- const camera = scene.camera;
131
- if (!camera) {
132
- throw new Error(`loadBlinnPhongMeshAsync("${path}"): the scene has no camera. Set scene.camera (or pass the scene to createPerspectiveCamera) before loading a Blinn-Phong mesh.`);
133
- }
134
- if (!camera.positionBuffer || !camera.projectionViewBuffer) {
135
- const what = [camera.projectionViewBuffer ? undefined : "projectionViewBuffer", camera.positionBuffer ? undefined : "positionBuffer"]
136
- .filter(x => x !== undefined).join(" and ");
137
- throw new Error(`loadBlinnPhongMeshAsync("${path}"): the scene camera has no ${what}. Call camera.initialize() first (the camera factory does).`);
138
- }
139
- const objResult = await this._loadObj(path);
140
- const geometry = this._createGeometry(objResult.geometry);
141
- const subMeshes = this._createSubMeshDescriptors(objResult,
142
- definition => this._createBlinnPhongMaterial(definition, camera, scene.__forwardLightsBuffer));
143
-
144
- return this._framework.meshFactory.createWithSubMeshes(scene, geometry, subMeshes);
145
- }
146
-
147
- /**
148
- * Loads the OBJ file and its .mtl material libraries.
149
- * @param path The path or url to the .obj file.
150
- * @returns The plain OBJ data.
151
- */
152
- private _loadObj(path: string): Promise<ObjLoadResult> {
153
- return this._objLoader.loadAsync(path);
154
- }
155
-
156
- /**
157
- * Creates framework geometry from the OBJ geometry.
158
- * Vertex colours stay white, because each submesh's material carries the colour.
159
- * @param definition The OBJ geometry definition.
160
- * @returns The geometry.
161
- */
162
- private _createGeometry(definition: ObjGeometryDefinition): IGeometry {
163
- const descriptor = ObjGeometryMapper.toDescriptor(definition);
164
- return this._framework.geometryBuilder.create(descriptor);
165
- }
166
-
167
-
168
- /**
169
- * Creates one submesh descriptor per material range.
170
- * Ranges that use the same material name share one material instance.
171
- * @param objResult The loaded OBJ data.
172
- * @param createMaterial Creates the material for a definition (undefined without `usemtl` or .mtl entry).
173
- * @returns The submesh descriptors, in file order.
174
- */
175
- private _createSubMeshDescriptors(
176
- objResult: ObjLoadResult,
177
- createMaterial: (definition: ObjMaterialDefinition | undefined) => IMaterial): SubMeshDescriptor[] {
178
-
179
- const definitionsByName = this._indexMaterialDefinitions(objResult.materials);
180
- const materialsByName = new Map<string | undefined, IMaterial>();
181
- const subMeshes: SubMeshDescriptor[] = [];
182
-
183
- for (const range of objResult.geometry.materialRanges) {
184
- let material = materialsByName.get(range.materialName);
185
- if (material === undefined) {
186
- const definition = this._findMaterialDefinition(definitionsByName, range.materialName);
187
- material = createMaterial(definition);
188
- materialsByName.set(range.materialName, material);
189
- }
190
-
191
- subMeshes.push({
192
- material: material,
193
- indexStart: range.indexStart,
194
- indexCount: range.indexCount,
195
- });
196
- }
197
-
198
- return subMeshes;
199
- }
200
-
201
- /**
202
- * Indexes material definitions by name.
203
- * @param definitions The material definitions from the .mtl files.
204
- * @returns A map from material name to definition.
205
- */
206
- private _indexMaterialDefinitions(definitions: ObjMaterialDefinition[]): Map<string, ObjMaterialDefinition> {
207
- const definitionsByName = new Map<string, ObjMaterialDefinition>();
208
- for (const definition of definitions) {
209
- definitionsByName.set(definition.name, definition);
210
- }
211
- return definitionsByName;
212
- }
213
-
214
- /**
215
- * Finds the definition for a `usemtl` name.
216
- * @param definitionsByName The definitions by name.
217
- * @param materialName The material name, or undefined for faces without `usemtl`.
218
- * @returns The definition, or undefined when there is none.
219
- */
220
- private _findMaterialDefinition(
221
- definitionsByName: Map<string, ObjMaterialDefinition>,
222
- materialName: string | undefined): ObjMaterialDefinition | undefined {
223
- if (materialName === undefined) {
224
- return undefined;
225
- }
226
- return definitionsByName.get(materialName);
227
- }
228
-
229
- /**
230
- * Creates the default unlit material for an OBJ material definition.
231
- * The diffuse colour is the definition's `Kd` with `d` as alpha; white when there is no definition.
232
- * @param definition The material definition, or undefined.
233
- * @param camera The scene's current camera, or undefined; the scene assigns it on update.
234
- * @returns The unlit material.
235
- */
236
- private _createUnlitMaterial(definition: ObjMaterialDefinition | undefined, camera: ICamera | undefined): IMaterial {
237
- const material = this._framework.materialFactory.createUnlitMaterial({
238
- camera: camera,
130
+ public loadUnlitMeshAsync(path: string, camera?: ICamera): Promise<IRenderableMesh> {
131
+ return this._framework.objLoader.loadAsync(path, subMesh => {
132
+ const material = this._framework.materialFactory.createUnlitMaterial({camera});
133
+ const diffuse = subMesh.material?.diffuseColor ?? [1, 1, 1];
134
+ material.diffuseColor = new Color(diffuse[0], diffuse[1], diffuse[2], subMesh.material?.opacity ?? 1);
135
+ return material;
239
136
  });
240
-
241
- const diffuse = definition?.diffuseColor ?? [1, 1, 1];
242
- const opacity = definition?.opacity ?? 1;
243
- material.diffuseColor = new Color(diffuse[0], diffuse[1], diffuse[2], opacity);
244
- return material;
245
137
  }
246
138
 
247
- /**
248
- * Creates a Blinn-Phong material for an OBJ material definition.
249
- * `Kd` (with `d` as alpha) becomes the diffuse colour, white when missing.
250
- * `Ka` becomes the ambient colour; when missing the diffuse colour is used, so ambient light tints by the surface colour.
251
- * `Ks` and `Ns` become specular colour and shininess; when missing the material defaults stay (0.5 grey, 32).
252
- * @param definition The material definition, or undefined.
253
- * @param camera The scene's camera; its projection view and position buffers are bound.
254
- * @param lightsBuffer The optional lights buffer; the shader is compiled for its light counts.
255
- * @returns The Blinn-Phong material.
256
- */
257
- private _createBlinnPhongMaterial(
258
- definition: ObjMaterialDefinition | undefined,
259
- camera: ICamera,
260
- lightsBuffer: LightsBuffer | undefined): IMaterial {
261
-
262
- const material = this._framework.materialFactory.createForwardBlinnPhongMaterial({
139
+ /** @inheritDoc */
140
+ public loadBlinnPhongMeshAsync(path: string, camera: ICamera): Promise<IRenderableMesh> {
141
+ if (!camera?.projectionViewBuffer || !camera?.positionBuffer) {
142
+ throw new Error(`loadBlinnPhongMeshAsync("${path}"): the camera has no projectionViewBuffer/positionBuffer. Pass an initialized camera (the camera factory initializes it).`);
143
+ }
144
+ return this._framework.objLoader.loadAsync(path, {
263
145
  projectionViewBuffer: camera.projectionViewBuffer,
264
146
  cameraPositionBuffer: camera.positionBuffer,
265
- lightsBuffer: lightsBuffer,
266
147
  });
267
- // Matches the scene camera, so Scene.update() does not rebind.
268
- material.camera = camera;
269
-
270
- const diffuse = definition?.diffuseColor ?? [1, 1, 1];
271
- const ambient = definition?.ambientColor ?? diffuse;
272
- material.diffuseColor = new Color(diffuse[0], diffuse[1], diffuse[2], definition?.opacity ?? 1);
273
- material.ambientColor = new Color(ambient[0], ambient[1], ambient[2]);
274
- if (definition?.specularColor) {
275
- const specular = definition.specularColor;
276
- material.specularColor = new Color(specular[0], specular[1], specular[2]);
277
- }
278
- if (definition?.specularExponent !== undefined) {
279
- material.shininess = definition.specularExponent;
280
- }
281
- return material;
282
148
  }
283
149
  }
@@ -1,4 +1,6 @@
1
- import type { Scene } from "../scene/Scene.ts";
1
+ import type { ICamera } from "../camera/ICamera.ts";
2
+ import type { GeometryFormat } from "../geometry/GeometryFormat.ts";
3
+ import type { IRenderableMesh } from "../meshes/IRenderableMesh.ts";
2
4
  import type { IShaderModuleLoader } from "../shader/IShaderModuleLoader.ts";
3
5
  import type { IShaderModule } from "../shader/IShaderModule.ts";
4
6
  import type { ITexture2D } from "../rendering/texture/ITexture2D.ts";
@@ -43,31 +45,33 @@ export interface IContentManager {
43
45
  loadTexture2DAsync(path: string, desc?: TextureDescriptor, contentConfig?: ContentConfig): Promise<ITexture2D>;
44
46
 
45
47
  /**
46
- * Loads a mesh from a model, typically.
47
- * Currently, OBJ(WAVEFRONT) is supported.
48
- * The mesh has one submesh per `usemtl` range, all sharing one vertex and index buffer.
49
- * By default, each submesh gets an unlit material with the .mtl `Kd` as diffuse colour and `d` as alpha.
50
- * @param path The path or url to the model.
51
- * @param scene The scene the mesh adds itself to; `scene.render()` draws it. The materials use `scene.camera`
52
- * (assigned on `scene.update()` when it is set later).
48
+ * Loads a plain mesh (geometry and buffers only, no material or transform) from an OBJ (Wavefront) file,
49
+ * like C# `ContentManager.LoadMesh`. Materials (.mtl) are not loaded.
50
+ * @param path The path or url to the .obj file.
51
+ * @param geometryFormat The vertex layout of the buffers, e.g. the format of the material it will be drawn with.
53
52
  * @return The mesh.
54
53
  */
55
- loadMeshAsync(path: string, scene: Scene): Promise<IMesh>;
54
+ loadMeshAsync(path: string, geometryFormat: GeometryFormat): Promise<IMesh>;
56
55
 
57
56
  /**
58
- * Loads an OBJ (Wavefront) mesh with lit Blinn-Phong materials.
59
- * Like {@link loadMeshAsync}, the mesh has one submesh per `usemtl` range sharing one vertex and index buffer,
60
- * and ranges with the same material name share one material. `scene.render()` draws it.
61
- * The .mtl values map onto `ForwardBlinnPhongMaterial`:
62
- * - `Kd` → `diffuseColor` (with `d` as alpha), white when missing.
63
- * - `Ka` → `ambientColor`, the diffuse colour when missing.
64
- * - `Ks` → `specularColor` and `Ns` → `shininess`, the material defaults (0.5 grey, 32) when missing.
65
- * Without an .mtl file every submesh gets a white material with those defaults.
57
+ * Loads an OBJ mesh with unlit materials, through `framework.objLoader`.
58
+ * The root mesh has no material; each `usemtl` range is a sub mesh with an unlit material
59
+ * (`Kd` as diffuse colour, `d` as alpha, white when missing). Add it with `scene.add(mesh)`.
60
+ * @param path The path or url to the .obj file.
61
+ * @param camera The optional camera; `scene.update()` assigns the scene camera anyway.
62
+ * @return The root mesh.
63
+ */
64
+ loadUnlitMeshAsync(path: string, camera?: ICamera): Promise<IRenderableMesh>;
65
+
66
+ /**
67
+ * Loads an OBJ mesh with Blinn-Phong materials: shorthand for
68
+ * `framework.objLoader.loadAsync(path, {projectionViewBuffer: camera.projectionViewBuffer, cameraPositionBuffer: camera.positionBuffer})`.
69
+ * See `ObjLoader.loadAsync` for the .mtl mapping. Add it with `scene.add(mesh)`; the scene assigns its camera and lights.
66
70
  * @param path The path or url to the .obj file. A relative `mtllib` is resolved against it.
67
- * @param scene The scene the mesh adds itself to. Every material uses the scene's lights and `scene.camera`
68
- * (assigned on `scene.update()` when it is set later).
69
- * @return The mesh.
71
+ * @param camera An initialized camera (e.g. `scene.camera`).
72
+ * @return The root mesh.
73
+ * @throws Error when the camera has no buffers.
70
74
  */
71
- loadBlinnPhongMeshAsync(path: string, scene: Scene): Promise<IMesh>;
75
+ loadBlinnPhongMeshAsync(path: string, camera: ICamera): Promise<IRenderableMesh>;
72
76
 
73
77
  }
@@ -36,8 +36,9 @@ export interface LightsBufferDescriptor {
36
36
  }
37
37
 
38
38
  /**
39
- * Holds the lights of a scene and owns the uniform buffer that shaders read them from.
40
- * Assign it to lit materials, e.g. `ForwardBlinnPhongMaterial.lightsBuffer`.
39
+ * Holds lights and owns the uniform buffer that shaders read them from.
40
+ * Each lit material (`ForwardBlinnPhongMaterial`) owns one.
41
+ *
41
42
  *
42
43
  * std140 layout of the `LightsBuffer` block:
43
44
  * Every light colour is written premultiplied by its intensity, so the layout has no intensity field.
@@ -52,14 +53,20 @@ export interface LightsBuffer extends IDisposable {
52
53
  /** The ambient light written to the buffer. */
53
54
  ambientLight: AmbientLight;
54
55
 
55
- /** The directional lights written to the buffer. Read-only; use {@link add} and {@link remove}. Unused slots are black. */
56
- readonly directionalLights: readonly DirectionalLight[];
56
+ /**
57
+ * The directional lights written to the buffer. Can be replaced by another list, which is then used by reference
58
+ * (a lit material uses the scene's list). Only the first {@link maxDirectionalLights} are written; unused slots are black.
59
+ */
60
+ directionalLights: DirectionalLight[];
57
61
 
58
62
  /** The number of directional light slots in the buffer. */
59
63
  readonly maxDirectionalLights: number;
60
64
 
61
- /** The point lights written to the buffer. Read-only; use {@link add} and {@link remove}. Unused slots are black. */
62
- readonly pointLights: readonly PointLight[];
65
+ /**
66
+ * The point lights written to the buffer. Can be replaced by another list, which is then used by reference.
67
+ * Only the first {@link maxPointLights} are written; unused slots are black.
68
+ */
69
+ pointLights: PointLight[];
63
70
 
64
71
  /** The number of point light slots in the buffer. */
65
72
  readonly maxPointLights: number;
@@ -2,7 +2,7 @@ import type {GeometryDescriptor} from "../geometry/IGeometryBuilder.ts";
2
2
  import type {ObjGeometryDefinition} from "./obj/index.ts";
3
3
 
4
4
  /**
5
- * Maps plain OBJ geometry definitions from {@link ObjLoader} onto the framework's {@link GeometryDescriptor}.
5
+ * Maps plain OBJ geometry definitions from {@link ObjParser} onto the framework's {@link GeometryDescriptor}.
6
6
  * Pass the result to `geometryBuilder.create`.
7
7
  * Not part of the public API: `content.loadMeshAsync` and `content.loadBlinnPhongMeshAsync` use it.
8
8
  * @internal
@@ -11,7 +11,7 @@ export class ObjGeometryMapper {
11
11
 
12
12
  /**
13
13
  * Creates a geometry descriptor from an OBJ geometry definition.
14
- * @param definition The geometry definition, e.g. `result.geometry` from `ObjLoader.loadAsync`.
14
+ * @param definition The geometry definition, e.g. `result.geometry` from `ObjParser.loadAsync`.
15
15
  * @param useMaterialColors True keeps the loader's per-vertex `Kd` colours; false (the default) uses white,
16
16
  * for when each submesh's material carries the colour instead.
17
17
  * @returns The descriptor. It references the definition's arrays; `geometryBuilder.create` copies them.
@@ -0,0 +1,126 @@
1
+ import type {IFramework} from "../IFramework.ts";
2
+ import type {IRenderableMesh} from "../meshes/IRenderableMesh.ts";
3
+ import {RenderableMesh} from "../meshes/RenderableMesh.ts";
4
+ import type {IMaterial} from "../material/IMaterial.ts";
5
+ import {ForwardBlinnPhongMaterialDescriptor} from "../material/ForwardBlinnPhongMaterial.ts";
6
+ import {Color} from "../data/Color.ts";
7
+ import {ObjParser} from "./obj/ObjParser.ts";
8
+ import type {ObjLoadOptions, ObjModel, ObjSubMesh} from "./obj/ObjTypes.ts";
9
+ import {ObjGeometryMapper} from "./ObjGeometryMapper.ts";
10
+
11
+ /** Creates the material for one OBJ sub mesh (`usemtl` range). */
12
+ export type ObjMaterialFactory = (subMesh: ObjSubMesh) => IMaterial;
13
+
14
+ /**
15
+ * Loads OBJ (Wavefront) models into renderable meshes (C# `ObjLoader`). Available as `framework.objLoader`.
16
+ *
17
+ * The returned root mesh has no material and owns the vertex and index buffers; each `usemtl` range is a sub mesh
18
+ * with its own material (ranges with the same material name share one material instance).
19
+ * Vertex colours are white, the materials carry the colour. Parsing is done by the engine-independent {@link ObjParser}.
20
+ * @public
21
+ */
22
+ export class ObjLoader {
23
+
24
+ /** Default specular colour when the .mtl has no `Ks` (0.5 grey). */
25
+ public static readonly DEFAULT_SPECULAR = 0.5;
26
+
27
+ /** Default shininess when the .mtl has no `Ns`. */
28
+ public static readonly DEFAULT_SHININESS = 32;
29
+
30
+ /**
31
+ * The constructor.
32
+ * @param _framework The framework.
33
+ */
34
+ public constructor(private readonly _framework: IFramework) {
35
+ }
36
+
37
+ /**
38
+ * Parses an .obj file (and its .mtl files) into plain data. Creates no GPU resources (C# `ObjLoader.Parse`).
39
+ * @param path The .obj URL.
40
+ * @param options Optional: how to resolve `mtllib` names, or skip materials.
41
+ * @returns The model.
42
+ */
43
+ public static parseAsync(path: string, options?: ObjLoadOptions): Promise<ObjModel> {
44
+ return new ObjParser().parseAsync(path, options);
45
+ }
46
+
47
+ /**
48
+ * Loads an .obj file into a renderable mesh with one Blinn-Phong material per `usemtl` range.
49
+ * The .mtl values map onto `ForwardBlinnPhongMaterial`: `Kd` (with `d` as alpha) → diffuse colour (white when missing),
50
+ * `Ka` → ambient colour (falls back to `Kd`), `Ks` → specular colour (0.5 grey), `Ns` → shininess (32).
51
+ * @param path The .obj URL. A relative `mtllib` is resolved against it.
52
+ * @param descriptor The descriptor every material is created with (camera buffers, primitive state).
53
+ * @param options Optional parser options.
54
+ * @returns The root mesh.
55
+ */
56
+ public loadAsync(path: string, descriptor: ForwardBlinnPhongMaterialDescriptor, options?: ObjLoadOptions): Promise<IRenderableMesh>;
57
+
58
+ /**
59
+ * Loads an .obj file into a renderable mesh, creating each sub mesh's material with a callback.
60
+ * @param path The .obj URL.
61
+ * @param createMaterial Called once per distinct `usemtl` name.
62
+ * @param options Optional parser options.
63
+ * @returns The root mesh.
64
+ */
65
+ public loadAsync(path: string, createMaterial: ObjMaterialFactory, options?: ObjLoadOptions): Promise<IRenderableMesh>;
66
+
67
+ public async loadAsync(path: string,
68
+ materialSource: ForwardBlinnPhongMaterialDescriptor | ObjMaterialFactory,
69
+ options?: ObjLoadOptions): Promise<IRenderableMesh> {
70
+ // Validate before fetching, so a bad descriptor fails fast.
71
+ const createMaterial: ObjMaterialFactory = typeof materialSource === "function"
72
+ ? materialSource
73
+ : this._blinnPhongFactory(materialSource);
74
+ const model = await ObjLoader.parseAsync(path, options);
75
+ return this.createMesh(model, createMaterial);
76
+ }
77
+
78
+ /**
79
+ * Creates a renderable mesh from a parsed model.
80
+ * @param model The model, e.g. from {@link parseAsync}.
81
+ * @param createMaterial Creates the material per distinct `usemtl` name.
82
+ * @returns The root mesh, without a material, with one sub mesh per range.
83
+ */
84
+ public createMesh(model: ObjModel, createMaterial: ObjMaterialFactory): IRenderableMesh {
85
+ if (model.subMeshes.length == 0) {
86
+ throw new Error("ObjLoader: the model has no faces.");
87
+ }
88
+ const materialsByName = new Map<string | undefined, IMaterial>();
89
+ const materials = model.subMeshes.map(subMesh => {
90
+ let material = materialsByName.get(subMesh.materialName);
91
+ if (!material) {
92
+ material = createMaterial(subMesh);
93
+ materialsByName.set(subMesh.materialName, material);
94
+ }
95
+ return material;
96
+ });
97
+ const format = materials[0].geometryFormat;
98
+ if (materials.some(m => m.geometryFormat != format)) {
99
+ throw new Error("ObjLoader: all materials must use the same geometry format, as the sub meshes share one vertex buffer.");
100
+ }
101
+
102
+ const geometry = this._framework.geometryBuilder.create(ObjGeometryMapper.toDescriptor(model.geometry));
103
+ const root = new RenderableMesh(this._framework);
104
+ root.setGeometry(geometry, format);
105
+ model.subMeshes.forEach((subMesh, i) => root.addSubMesh(materials[i], subMesh.indexStart, subMesh.indexCount));
106
+ return root;
107
+ }
108
+
109
+ private _blinnPhongFactory(descriptor: ForwardBlinnPhongMaterialDescriptor): ObjMaterialFactory {
110
+ if (!descriptor?.projectionViewBuffer || !descriptor?.cameraPositionBuffer) {
111
+ throw new Error("ObjLoader.loadAsync: the Blinn-Phong descriptor needs projectionViewBuffer and cameraPositionBuffer (e.g. camera.projectionViewBuffer and camera.positionBuffer).");
112
+ }
113
+ return subMesh => {
114
+ const definition = subMesh.material;
115
+ const material = this._framework.materialFactory.createForwardBlinnPhongMaterial(descriptor);
116
+ const diffuse = definition?.diffuseColor ?? [1, 1, 1];
117
+ const ambient = definition?.ambientColor ?? diffuse;
118
+ const specular = definition?.specularColor ?? [ObjLoader.DEFAULT_SPECULAR, ObjLoader.DEFAULT_SPECULAR, ObjLoader.DEFAULT_SPECULAR];
119
+ material.diffuseColor = new Color(diffuse[0], diffuse[1], diffuse[2], definition?.opacity ?? 1);
120
+ material.ambientColor = new Color(ambient[0], ambient[1], ambient[2]);
121
+ material.specularColor = new Color(specular[0], specular[1], specular[2]);
122
+ material.shininess = definition?.specularExponent ?? ObjLoader.DEFAULT_SHININESS;
123
+ return material;
124
+ };
125
+ }
126
+ }
@@ -1,3 +1,4 @@
1
1
  export * from "./IImageLoader.ts"
2
2
  export * from "./ImageLoader.ts"
3
3
  export * from "./obj/index.ts"
4
+ export * from "./ObjLoader.ts"