ris-framework 0.1.0 → 0.2.0-dev.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +49 -1
- package/README.md +15 -4
- package/dist/Framework.d.ts +9 -3
- package/dist/Framework.d.ts.map +1 -1
- package/dist/api/IFramework.d.ts +7 -6
- package/dist/api/IFramework.d.ts.map +1 -1
- package/dist/api/_export.d.ts +2 -0
- package/dist/api/_export.d.ts.map +1 -1
- package/dist/api/camera/CameraFactory.d.ts +3 -2
- package/dist/api/camera/CameraFactory.d.ts.map +1 -1
- package/dist/api/camera/ICamera.d.ts +5 -0
- package/dist/api/camera/ICamera.d.ts.map +1 -1
- package/dist/api/camera/ICameraFactory.d.ts +5 -6
- package/dist/api/camera/ICameraFactory.d.ts.map +1 -1
- package/dist/api/camera/OrthographicCamera.d.ts +7 -0
- package/dist/api/camera/OrthographicCamera.d.ts.map +1 -1
- package/dist/api/camera/PerspectiveCamera.d.ts +30 -6
- package/dist/api/camera/PerspectiveCamera.d.ts.map +1 -1
- package/dist/api/content/ContentManager.d.ts +67 -2
- package/dist/api/content/ContentManager.d.ts.map +1 -1
- package/dist/api/content/IContentManager.d.ts +32 -1
- package/dist/api/content/IContentManager.d.ts.map +1 -1
- package/dist/api/content/ShaderModuleContent.d.ts.map +1 -1
- package/dist/api/data/Color.d.ts +5 -0
- package/dist/api/data/Color.d.ts.map +1 -1
- package/dist/api/geometry/BaseGeometry.d.ts +9 -0
- package/dist/api/geometry/BaseGeometry.d.ts.map +1 -1
- package/dist/api/geometry/GeometryBuilder.d.ts +3 -1
- package/dist/api/geometry/GeometryBuilder.d.ts.map +1 -1
- package/dist/api/geometry/IGeometryBuilder.d.ts +24 -0
- package/dist/api/geometry/IGeometryBuilder.d.ts.map +1 -1
- package/dist/api/geometry/_export-geometry.d.ts +1 -0
- package/dist/api/geometry/_export-geometry.d.ts.map +1 -1
- package/dist/api/input/InputManager.d.ts +4 -0
- package/dist/api/input/InputManager.d.ts.map +1 -1
- package/dist/api/lights/AmbientLight.d.ts +35 -0
- package/dist/api/lights/AmbientLight.d.ts.map +1 -0
- package/dist/api/lights/DirectionalLight.d.ts +40 -0
- package/dist/api/lights/DirectionalLight.d.ts.map +1 -0
- package/dist/api/lights/LightFactory.d.ts +18 -0
- package/dist/api/lights/LightFactory.d.ts.map +1 -0
- package/dist/api/lights/LightId.d.ts +6 -0
- package/dist/api/lights/LightId.d.ts.map +1 -0
- package/dist/api/lights/LightsBuffer.d.ts +70 -0
- package/dist/api/lights/LightsBuffer.d.ts.map +1 -0
- package/dist/api/lights/PointLight.d.ts +59 -0
- package/dist/api/lights/PointLight.d.ts.map +1 -0
- package/dist/api/lights/_export.d.ts +6 -0
- package/dist/api/lights/_export.d.ts.map +1 -0
- package/dist/api/loaders/ObjGeometryMapper.d.ts +19 -0
- package/dist/api/loaders/ObjGeometryMapper.d.ts.map +1 -0
- package/dist/api/loaders/_export.d.ts +1 -0
- package/dist/api/loaders/_export.d.ts.map +1 -1
- package/dist/api/loaders/obj/ObjLoader.d.ts +29 -0
- package/dist/api/loaders/obj/ObjLoader.d.ts.map +1 -0
- package/dist/api/loaders/obj/ObjTypes.d.ts +103 -0
- package/dist/api/loaders/obj/ObjTypes.d.ts.map +1 -0
- package/dist/api/loaders/obj/index.d.ts +3 -0
- package/dist/api/loaders/obj/index.d.ts.map +1 -0
- package/dist/api/material/ForwardBlinnPhongMaterial.d.ts +127 -0
- package/dist/api/material/ForwardBlinnPhongMaterial.d.ts.map +1 -0
- package/dist/api/material/IMaterial.d.ts +15 -6
- package/dist/api/material/IMaterial.d.ts.map +1 -1
- package/dist/api/material/IMaterialFactory.d.ts +17 -2
- package/dist/api/material/IMaterialFactory.d.ts.map +1 -1
- package/dist/api/material/InspectTextureMipsMaterial.d.ts +16 -7
- package/dist/api/material/InspectTextureMipsMaterial.d.ts.map +1 -1
- package/dist/api/material/MaterialFactory.d.ts +6 -0
- package/dist/api/material/MaterialFactory.d.ts.map +1 -1
- package/dist/api/material/SpriteMaterial.d.ts +51 -0
- package/dist/api/material/SpriteMaterial.d.ts.map +1 -0
- package/dist/api/material/UnlitMaterial.d.ts +28 -10
- package/dist/api/material/UnlitMaterial.d.ts.map +1 -1
- package/dist/api/material/_export.d.ts +2 -0
- package/dist/api/material/_export.d.ts.map +1 -1
- package/dist/api/meshes/IMesh.d.ts +35 -5
- package/dist/api/meshes/IMesh.d.ts.map +1 -1
- package/dist/api/meshes/IMeshFactory.d.ts +25 -4
- package/dist/api/meshes/IMeshFactory.d.ts.map +1 -1
- package/dist/api/meshes/Mesh.d.ts +58 -6
- package/dist/api/meshes/Mesh.d.ts.map +1 -1
- package/dist/api/meshes/MeshFactory.d.ts +7 -3
- package/dist/api/meshes/MeshFactory.d.ts.map +1 -1
- package/dist/api/meshes/QuadMesh.d.ts +5 -1
- package/dist/api/meshes/QuadMesh.d.ts.map +1 -1
- package/dist/api/meshes/SubMesh.d.ts +47 -0
- package/dist/api/meshes/SubMesh.d.ts.map +1 -0
- package/dist/api/meshes/_export.d.ts +1 -0
- package/dist/api/meshes/_export.d.ts.map +1 -1
- package/dist/api/rendering/render-pipelines/IForwardBlinnPhongRenderPipeline.d.ts +56 -0
- package/dist/api/rendering/render-pipelines/IForwardBlinnPhongRenderPipeline.d.ts.map +1 -0
- package/dist/api/rendering/render-pipelines/IRenderPipeline.d.ts +3 -0
- package/dist/api/rendering/render-pipelines/IRenderPipeline.d.ts.map +1 -1
- package/dist/api/rendering/render-pipelines/IRenderPipelineFactory.d.ts +29 -0
- package/dist/api/rendering/render-pipelines/IRenderPipelineFactory.d.ts.map +1 -1
- package/dist/api/rendering/render-pipelines/_export-render-pipelines.d.ts +1 -0
- package/dist/api/rendering/render-pipelines/_export-render-pipelines.d.ts.map +1 -1
- package/dist/api/scene/Scene.d.ts +104 -0
- package/dist/api/scene/Scene.d.ts.map +1 -0
- package/dist/api/shader/IShaderModuleLoader.d.ts +4 -1
- package/dist/api/shader/IShaderModuleLoader.d.ts.map +1 -1
- package/dist/api/shader/{shader-loader.d.ts → ShaderLoader.d.ts} +1 -1
- package/dist/api/shader/ShaderLoader.d.ts.map +1 -0
- package/dist/api/sprites/SpriteBatchDrawable.d.ts +1 -1
- package/dist/api/sprites/SpriteBatchDrawable.d.ts.map +1 -1
- package/dist/api/sprites/SpriteBatchMesh.d.ts +14 -1
- package/dist/api/sprites/SpriteBatchMesh.d.ts.map +1 -1
- package/dist/api/utilities/GeometryUtilities.d.ts.map +1 -1
- package/dist/api/window/WindowManager.d.ts +4 -0
- package/dist/api/window/WindowManager.d.ts.map +1 -1
- package/dist/core/rendering/vertex-buffer-layout.d.ts +1 -0
- package/dist/core/rendering/vertex-buffer-layout.d.ts.map +1 -1
- package/dist/index.js +2252 -260
- package/dist/webgl/WebGlGraphicsDevice.d.ts.map +1 -1
- package/dist/webgl/lights/WebGlAmbientLightFactory.d.ts +17 -0
- package/dist/webgl/lights/WebGlAmbientLightFactory.d.ts.map +1 -0
- package/dist/webgl/lights/WebGlLightsBuffer.d.ts +55 -0
- package/dist/webgl/lights/WebGlLightsBuffer.d.ts.map +1 -0
- package/dist/webgl/render-pipelines/AWebGlRenderPipeline.d.ts +3 -1
- package/dist/webgl/render-pipelines/AWebGlRenderPipeline.d.ts.map +1 -1
- package/dist/webgl/render-pipelines/WebGlMainRenderTargetRenderPipeline.d.ts +3 -0
- package/dist/webgl/render-pipelines/WebGlMainRenderTargetRenderPipeline.d.ts.map +1 -1
- package/dist/webgl/render-pipelines/WebGlRenderPipelineFactory.d.ts +3 -1
- package/dist/webgl/render-pipelines/WebGlRenderPipelineFactory.d.ts.map +1 -1
- package/dist/webgl/render-pipelines/inspect/WebGlInspectTextureMipsRenderPipeline.d.ts +3 -1
- package/dist/webgl/render-pipelines/inspect/WebGlInspectTextureMipsRenderPipeline.d.ts.map +1 -1
- package/dist/webgl/render-pipelines/material/WebGlBlinnPhongRenderPipeline.d.ts +88 -0
- package/dist/webgl/render-pipelines/material/WebGlBlinnPhongRenderPipeline.d.ts.map +1 -0
- package/dist/webgl/render-pipelines/material/WebGlUnlitRenderPipeline.d.ts +3 -1
- package/dist/webgl/render-pipelines/material/WebGlUnlitRenderPipeline.d.ts.map +1 -1
- package/dist/webgl/render-pipelines/sprite/WebGlSpriteRenderPipeline.d.ts +3 -1
- package/dist/webgl/render-pipelines/sprite/WebGlSpriteRenderPipeline.d.ts.map +1 -1
- package/dist/webgl/shader/WebGlShaderModule.d.ts +4 -1
- package/dist/webgl/shader/WebGlShaderModule.d.ts.map +1 -1
- package/dist/webgl/shader/WebGlShaderModuleLoader.d.ts +16 -5
- package/dist/webgl/shader/WebGlShaderModuleLoader.d.ts.map +1 -1
- package/dist/webgl/texture/WebGlTexture2D.d.ts +8 -1
- package/dist/webgl/texture/WebGlTexture2D.d.ts.map +1 -1
- package/dist/webgl/utilities/webgl-filter-anisotropic-utilities.d.ts +0 -1
- package/dist/webgl/utilities/webgl-filter-anisotropic-utilities.d.ts.map +1 -1
- package/package.json +4 -4
- package/shaders/glsl/forward_blinn_phong_material_fs.glsl +110 -0
- package/shaders/glsl/forward_blinn_phong_material_vs.glsl +32 -0
- package/shaders/glsl/sprite_fs.glsl +1 -1
- package/shaders/glsl/unlit_material_fs.glsl +1 -1
- package/src/Framework.ts +37 -13
- package/src/api/IFramework.ts +8 -6
- package/src/api/_export.ts +2 -0
- package/src/api/camera/CameraFactory.ts +6 -6
- package/src/api/camera/ICamera.ts +6 -0
- package/src/api/camera/ICameraFactory.ts +5 -10
- package/src/api/camera/OrthographicCamera.ts +23 -1
- package/src/api/camera/PerspectiveCamera.ts +60 -15
- package/src/api/content/ContentManager.ts +201 -5
- package/src/api/content/IContentManager.ts +33 -1
- package/src/api/content/ShaderModuleContent.ts +9 -0
- package/src/api/data/Color.ts +7 -1
- package/src/api/geometry/BaseGeometry.ts +23 -0
- package/src/api/geometry/GeometryBuilder.ts +14 -2
- package/src/api/geometry/IGeometryBuilder.ts +31 -1
- package/src/api/geometry/_export-geometry.ts +2 -1
- package/src/api/input/InputManager.ts +14 -5
- package/src/api/lights/AmbientLight.ts +53 -0
- package/src/api/lights/DirectionalLight.ts +60 -0
- package/src/api/lights/LightFactory.ts +21 -0
- package/src/api/lights/LightId.ts +9 -0
- package/src/api/lights/LightsBuffer.ts +87 -0
- package/src/api/lights/PointLight.ts +91 -0
- package/src/api/lights/_export.ts +5 -0
- package/src/api/loaders/ObjGeometryMapper.ts +28 -0
- package/src/api/loaders/_export.ts +2 -1
- package/src/api/loaders/obj/ObjLoader.ts +270 -0
- package/src/api/loaders/obj/ObjTypes.ts +124 -0
- package/src/api/loaders/obj/index.ts +5 -0
- package/src/api/material/ForwardBlinnPhongMaterial.ts +302 -0
- package/src/api/material/IMaterial.ts +16 -6
- package/src/api/material/IMaterialFactory.ts +19 -2
- package/src/api/material/InspectTextureMipsMaterial.ts +63 -24
- package/src/api/material/MaterialFactory.ts +12 -0
- package/src/api/material/SpriteMaterial.ts +83 -0
- package/src/api/material/UnlitMaterial.ts +101 -29
- package/src/api/material/_export.ts +3 -1
- package/src/api/meshes/IMesh.ts +45 -6
- package/src/api/meshes/IMeshFactory.ts +27 -4
- package/src/api/meshes/Mesh.ts +163 -41
- package/src/api/meshes/MeshFactory.ts +30 -6
- package/src/api/meshes/QuadMesh.ts +6 -2
- package/src/api/meshes/SubMesh.ts +71 -0
- package/src/api/meshes/_export.ts +1 -0
- package/src/api/rendering/render-pipelines/IForwardBlinnPhongRenderPipeline.ts +66 -0
- package/src/api/rendering/render-pipelines/IRenderPipeline.ts +4 -0
- package/src/api/rendering/render-pipelines/IRenderPipelineFactory.ts +39 -0
- package/src/api/rendering/render-pipelines/_export-render-pipelines.ts +2 -1
- package/src/api/scene/Scene.ts +264 -0
- package/src/api/shader/IShaderModuleLoader.ts +2 -1
- package/src/api/sprites/SpriteBatchDrawable.ts +12 -16
- package/src/api/sprites/SpriteBatchMesh.ts +23 -4
- package/src/api/utilities/GeometryUtilities.ts +2 -0
- package/src/api/window/WindowManager.ts +22 -2
- package/src/core/rendering/vertex-buffer-layout.ts +32 -1
- package/src/main.ts +0 -1
- package/src/webgl/WebGlGraphicsDevice.ts +0 -1
- package/src/webgl/lights/WebGlAmbientLightFactory.ts +35 -0
- package/src/webgl/lights/WebGlLightsBuffer.ts +215 -0
- package/src/webgl/render-pipelines/AWebGlRenderPipeline.ts +7 -1
- package/src/webgl/render-pipelines/WebGlMainRenderTargetRenderPipeline.ts +3 -0
- package/src/webgl/render-pipelines/WebGlRenderPipelineFactory.ts +24 -2
- package/src/webgl/render-pipelines/inspect/WebGlInspectTextureMipsRenderPipeline.ts +16 -6
- package/src/webgl/render-pipelines/material/WebGlBlinnPhongRenderPipeline.ts +300 -0
- package/src/webgl/render-pipelines/material/WebGlUnlitRenderPipeline.ts +16 -6
- package/src/webgl/render-pipelines/sprite/WebGlSpriteRenderPipeline.ts +11 -7
- package/src/webgl/shader/WebGlShaderModule.ts +11 -4
- package/src/webgl/shader/WebGlShaderModuleLoader.ts +29 -10
- package/src/webgl/texture/WebGlTexture2D.ts +19 -5
- package/src/webgl/utilities/webgl-filter-anisotropic-utilities.ts +9 -6
- package/dist/api/shader/shader-loader.d.ts.map +0 -1
- /package/src/api/shader/{shader-loader.ts → ShaderLoader.ts} +0 -0
package/src/Framework.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {WebGlAmbientLightFactory} from "./webgl/lights/WebGlAmbientLightFactory.ts";
|
|
2
2
|
import {WindowManager} from "./api/window/WindowManager.ts";
|
|
3
3
|
import {FrameworkConfiguration} from "./api/FrameworkConfiguration.ts";
|
|
4
|
-
import {type IRendererConfiguration
|
|
4
|
+
import {type IRendererConfiguration} from "./api/rendering/renderer-interface.ts";
|
|
5
5
|
import {GeometryBuilder} from "./api/geometry/GeometryBuilder.ts";
|
|
6
6
|
import {ContentManager} from "./api/content/ContentManager.ts";
|
|
7
7
|
import {WebGlRenderer} from "./webgl/WebGlRenderer.ts";
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
type IInputManager,
|
|
27
27
|
ImageLoader,
|
|
28
28
|
type IMaterialFactory,
|
|
29
|
+
type AmbientLightFactory,
|
|
29
30
|
type IMeshFactory,
|
|
30
31
|
type ISpriteBatch,
|
|
31
32
|
type ITextureFactory,
|
|
@@ -35,6 +36,8 @@ import {
|
|
|
35
36
|
RenderingBackend,
|
|
36
37
|
TimeManager
|
|
37
38
|
} from "./api/index.ts";
|
|
39
|
+
import {WebGlTexture2D} from "./webgl/texture/WebGlTexture2D.ts";
|
|
40
|
+
import type {IDisposable} from "./api/core/IDisposable.ts";
|
|
38
41
|
import {WebGlShaderModuleLoader} from "./webgl/shader/WebGlShaderModuleLoader.ts";
|
|
39
42
|
import {TextureSamplerFilteringPreset} from "./core/rendering/enums.ts";
|
|
40
43
|
import {SpriteBatch} from "./api/sprites/SpriteBatch.ts";
|
|
@@ -53,12 +56,12 @@ export class Framework implements IFramework {
|
|
|
53
56
|
private readonly _onUpdateListeners: ((gameTime: GameTime) => void)[] = [];
|
|
54
57
|
private readonly _onRenderListeners: (() => void)[] = [];
|
|
55
58
|
|
|
56
|
-
private readonly _container: DependencyContainer;
|
|
57
59
|
private readonly _textureFactory: ITextureFactory;
|
|
58
60
|
private readonly _buffersFactory: IBufferFactory;
|
|
59
61
|
private readonly _contentManager: IContentManager;
|
|
60
62
|
private readonly _geometryBuilder: IGeometryBuilder;
|
|
61
63
|
private readonly _meshFactory: IMeshFactory;
|
|
64
|
+
private _disposed = false;
|
|
62
65
|
|
|
63
66
|
/**
|
|
64
67
|
* The constructor for the Framework class.
|
|
@@ -73,17 +76,15 @@ export class Framework implements IFramework {
|
|
|
73
76
|
}
|
|
74
77
|
options.backBufferSize = options.backBufferSize ?? vec2.fromValues(800, 600);
|
|
75
78
|
|
|
76
|
-
this._container = container.createChildContainer();
|
|
77
79
|
this.windowManager = new WindowManager(options.canvas ?? null);
|
|
78
80
|
|
|
79
|
-
//
|
|
81
|
+
// Services are created here and get their dependencies through their constructors.
|
|
80
82
|
const rendererConfig: IRendererConfiguration = {
|
|
81
83
|
backBufferSize: options.backBufferSize,
|
|
82
84
|
textureFiltering: options.textureFiltering ?? TextureSamplerFilteringPreset.BILINEAR,
|
|
83
85
|
alpha: options.alpha ?? false,
|
|
84
86
|
powerPreference: options.powerPreference ?? PowerPreferenceType.DEFAULT
|
|
85
87
|
};
|
|
86
|
-
this._container.registerInstance(RenderConfigurationSymbol, rendererConfig);
|
|
87
88
|
this.renderer = new WebGlRenderer(this, rendererConfig);
|
|
88
89
|
this.renderingBackend = RenderingBackend.WEB_GL;
|
|
89
90
|
this._textureFactory = new WebGlTextureFactory(this);
|
|
@@ -92,6 +93,7 @@ export class Framework implements IFramework {
|
|
|
92
93
|
this._contentManager = new ContentManager(this, new WebGlShaderModuleLoader(this));
|
|
93
94
|
this._meshFactory = new MeshFactory(this);
|
|
94
95
|
this.materialFactory = new MaterialFactory(this);
|
|
96
|
+
this.lightsFactory = new WebGlAmbientLightFactory(this);
|
|
95
97
|
|
|
96
98
|
this._buffersFactory = new WebGlBuffersFactory(this);
|
|
97
99
|
this.spriteBatch = new SpriteBatch(this);
|
|
@@ -216,6 +218,9 @@ export class Framework implements IFramework {
|
|
|
216
218
|
/** @inheritDoc */
|
|
217
219
|
public readonly materialFactory: IMaterialFactory;
|
|
218
220
|
|
|
221
|
+
/** @inheritDoc */
|
|
222
|
+
public readonly lightsFactory: AmbientLightFactory;
|
|
223
|
+
|
|
219
224
|
/** @inheritDoc */
|
|
220
225
|
public readonly timeManager: ITimeManager;
|
|
221
226
|
|
|
@@ -235,12 +240,13 @@ export class Framework implements IFramework {
|
|
|
235
240
|
|
|
236
241
|
this.timeManager.prepareStart();
|
|
237
242
|
|
|
238
|
-
//
|
|
239
|
-
for(const listener of this.
|
|
243
|
+
// Initialize callbacks.
|
|
244
|
+
for(const listener of this._onInitializeListeners){
|
|
240
245
|
listener();
|
|
241
246
|
}
|
|
242
247
|
|
|
243
|
-
|
|
248
|
+
// Load content events.
|
|
249
|
+
for(const listener of this._onLoadContentListeners){
|
|
244
250
|
listener();
|
|
245
251
|
}
|
|
246
252
|
|
|
@@ -271,10 +277,28 @@ export class Framework implements IFramework {
|
|
|
271
277
|
this.windowManager.runEventLoop();
|
|
272
278
|
}
|
|
273
279
|
|
|
274
|
-
/**
|
|
275
|
-
|
|
276
|
-
|
|
280
|
+
/**
|
|
281
|
+
* Stops the event loop and disposes the framework's services and GL resources,
|
|
282
|
+
* including per-framework caches such as the default texture and the shader modules.
|
|
283
|
+
* A new `Framework` afterwards creates fresh resources on its own context. Calling it twice does nothing.
|
|
284
|
+
*/
|
|
285
|
+
public dispose(): void {
|
|
286
|
+
if (this._disposed) {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
this._disposed = true;
|
|
290
|
+
|
|
291
|
+
this.windowManager.dispose();
|
|
292
|
+
(this.input as Partial<IDisposable>).dispose?.();
|
|
293
|
+
|
|
294
|
+
this._onLoadContentListeners.length = 0;
|
|
295
|
+
this._onInitializeListeners.length = 0;
|
|
296
|
+
this._onUpdateListeners.length = 0;
|
|
297
|
+
this._onRenderListeners.length = 0;
|
|
277
298
|
|
|
278
|
-
|
|
299
|
+
WebGlTexture2D.disposeDefault(this);
|
|
300
|
+
(this._contentManager as Partial<IDisposable>).dispose?.();
|
|
301
|
+
// Only exists after initialize(); it owns the default sampler and blend state.
|
|
302
|
+
(this.renderer.graphicsDevice as IGraphicsDevice | undefined)?.dispose();
|
|
279
303
|
}
|
|
280
304
|
}
|
package/src/api/IFramework.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type { IContentManager } from "./content/IContentManager.ts";
|
|
|
11
11
|
import type { IImageLoader } from "./loaders/IImageLoader.ts";
|
|
12
12
|
import type { IMeshFactory } from "./meshes/IMeshFactory.ts";
|
|
13
13
|
import type { IMaterialFactory } from "./material/IMaterialFactory.ts";
|
|
14
|
+
import type { AmbientLightFactory } from "./lights/LightFactory.ts";
|
|
14
15
|
import type { ITimeManager } from "./time/ITimeManager.ts";
|
|
15
16
|
import type { IInputManager } from "./input/IInputManager.ts";
|
|
16
17
|
import type { IWindowManager } from "./window/IWindowManager.ts";
|
|
@@ -91,6 +92,11 @@ export interface IFramework extends IDisposable {
|
|
|
91
92
|
*/
|
|
92
93
|
readonly materialFactory: IMaterialFactory;
|
|
93
94
|
|
|
95
|
+
/**
|
|
96
|
+
* The ambient light factory.
|
|
97
|
+
*/
|
|
98
|
+
readonly lightsFactory: AmbientLightFactory;
|
|
99
|
+
|
|
94
100
|
/**
|
|
95
101
|
* The time manager.
|
|
96
102
|
*/
|
|
@@ -117,14 +123,10 @@ export interface IFramework extends IDisposable {
|
|
|
117
123
|
*/
|
|
118
124
|
removeOnLoadContentListener(event: () => void): void;
|
|
119
125
|
|
|
120
|
-
/**
|
|
121
|
-
* Called when the framework is initialized.
|
|
122
|
-
*/
|
|
126
|
+
/** Called when the framework is initialized.*/
|
|
123
127
|
addOnInitializedListener(event: () => void): void;
|
|
124
128
|
|
|
125
|
-
/**
|
|
126
|
-
* Called when the framework is initialized.
|
|
127
|
-
*/
|
|
129
|
+
/** Called when the framework is initialized.*/
|
|
128
130
|
removeOnInitializedListener(event: () => void): void;
|
|
129
131
|
|
|
130
132
|
/**
|
package/src/api/_export.ts
CHANGED
|
@@ -22,5 +22,7 @@ export * from "./rendering/sampler/_export.ts"
|
|
|
22
22
|
export * from "./utilities/_export.ts"
|
|
23
23
|
export * from "./meshes/_export.ts";
|
|
24
24
|
export * from "./material/_export.ts";
|
|
25
|
+
export * from "./lights/_export.ts";
|
|
26
|
+
export * from "./scene/Scene.ts";
|
|
25
27
|
export * from "./input/_export.ts";
|
|
26
28
|
export * from "./image/_export.ts";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {vec2} from "gl-matrix";
|
|
2
2
|
import type { ICameraFactory } from "./ICameraFactory.ts";
|
|
3
|
+
import type { Scene } from "../scene/Scene.ts";
|
|
3
4
|
import type { IFramework } from "../IFramework.ts";
|
|
4
5
|
import type { IOrthographicCamera } from "./IOrthographicCamera.ts";
|
|
5
6
|
import {OrthographicCamera} from "./OrthographicCamera.ts";
|
|
6
7
|
import {OrbitCamera} from "./OrbitCamera.ts";
|
|
7
|
-
import {PerspectiveCamera} from "./PerspectiveCamera.ts";
|
|
8
|
-
import {MathHelper} from "../utilities/MathHelper.ts";
|
|
8
|
+
import {PerspectiveCamera, type PerspectiveCameraDescriptor} from "./PerspectiveCamera.ts";
|
|
9
9
|
|
|
10
10
|
/** The Camera Factory */
|
|
11
11
|
export class CameraFactory implements ICameraFactory {
|
|
@@ -41,15 +41,15 @@ export class CameraFactory implements ICameraFactory {
|
|
|
41
41
|
|
|
42
42
|
/** @inheritDoc */
|
|
43
43
|
public createOrbitCamera(fov = 60, aspectRatio = 1, near = 0.01, far = 100): OrbitCamera {
|
|
44
|
-
return new OrbitCamera(this.createPerspectiveCamera(fov, aspectRatio, near, far), this._framework.input);
|
|
44
|
+
return new OrbitCamera(this.createPerspectiveCamera({fov, aspectRatio, near, far}), this._framework.input);
|
|
45
45
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
/** @inheritDoc */
|
|
49
|
-
public createPerspectiveCamera(
|
|
50
|
-
|
|
51
|
-
const camera = new PerspectiveCamera(this._framework, fov, aspectRatio, near, far);
|
|
49
|
+
public createPerspectiveCamera(descriptor?: PerspectiveCameraDescriptor, scene? : Scene): PerspectiveCamera {
|
|
50
|
+
const camera = new PerspectiveCamera(this._framework, descriptor, scene);
|
|
52
51
|
camera.initialize();
|
|
52
|
+
|
|
53
53
|
return camera;
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -36,6 +36,12 @@ export interface ICamera extends IDisposable {
|
|
|
36
36
|
*/
|
|
37
37
|
readonly viewBuffer: IUniformBuffer;
|
|
38
38
|
|
|
39
|
+
/**
|
|
40
|
+
* The world-space eye position buffer, std140 `vec3` (`[x, y, z, 0]`).
|
|
41
|
+
* Used by lit materials for specular highlights.
|
|
42
|
+
*/
|
|
43
|
+
readonly positionBuffer: IUniformBuffer;
|
|
44
|
+
|
|
39
45
|
/**
|
|
40
46
|
* Update the GPU buffers.
|
|
41
47
|
* This needs to be called when camera properties are changed.
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { IOrthographicCamera } from "./IOrthographicCamera.ts";
|
|
2
2
|
import {vec2} from "gl-matrix";
|
|
3
3
|
import {OrbitCamera} from "./OrbitCamera.ts";
|
|
4
|
-
import {PerspectiveCamera} from "./PerspectiveCamera.ts";
|
|
4
|
+
import {PerspectiveCamera, type PerspectiveCameraDescriptor} from "./PerspectiveCamera.ts";
|
|
5
|
+
import type {Scene} from "../scene/Scene.ts";
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* The camera factory.
|
|
@@ -10,17 +11,11 @@ export interface ICameraFactory {
|
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Creates a new perspective camera.
|
|
13
|
-
* @param
|
|
14
|
-
* @param
|
|
15
|
-
* @param near The near plane. By default, 0.01.
|
|
16
|
-
* @param far The far plane. By default, 100.
|
|
14
|
+
* @param descriptor The optional descriptor; omitted fields use the defaults documented on {@link PerspectiveCameraDescriptor}.
|
|
15
|
+
* @param scene The optional scene; the camera becomes its `scene.camera`.
|
|
17
16
|
* @return The perspective camera.
|
|
18
17
|
*/
|
|
19
|
-
createPerspectiveCamera(
|
|
20
|
-
fov?: number,
|
|
21
|
-
aspectRatio?: number,
|
|
22
|
-
near?: number,
|
|
23
|
-
far?: number): PerspectiveCamera;
|
|
18
|
+
createPerspectiveCamera(descriptor?: PerspectiveCameraDescriptor, scene?: Scene): PerspectiveCamera;
|
|
24
19
|
|
|
25
20
|
/**
|
|
26
21
|
* Creates a new orthographic camera which is suitable for 2D games, or for UI rendering.
|
|
@@ -40,6 +40,9 @@ export class OrthographicCamera implements IOrthographicCamera {
|
|
|
40
40
|
private _projectionBuffer: IUniformBuffer = null!;
|
|
41
41
|
private _viewBuffer: IUniformBuffer = null!;
|
|
42
42
|
private _projectionViewBuffer: IUniformBuffer = null!;
|
|
43
|
+
private _positionBuffer: IUniformBuffer = null!;
|
|
44
|
+
/** std140 vec3 world-space eye, padded to 4 floats. */
|
|
45
|
+
private readonly _positionData = [0, 0, 0, 0];
|
|
43
46
|
|
|
44
47
|
/**
|
|
45
48
|
*
|
|
@@ -69,7 +72,7 @@ export class OrthographicCamera implements IOrthographicCamera {
|
|
|
69
72
|
this._near = near;
|
|
70
73
|
this._far = far;
|
|
71
74
|
|
|
72
|
-
this._eye = vec3.fromValues(0, 0,
|
|
75
|
+
this._eye = vec3.fromValues(0, 0, 1);
|
|
73
76
|
this._target = vec3.fromValues(0, 0, 0);
|
|
74
77
|
|
|
75
78
|
this._zSpaceLength = 2; // For WebGL2 it is 2, WebGPU it is 1.
|
|
@@ -204,6 +207,19 @@ export class OrthographicCamera implements IOrthographicCamera {
|
|
|
204
207
|
return this._viewBuffer;
|
|
205
208
|
}
|
|
206
209
|
|
|
210
|
+
/** @inheritDoc */
|
|
211
|
+
public get positionBuffer(): IUniformBuffer {
|
|
212
|
+
return this._positionBuffer;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** Writes the world-space eye into the std140 position data (no z flip: the look-at uses the eye as is). */
|
|
216
|
+
private _updatePositionData(): number[] {
|
|
217
|
+
this._positionData[0] = this._eye[0];
|
|
218
|
+
this._positionData[1] = this._eye[1];
|
|
219
|
+
this._positionData[2] = this._eye[2];
|
|
220
|
+
return this._positionData;
|
|
221
|
+
}
|
|
222
|
+
|
|
207
223
|
/**
|
|
208
224
|
* Updates the camera matrices.
|
|
209
225
|
*/
|
|
@@ -227,6 +243,10 @@ export class OrthographicCamera implements IOrthographicCamera {
|
|
|
227
243
|
this._projectionViewBuffer = this._framework.bufferFactory.createUniformBuffer(
|
|
228
244
|
this._projectionViewMatrix, BufferUsage.UNIFORM, "OrthographicCamera.projectionViewBuffer"
|
|
229
245
|
);
|
|
246
|
+
|
|
247
|
+
this._positionBuffer = this._framework.bufferFactory.createUniformBuffer(
|
|
248
|
+
this._updatePositionData(), BufferUsage.UNIFORM, "OrthographicCamera.positionBuffer"
|
|
249
|
+
);
|
|
230
250
|
}
|
|
231
251
|
|
|
232
252
|
/** @inheritDoc */
|
|
@@ -235,6 +255,7 @@ export class OrthographicCamera implements IOrthographicCamera {
|
|
|
235
255
|
this.projectionBuffer.update(this.projectionMatrix);
|
|
236
256
|
this.viewBuffer.update(this.viewMatrix);
|
|
237
257
|
this.projectionViewBuffer.update(this.projectionViewMatrix);
|
|
258
|
+
this.positionBuffer.update(this._updatePositionData());
|
|
238
259
|
}
|
|
239
260
|
|
|
240
261
|
/** @inheritDoc */
|
|
@@ -253,5 +274,6 @@ export class OrthographicCamera implements IOrthographicCamera {
|
|
|
253
274
|
this.projectionBuffer.dispose();
|
|
254
275
|
this.projectionViewBuffer.dispose();
|
|
255
276
|
this.viewBuffer.dispose();
|
|
277
|
+
this.positionBuffer.dispose();
|
|
256
278
|
}
|
|
257
279
|
}
|
|
@@ -5,6 +5,34 @@ import {MathHelper} from "../utilities/MathHelper.ts";
|
|
|
5
5
|
import {BufferUsage} from "../rendering/buffers/BufferUsage.ts";
|
|
6
6
|
import type { IUniformBuffer } from "../rendering/buffers/IUniformBuffer.ts";
|
|
7
7
|
import {GameTime} from "../time/GameTime.ts";
|
|
8
|
+
import type {Scene} from "../scene/Scene.ts";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The descriptor for a perspective camera. Every field is optional.
|
|
12
|
+
*/
|
|
13
|
+
export interface PerspectiveCameraDescriptor {
|
|
14
|
+
|
|
15
|
+
/** The vertical field of view in degrees. By default, 60. */
|
|
16
|
+
fov?: number;
|
|
17
|
+
|
|
18
|
+
/** The aspect ratio (width / height). By default, 1. */
|
|
19
|
+
aspectRatio?: number;
|
|
20
|
+
|
|
21
|
+
/** The near plane. By default, 0.01. */
|
|
22
|
+
near?: number;
|
|
23
|
+
|
|
24
|
+
/** The far plane. By default, 100. */
|
|
25
|
+
far?: number;
|
|
26
|
+
|
|
27
|
+
/** The eye position. Copied. By default, (0, 0, 3). */
|
|
28
|
+
eye?: vec3;
|
|
29
|
+
|
|
30
|
+
/** The point the camera looks at. Copied. By default, the origin. */
|
|
31
|
+
target?: vec3;
|
|
32
|
+
|
|
33
|
+
/** The up vector. Copied. By default, (0, 1, 0). */
|
|
34
|
+
up?: vec3;
|
|
35
|
+
}
|
|
8
36
|
|
|
9
37
|
/**
|
|
10
38
|
* The perspective camera.
|
|
@@ -26,24 +54,33 @@ export class PerspectiveCamera implements ICamera {
|
|
|
26
54
|
private _projectionBuffer: IUniformBuffer = null!;
|
|
27
55
|
|
|
28
56
|
/**
|
|
29
|
-
* The constructor.
|
|
57
|
+
* The constructor. Call `initialize()` before use (the camera factory does).
|
|
30
58
|
* @param framework The framework.
|
|
31
|
-
* @param
|
|
32
|
-
* @
|
|
33
|
-
* @param
|
|
34
|
-
* @param farPlane The far plane.
|
|
59
|
+
* @param descriptor The optional descriptor; omitted fields use the defaults documented on {@link PerspectiveCameraDescriptor}.
|
|
60
|
+
* `fov` is in degrees; {@link fieldOfView} holds it in radians. Vectors are copied.
|
|
61
|
+
* @param scene The optional scene; the camera assigns itself as `scene.camera`.
|
|
35
62
|
*/
|
|
36
63
|
public constructor(
|
|
37
64
|
framework: IFramework,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
nearPlane: number,
|
|
41
|
-
farPlane: number) {
|
|
65
|
+
descriptor?: PerspectiveCameraDescriptor,
|
|
66
|
+
scene?: Scene) {
|
|
42
67
|
this._framework = framework;
|
|
43
|
-
this.fieldOfView = fov;
|
|
44
|
-
this.aspectRatio = aspectRatio;
|
|
45
|
-
this.nearPlane =
|
|
46
|
-
this.farPlane =
|
|
68
|
+
this.fieldOfView = MathHelper.toRadians(descriptor?.fov ?? 60);
|
|
69
|
+
this.aspectRatio = descriptor?.aspectRatio ?? 1;
|
|
70
|
+
this.nearPlane = descriptor?.near ?? 0.01;
|
|
71
|
+
this.farPlane = descriptor?.far ?? 100;
|
|
72
|
+
if (descriptor?.eye) {
|
|
73
|
+
vec3.copy(this.eye, descriptor.eye);
|
|
74
|
+
}
|
|
75
|
+
if (descriptor?.target) {
|
|
76
|
+
vec3.copy(this.target, descriptor.target);
|
|
77
|
+
}
|
|
78
|
+
if (descriptor?.up) {
|
|
79
|
+
vec3.copy(this.up, descriptor.up);
|
|
80
|
+
}
|
|
81
|
+
if (scene) {
|
|
82
|
+
scene.add(this);
|
|
83
|
+
}
|
|
47
84
|
|
|
48
85
|
this._updateMatrices();
|
|
49
86
|
}
|
|
@@ -159,12 +196,20 @@ export class PerspectiveCamera implements ICamera {
|
|
|
159
196
|
*/
|
|
160
197
|
public initialize(): void {
|
|
161
198
|
const bufferUsage = BufferUsage.UNIFORM | BufferUsage.COPY_DST;
|
|
162
|
-
this._positionBuffer = this._framework.bufferFactory.createUniformBuffer(this.
|
|
199
|
+
this._positionBuffer = this._framework.bufferFactory.createUniformBuffer(this._worldEye(), bufferUsage);
|
|
163
200
|
this._projectionViewBuffer = this._framework.bufferFactory.createUniformBuffer(this.projectionViewMatrix, bufferUsage);
|
|
164
201
|
this._projectionBuffer = this._framework.bufferFactory.createUniformBuffer(this.projectionMatrix, bufferUsage);
|
|
165
202
|
this._viewBuffer = this._framework.bufferFactory.createUniformBuffer(this.viewMatrix, bufferUsage);
|
|
166
203
|
}
|
|
167
204
|
|
|
205
|
+
/**
|
|
206
|
+
* The eye in world space, as used by the view matrix: z is flipped for the right-handed look-at.
|
|
207
|
+
* This is what {@link positionBuffer} holds, std140 `vec3` (padded to 16 bytes).
|
|
208
|
+
*/
|
|
209
|
+
private _worldEye(): number[] {
|
|
210
|
+
return [this.eye[0], this.eye[1], -this.eye[2], 0];
|
|
211
|
+
}
|
|
212
|
+
|
|
168
213
|
/**
|
|
169
214
|
* Updates the camera matrices.
|
|
170
215
|
*/
|
|
@@ -190,7 +235,7 @@ export class PerspectiveCamera implements ICamera {
|
|
|
190
235
|
|
|
191
236
|
/** @inheritDoc */
|
|
192
237
|
public updateBuffers(): void {
|
|
193
|
-
this._positionBuffer.update(this.
|
|
238
|
+
this._positionBuffer.update(this._worldEye());
|
|
194
239
|
this._projectionBuffer.update(this.projectionMatrix);
|
|
195
240
|
this._viewBuffer.update(this.viewMatrix);
|
|
196
241
|
this._projectionViewBuffer.update(this.projectionViewMatrix);
|
|
@@ -3,12 +3,29 @@ import {
|
|
|
3
3
|
type IContentManager,
|
|
4
4
|
type IShaderModuleLoader,
|
|
5
5
|
type ITexture2D,
|
|
6
|
-
type IFramework,
|
|
6
|
+
type IFramework,
|
|
7
|
+
TextureDescriptor,
|
|
8
|
+
TextureFormat,
|
|
9
|
+
ContentConfig,
|
|
10
|
+
TextureUsage,
|
|
11
|
+
type IMesh,
|
|
12
|
+
ObjLoader,
|
|
13
|
+
Color,
|
|
14
|
+
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
|
+
type IDisposable,
|
|
7
24
|
} from "../index.ts";
|
|
25
|
+
import {ObjGeometryMapper} from "../loaders/ObjGeometryMapper.ts";
|
|
8
26
|
import {Ktx2Factory} from "ris-ktx2";
|
|
9
27
|
import type {IKtx2Texture} from "ris-ktx2";
|
|
10
28
|
|
|
11
|
-
|
|
12
29
|
/**
|
|
13
30
|
* The content manager.
|
|
14
31
|
* The content manager is responsible for managing the content modules and loading the content with the given asset file path or identifier.
|
|
@@ -17,6 +34,7 @@ export class ContentManager implements IContentManager {
|
|
|
17
34
|
|
|
18
35
|
private readonly _ktx2Factory = new Ktx2Factory();
|
|
19
36
|
private readonly _ktx2TextureCache: {[key: string]: IKtx2Texture} = {};
|
|
37
|
+
private readonly _objLoader = new ObjLoader();
|
|
20
38
|
|
|
21
39
|
/**
|
|
22
40
|
* The constructor.
|
|
@@ -41,9 +59,20 @@ export class ContentManager implements IContentManager {
|
|
|
41
59
|
return ktx2Texture;
|
|
42
60
|
}
|
|
43
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Disposes the cached shader modules (their GL programs) and forgets cached KTX2 data.
|
|
64
|
+
* Called from `Framework.dispose()`.
|
|
65
|
+
*/
|
|
66
|
+
public dispose(): void {
|
|
67
|
+
(this.shaderModuleLoader as Partial<IDisposable>).dispose?.();
|
|
68
|
+
for (const key of Object.keys(this._ktx2TextureCache)) {
|
|
69
|
+
delete this._ktx2TextureCache[key];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
44
73
|
/** @inheritDoc */
|
|
45
|
-
public loadShaderModule(shaderModuleId: string): IShaderModule {
|
|
46
|
-
return this.shaderModuleLoader.load(shaderModuleId);
|
|
74
|
+
public loadShaderModule(shaderModuleId: string, keyValueDictionary?: { [id:string]: number}): IShaderModule {
|
|
75
|
+
return this.shaderModuleLoader.load(shaderModuleId, keyValueDictionary);
|
|
47
76
|
}
|
|
48
77
|
|
|
49
78
|
/** @inheritDoc */
|
|
@@ -84,4 +113,171 @@ export class ContentManager implements IContentManager {
|
|
|
84
113
|
return this._framework.textureFactory.create(width, height, view);
|
|
85
114
|
}
|
|
86
115
|
|
|
87
|
-
|
|
116
|
+
/** @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);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** @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,
|
|
239
|
+
});
|
|
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
|
+
}
|
|
246
|
+
|
|
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({
|
|
263
|
+
projectionViewBuffer: camera.projectionViewBuffer,
|
|
264
|
+
cameraPositionBuffer: camera.positionBuffer,
|
|
265
|
+
lightsBuffer: lightsBuffer,
|
|
266
|
+
});
|
|
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
|
+
}
|
|
283
|
+
}
|