@xeokit/xeokit-sdk 2.6.92 → 2.6.93
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/xeokit-sdk.cjs.js +13074 -44661
- package/dist/xeokit-sdk.es.js +13075 -44660
- package/dist/xeokit-sdk.es5.js +1403 -3501
- package/dist/xeokit-sdk.min.cjs.js +8 -8
- package/dist/xeokit-sdk.min.es.js +8 -8
- package/dist/xeokit-sdk.min.es5.js +7 -7
- package/package.json +1 -1
- package/src/viewer/Viewer.js +55 -103
- package/src/viewer/scene/canvas/Canvas.js +3 -43
- package/src/viewer/scene/geometry/ReadableGeometry.js +0 -25
- package/src/viewer/scene/lights/CubeTexture.js +0 -13
- package/src/viewer/scene/lights/DirLight.js +2 -1
- package/src/viewer/scene/lights/PointLight.js +2 -1
- package/src/viewer/scene/materials/Texture.js +0 -9
- package/src/viewer/scene/math/rtcCoords.js +1 -38
- package/src/viewer/scene/mesh/Mesh.js +454 -212
- package/src/viewer/scene/mesh/draw/DrawShaderSource.js +305 -1504
- package/src/viewer/scene/mesh/draw/LambertShaderSource.js +35 -0
- package/src/viewer/scene/mesh/emphasis/EmphasisShaderSource.js +34 -0
- package/src/viewer/scene/mesh/occlusion/OcclusionShaderSource.js +9 -158
- package/src/viewer/scene/mesh/pick/PickMeshShaderSource.js +21 -151
- package/src/viewer/scene/mesh/pick/PickTriangleShaderSource.js +12 -124
- package/src/viewer/scene/mesh/shadow/ShadowShaderSource.js +22 -97
- package/src/viewer/scene/model/SceneModel.js +248 -852
- package/src/viewer/scene/model/SceneModelEntity.js +4 -4
- package/src/viewer/scene/model/SceneModelMesh.js +3 -3
- package/src/viewer/scene/model/layer/DTXLayer.js +940 -0
- package/src/viewer/scene/model/layer/Layer.js +788 -0
- package/src/viewer/scene/model/layer/VBOLayer.js +1019 -0
- package/src/viewer/scene/model/layer/programs/ColorProgram.js +35 -0
- package/src/viewer/scene/model/layer/programs/ColorTextureProgram.js +46 -0
- package/src/viewer/scene/model/layer/programs/DepthProgram.js +11 -0
- package/src/viewer/scene/model/layer/programs/EdgesProgram.js +12 -0
- package/src/viewer/scene/model/layer/programs/FlatColorProgram.js +24 -0
- package/src/viewer/scene/model/layer/programs/OcclusionProgram.js +12 -0
- package/src/viewer/scene/model/layer/programs/PBRProgram.js +180 -0
- package/src/viewer/scene/model/layer/programs/PickDepthProgram.js +30 -0
- package/src/viewer/scene/model/layer/programs/PickMeshProgram.js +12 -0
- package/src/viewer/scene/model/layer/programs/PickNormalsProgram.js +18 -0
- package/src/viewer/scene/model/layer/programs/ShadowProgram.js +23 -0
- package/src/viewer/scene/model/layer/programs/SilhouetteProgram.js +15 -0
- package/src/viewer/scene/model/layer/programs/SnapProgram.js +29 -0
- package/src/viewer/scene/scene/Scene.js +21 -38
- package/src/viewer/scene/webgl/ArrayBuf.js +5 -20
- package/src/viewer/scene/webgl/FrameContext.js +14 -86
- package/src/viewer/scene/webgl/RenderBuffer.js +62 -262
- package/src/viewer/scene/webgl/Renderer.js +880 -843
- package/src/viewer/scene/webgl/WebGLRenderer.js +612 -0
- package/src/viewer/scene/webgl/occlusion/OcclusionLayer.js +60 -132
- package/src/viewer/scene/webgl/occlusion/OcclusionTester.js +167 -328
- package/src/viewer/scene/mesh/draw/DrawRenderer.js +0 -998
- package/src/viewer/scene/mesh/emphasis/EmphasisEdgesRenderer.js +0 -259
- package/src/viewer/scene/mesh/emphasis/EmphasisEdgesShaderSource.js +0 -160
- package/src/viewer/scene/mesh/emphasis/EmphasisFillRenderer.js +0 -286
- package/src/viewer/scene/mesh/emphasis/EmphasisFillShaderSource.js +0 -263
- package/src/viewer/scene/mesh/occlusion/OcclusionRenderer.js +0 -221
- package/src/viewer/scene/mesh/pick/PickMeshRenderer.js +0 -223
- package/src/viewer/scene/mesh/pick/PickTriangleRenderer.js +0 -200
- package/src/viewer/scene/mesh/shadow/ShadowRenderer.js +0 -214
- package/src/viewer/scene/model/RENDER_PASSES.js +0 -34
- package/src/viewer/scene/model/dtx/BindableDataTexture.js +0 -31
- package/src/viewer/scene/model/dtx/lines/DTXLinesBuffer.js +0 -27
- package/src/viewer/scene/model/dtx/lines/DTXLinesLayer.js +0 -897
- package/src/viewer/scene/model/dtx/lines/DTXLinesState.js +0 -46
- package/src/viewer/scene/model/dtx/lines/DTXLinesTextureFactory.js +0 -411
- package/src/viewer/scene/model/dtx/lines/dataTextureRamStats.js +0 -49
- package/src/viewer/scene/model/dtx/lines/rebucketPositions.js +0 -208
- package/src/viewer/scene/model/dtx/lines/renderers/DTXLinesColorRenderer.js +0 -389
- package/src/viewer/scene/model/dtx/lines/renderers/DTXLinesRenderers.js +0 -65
- package/src/viewer/scene/model/dtx/triangles/DTXTrianglesLayer.js +0 -1399
- package/src/viewer/scene/model/dtx/triangles/lib/DTXTrianglesBuffer.js +0 -46
- package/src/viewer/scene/model/dtx/triangles/lib/DTXTrianglesState.js +0 -250
- package/src/viewer/scene/model/dtx/triangles/lib/DTXTrianglesTextureFactory.js +0 -518
- package/src/viewer/scene/model/dtx/triangles/lib/dataTextureRamStats.js +0 -54
- package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesColorRenderer.js +0 -639
- package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesDepthRenderer.js +0 -464
- package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesEdgesColorRenderer.js +0 -423
- package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesEdgesRenderer.js +0 -431
- package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesNormalsRenderer.js +0 -345
- package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesOcclusionRenderer.js +0 -436
- package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickDepthRenderer.js +0 -466
- package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickMeshRenderer.js +0 -437
- package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickNormalsFlatRenderer.js +0 -460
- package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickNormalsRenderer.js +0 -437
- package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesRenderers.js +0 -307
- package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSilhouetteRenderer.js +0 -472
- package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSnapInitRenderer.js +0 -474
- package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSnapRenderer.js +0 -435
- package/src/viewer/scene/model/vbo/ScratchMemory.js +0 -63
- package/src/viewer/scene/model/vbo/VBORenderer.js +0 -664
- package/src/viewer/scene/model/vbo/batching/lines/VBOBatchingLinesLayer.js +0 -704
- package/src/viewer/scene/model/vbo/batching/lines/lib/VBOBatchingLinesBuffer.js +0 -19
- package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLineSnapInitRenderer.js +0 -318
- package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesColorRenderer.js +0 -114
- package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesRenderers.js +0 -99
- package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesSilhouetteRenderer.js +0 -124
- package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesSnapInitRenderer.js +0 -313
- package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesSnapRenderer.js +0 -311
- package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOSceneModelLineBatchingRenderer.js +0 -24
- package/src/viewer/scene/model/vbo/batching/points/VBOBatchingPointsLayer.js +0 -688
- package/src/viewer/scene/model/vbo/batching/points/VBOBatchingPointsRenderer.js +0 -24
- package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsColorRenderer.js +0 -168
- package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsOcclusionRenderer.js +0 -136
- package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsPickDepthRenderer.js +0 -156
- package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsPickMeshRenderer.js +0 -148
- package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsRenderers.js +0 -144
- package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsShadowRenderer.js +0 -107
- package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsSilhouetteRenderer.js +0 -146
- package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsSnapInitRenderer.js +0 -315
- package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsSnapRenderer.js +0 -305
- package/src/viewer/scene/model/vbo/batching/triangles/VBOBatchingTrianglesBuffer.js +0 -24
- package/src/viewer/scene/model/vbo/batching/triangles/VBOBatchingTrianglesLayer.js +0 -1346
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/EdgesColorRenderer.js +0 -131
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/EdgesEmphasisRenderer.js +0 -135
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/EdgesRenderer.js +0 -12
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/Renderers.js +0 -403
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesBatchingRenderer.js +0 -35
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesColorRenderer.js +0 -252
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesColorTextureRenderer.js +0 -294
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesDepthRenderer.js +0 -115
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesFlatColorRenderer.js +0 -246
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesNormalsRenderer.js +0 -139
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesOcclusionRenderer.js +0 -125
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPBRRenderer.js +0 -561
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPickDepthRenderer.js +0 -144
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPickMeshRenderer.js +0 -130
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPickNormalsFlatRenderer.js +0 -121
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPickNormalsRenderer.js +0 -131
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesShadowRenderer.js +0 -107
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesSilhouetteRenderer.js +0 -144
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesSnapInitRenderer.js +0 -313
- package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesSnapRenderer.js +0 -312
- package/src/viewer/scene/model/vbo/float16.js +0 -760
- package/src/viewer/scene/model/vbo/instancing/lines/VBOInstancingLinesLayer.js +0 -711
- package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesColorRenderer.js +0 -148
- package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesRenderer.js +0 -26
- package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesRenderers.js +0 -139
- package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesSilhouetteRenderer.js +0 -127
- package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesSnapInitRenderer.js +0 -308
- package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesSnapRenderer.js +0 -299
- package/src/viewer/scene/model/vbo/instancing/points/VBOInstancingPointsLayer.js +0 -733
- package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsColorRenderer.js +0 -174
- package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsDepthRenderer.js +0 -156
- package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsOcclusionRenderer.js +0 -149
- package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsPickDepthRenderer.js +0 -170
- package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsPickMeshRenderer.js +0 -152
- package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsRenderer.js +0 -26
- package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsRenderers.js +0 -174
- package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsShadowRenderer.js +0 -119
- package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsSilhouetteRenderer.js +0 -154
- package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsSnapInitRenderer.js +0 -307
- package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsSnapRenderer.js +0 -293
- package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingTrianglesRenderer.js +0 -150
- package/src/viewer/scene/model/vbo/instancing/triangles/VBOInstancingTrianglesLayer.js +0 -1289
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/EdgesColorRenderer.js +0 -135
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/EdgesEmphasisRenderer.js +0 -137
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/EdgesRenderer.js +0 -12
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/Renderers.js +0 -403
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesColorRenderer.js +0 -267
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesColorTextureRenderer.js +0 -299
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesDepthRenderer.js +0 -126
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesFlatColorRenderer.js +0 -255
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesFlatNormalsRenderer.js +0 -130
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesInstancingRenderer.js +0 -32
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesNormalsRenderer.js +0 -138
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesOcclusionRenderer.js +0 -128
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPBRRenderer.js +0 -561
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPickDepthRenderer.js +0 -149
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPickMeshRenderer.js +0 -136
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPickNormalsFlatRenderer.js +0 -130
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPickNormalsRenderer.js +0 -145
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesShadowRenderer.js +0 -113
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesSilhouetteRenderer.js +0 -148
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesSnapInitRenderer.js +0 -319
- package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesSnapRenderer.js +0 -310
- package/src/viewer/scene/webgl/Attribute.js +0 -23
- package/src/viewer/scene/webgl/Program.js +0 -181
- package/src/viewer/scene/webgl/RenderBufferManager.js +0 -34
- package/src/viewer/scene/webgl/Sampler.js +0 -18
- package/src/viewer/scene/webgl/Shader.js +0 -49
- package/src/viewer/scene/webgl/sao/SAODepthLimitedBlurRenderer.js +0 -324
- package/src/viewer/scene/webgl/sao/SAOOcclusionRenderer.js +0 -384
|
@@ -11,15 +11,7 @@ import {createRTCViewMat} from "../math/rtcCoords.js";
|
|
|
11
11
|
class FrameContext {
|
|
12
12
|
|
|
13
13
|
constructor(scene) {
|
|
14
|
-
|
|
15
|
-
this._scene = scene;
|
|
16
|
-
|
|
17
14
|
this._matPool = [];
|
|
18
|
-
this._matPoolNextFreeIndex = 0;
|
|
19
|
-
|
|
20
|
-
this._rtcViewMats = {};
|
|
21
|
-
this._rtcPickViewMats = {};
|
|
22
|
-
|
|
23
15
|
this.reset();
|
|
24
16
|
}
|
|
25
17
|
|
|
@@ -31,13 +23,6 @@ class FrameContext {
|
|
|
31
23
|
|
|
32
24
|
this._matPoolNextFreeIndex = 0;
|
|
33
25
|
this._rtcViewMats = {};
|
|
34
|
-
this._rtcPickViewMats = {};
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* The WebGL rendering context.
|
|
38
|
-
* @type {WebGLRenderingContext}
|
|
39
|
-
*/
|
|
40
|
-
this.gl = this._scene.canvas.gl;
|
|
41
26
|
|
|
42
27
|
/**
|
|
43
28
|
* ID of the last {@link WebGLProgram} that was bound during the current frame.
|
|
@@ -157,59 +142,39 @@ class FrameContext {
|
|
|
157
142
|
*/
|
|
158
143
|
this.pass = 0;
|
|
159
144
|
|
|
160
|
-
|
|
161
|
-
* The 4x4 viewing transform matrix the renderer is currently using when rendering castsShadows.
|
|
162
|
-
*
|
|
163
|
-
* This sets the viewpoint to look from the point of view of each {@link DirLight}
|
|
164
|
-
* or {@link PointLight} that casts a shadow.
|
|
165
|
-
*
|
|
166
|
-
* @property shadowViewMatrix
|
|
167
|
-
* @type {Number[]}
|
|
168
|
-
*/
|
|
169
|
-
this.shadowViewMatrix = null;
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* The 4x4 viewing projection matrix the renderer is currently using when rendering shadows.
|
|
173
|
-
*
|
|
174
|
-
* @property shadowProjMatrix
|
|
175
|
-
* @type {Number[]}
|
|
176
|
-
*/
|
|
177
|
-
this.shadowProjMatrix = null;
|
|
145
|
+
this.viewParams = { };
|
|
178
146
|
|
|
179
147
|
/**
|
|
180
|
-
* The 4x4
|
|
148
|
+
* The 4x4 view matrix.
|
|
181
149
|
*
|
|
182
|
-
*
|
|
183
|
-
* when picking with a ray.
|
|
184
|
-
*
|
|
185
|
-
* @property pickViewMatrix
|
|
150
|
+
* @property viewMatrix
|
|
186
151
|
* @type {Number[]}
|
|
187
152
|
*/
|
|
188
|
-
this.
|
|
153
|
+
this.viewParams.viewMatrix = null;
|
|
189
154
|
|
|
190
155
|
/**
|
|
191
|
-
* The 4x4
|
|
156
|
+
* The 4x4 projection matrix.
|
|
192
157
|
*
|
|
193
|
-
* @property
|
|
158
|
+
* @property projMatrix
|
|
194
159
|
* @type {Number[]}
|
|
195
160
|
*/
|
|
196
|
-
this.
|
|
161
|
+
this.viewParams.projMatrix = null;
|
|
197
162
|
|
|
198
163
|
/**
|
|
199
164
|
* Distance to the near clipping plane when rendering depth fragments for GPU-accelerated 3D picking.
|
|
200
165
|
*
|
|
201
|
-
* @property
|
|
166
|
+
* @property near
|
|
202
167
|
* @type {Number|*}
|
|
203
168
|
*/
|
|
204
|
-
this.
|
|
169
|
+
this.viewParams.near = 0.01;
|
|
205
170
|
|
|
206
171
|
/**
|
|
207
172
|
* Distance to the far clipping plane when rendering depth fragments for GPU-accelerated 3D picking.
|
|
208
173
|
*
|
|
209
|
-
* @property
|
|
174
|
+
* @property far
|
|
210
175
|
* @type {Number|*}
|
|
211
176
|
*/
|
|
212
|
-
this.
|
|
177
|
+
this.viewParams.far = 5000;
|
|
213
178
|
|
|
214
179
|
/**
|
|
215
180
|
* Whether or not the renderer is currently picking invisible objects.
|
|
@@ -219,22 +184,6 @@ class FrameContext {
|
|
|
219
184
|
*/
|
|
220
185
|
this.pickInvisible = false;
|
|
221
186
|
|
|
222
|
-
/**
|
|
223
|
-
* Used to draw only requested elements / indices.
|
|
224
|
-
*
|
|
225
|
-
* @property pickElementsCount
|
|
226
|
-
* @type {Number}
|
|
227
|
-
*/
|
|
228
|
-
this.pickElementsCount = null;
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* Used to draw only requested elements / indices.
|
|
232
|
-
*
|
|
233
|
-
* @property pickElementsOffset
|
|
234
|
-
* @type {Number}
|
|
235
|
-
*/
|
|
236
|
-
this.pickElementsOffset = null;
|
|
237
|
-
|
|
238
187
|
/** The current line width.
|
|
239
188
|
*
|
|
240
189
|
* @property lineWidth
|
|
@@ -246,16 +195,9 @@ class FrameContext {
|
|
|
246
195
|
* Collects info from SceneModel.drawSnapInit and SceneModel.drawSnap,
|
|
247
196
|
* which is then used in Renderer to determine snap-picking results.
|
|
248
197
|
*
|
|
249
|
-
* @type {
|
|
250
|
-
*/
|
|
251
|
-
this.snapPickLayerParams = {};
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* Collects info from SceneModel.drawSnapInit and SceneModel.drawSnap,
|
|
255
|
-
* which is then used in Renderer to determine snap-picking results.
|
|
256
|
-
* @type {number}
|
|
198
|
+
* @type {[]}
|
|
257
199
|
*/
|
|
258
|
-
this.
|
|
200
|
+
this.snapPickLayerParams = [];
|
|
259
201
|
|
|
260
202
|
/**
|
|
261
203
|
* Collects info from SceneModel.drawSnapInit and SceneModel.drawSnap,
|
|
@@ -279,26 +221,12 @@ class FrameContext {
|
|
|
279
221
|
let rtcViewMat = this._rtcViewMats[originHash];
|
|
280
222
|
if (!rtcViewMat) {
|
|
281
223
|
rtcViewMat = this._getNewMat();
|
|
282
|
-
createRTCViewMat(this.
|
|
224
|
+
createRTCViewMat(this.viewParams.viewMatrix, origin, rtcViewMat);
|
|
283
225
|
this._rtcViewMats[originHash] = rtcViewMat;
|
|
284
226
|
}
|
|
285
227
|
return rtcViewMat;
|
|
286
228
|
}
|
|
287
229
|
|
|
288
|
-
/**
|
|
289
|
-
* Get picking View RTC matrix for the given RTC center.
|
|
290
|
-
*/
|
|
291
|
-
getRTCPickViewMatrix(originHash, origin) {
|
|
292
|
-
let rtcPickViewMat = this._rtcPickViewMats[originHash];
|
|
293
|
-
if (!rtcPickViewMat) {
|
|
294
|
-
rtcPickViewMat = this._getNewMat();
|
|
295
|
-
const pickViewMat = this.pickViewMatrix || this._scene.camera.viewMatrix;
|
|
296
|
-
createRTCViewMat(pickViewMat, origin, rtcPickViewMat);
|
|
297
|
-
this._rtcPickViewMats[originHash] = rtcPickViewMat;
|
|
298
|
-
}
|
|
299
|
-
return rtcPickViewMat;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
230
|
_getNewMat() {
|
|
303
231
|
let mat = this._matPool[this._matPoolNextFreeIndex];
|
|
304
232
|
if (!mat) {
|
|
@@ -4,117 +4,65 @@
|
|
|
4
4
|
*/
|
|
5
5
|
class RenderBuffer {
|
|
6
6
|
|
|
7
|
-
constructor(
|
|
8
|
-
options = options || {};
|
|
7
|
+
constructor(gl, colorFormats, hasDepthTexture) {
|
|
9
8
|
/** @type {WebGL2RenderingContext} */
|
|
10
9
|
this.gl = gl;
|
|
11
10
|
this.allocated = false;
|
|
12
|
-
this.canvas = canvas;
|
|
13
11
|
this.buffer = null;
|
|
14
12
|
this.bound = false;
|
|
15
|
-
this.
|
|
16
|
-
this._hasDepthTexture =
|
|
13
|
+
this._colorFormats = colorFormats;
|
|
14
|
+
this._hasDepthTexture = hasDepthTexture;
|
|
17
15
|
}
|
|
18
16
|
|
|
19
17
|
setSize(size) {
|
|
20
18
|
this.size = size;
|
|
21
19
|
}
|
|
22
20
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
this.allocated = false;
|
|
27
|
-
this.bound = false;
|
|
28
|
-
}
|
|
21
|
+
bind() {
|
|
22
|
+
const width = this.size[0];
|
|
23
|
+
const height = this.size[1];
|
|
29
24
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return;
|
|
25
|
+
if (this.buffer && ((this.buffer.width !== width) || (this.buffer.height !== height))) {
|
|
26
|
+
this.buffer.cleanup();
|
|
27
|
+
this.buffer = null;
|
|
34
28
|
}
|
|
35
|
-
const gl = this.gl;
|
|
36
|
-
gl.bindFramebuffer(gl.FRAMEBUFFER, this.buffer.framebuf);
|
|
37
|
-
this.bound = true;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Create and specify a WebGL texture image.
|
|
42
|
-
*
|
|
43
|
-
* @param { number } width
|
|
44
|
-
* @param { number } height
|
|
45
|
-
* @param { GLenum } [internalformat=null]
|
|
46
|
-
*
|
|
47
|
-
* @returns { WebGLTexture }
|
|
48
|
-
*/
|
|
49
|
-
createTexture(width, height, internalformat = null) {
|
|
50
|
-
const gl = this.gl;
|
|
51
|
-
|
|
52
|
-
const colorTexture = gl.createTexture();
|
|
53
|
-
gl.bindTexture(gl.TEXTURE_2D, colorTexture);
|
|
54
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
55
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
56
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
57
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
58
29
|
|
|
59
|
-
if (
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
|
30
|
+
if (! this.buffer) {
|
|
31
|
+
this._allocateBuffer(width, height);
|
|
32
|
+
this.bound = false;
|
|
63
33
|
}
|
|
64
34
|
|
|
65
|
-
|
|
35
|
+
if (! this.bound) {
|
|
36
|
+
const gl = this.gl;
|
|
37
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, this.buffer.framebuf);
|
|
38
|
+
this.bound = true;
|
|
39
|
+
}
|
|
66
40
|
}
|
|
67
41
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
* @param {number[]} [internalformats=[]]
|
|
71
|
-
* @returns
|
|
72
|
-
*/
|
|
73
|
-
_touch(...internalformats) {
|
|
42
|
+
_allocateBuffer(width, height) {
|
|
43
|
+
const internalformats = this._colorFormats || [];
|
|
74
44
|
|
|
75
|
-
let width;
|
|
76
|
-
let height;
|
|
77
45
|
const gl = this.gl;
|
|
78
46
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
} else {
|
|
84
|
-
width = gl.drawingBufferWidth;
|
|
85
|
-
height = gl.drawingBufferHeight;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (this.buffer) {
|
|
89
|
-
|
|
90
|
-
if (this.buffer.width === width && this.buffer.height === height) {
|
|
91
|
-
return;
|
|
92
|
-
|
|
93
|
-
} else {
|
|
94
|
-
this.buffer.textures.forEach(texture => gl.deleteTexture(texture));
|
|
95
|
-
gl.deleteFramebuffer(this.buffer.framebuf);
|
|
96
|
-
gl.deleteRenderbuffer(this.buffer.renderbuf);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const colorTextures = [];
|
|
101
|
-
if (internalformats.length > 0) {
|
|
102
|
-
colorTextures.push(...internalformats.map(internalformat => this.createTexture(width, height, internalformat)));
|
|
103
|
-
} else {
|
|
104
|
-
colorTextures.push(this.createTexture(width, height));
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
let depthTexture;
|
|
108
|
-
|
|
109
|
-
if (this._hasDepthTexture) {
|
|
110
|
-
depthTexture = gl.createTexture();
|
|
111
|
-
gl.bindTexture(gl.TEXTURE_2D, depthTexture);
|
|
112
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
47
|
+
const createTexture = () => {
|
|
48
|
+
const tex = gl.createTexture();
|
|
49
|
+
gl.bindTexture(gl.TEXTURE_2D, tex);
|
|
113
50
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
51
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
114
52
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
115
53
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
116
|
-
|
|
117
|
-
}
|
|
54
|
+
return tex;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const colorTextures = ((internalformats.length > 0) ? internalformats : [ null ]).map(internalformat => {
|
|
58
|
+
const tex = createTexture();
|
|
59
|
+
if (internalformat) {
|
|
60
|
+
gl.texStorage2D(gl.TEXTURE_2D, 1, internalformat, width, height);
|
|
61
|
+
} else {
|
|
62
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
|
63
|
+
}
|
|
64
|
+
return tex;
|
|
65
|
+
});
|
|
118
66
|
|
|
119
67
|
const renderbuf = gl.createRenderbuffer();
|
|
120
68
|
gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuf);
|
|
@@ -129,7 +77,9 @@ class RenderBuffer {
|
|
|
129
77
|
gl.drawBuffers(colorTextures.map((_, i) => gl.COLOR_ATTACHMENT0 + i));
|
|
130
78
|
}
|
|
131
79
|
|
|
132
|
-
|
|
80
|
+
const depthTexture = this._hasDepthTexture && createTexture();
|
|
81
|
+
if (depthTexture) {
|
|
82
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT32F, width, height, 0, gl.DEPTH_COMPONENT, gl.FLOAT, null);
|
|
133
83
|
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthTexture, 0);
|
|
134
84
|
} else {
|
|
135
85
|
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbuf);
|
|
@@ -171,207 +121,57 @@ class RenderBuffer {
|
|
|
171
121
|
}
|
|
172
122
|
|
|
173
123
|
this.buffer = {
|
|
124
|
+
cleanup: () => {
|
|
125
|
+
colorTextures.forEach(texture => gl.deleteTexture(texture));
|
|
126
|
+
depthTexture && gl.deleteTexture(depthTexture);
|
|
127
|
+
gl.deleteFramebuffer(framebuf);
|
|
128
|
+
gl.deleteRenderbuffer(renderbuf);
|
|
129
|
+
},
|
|
174
130
|
framebuf: framebuf,
|
|
175
|
-
renderbuf: renderbuf,
|
|
176
|
-
texture: colorTextures[0],
|
|
177
|
-
textures: colorTextures,
|
|
178
|
-
depthTexture: depthTexture,
|
|
179
131
|
width: width,
|
|
180
132
|
height: height
|
|
181
133
|
};
|
|
182
134
|
|
|
183
|
-
this.
|
|
184
|
-
|
|
135
|
+
this.colorTextures = colorTextures.map(tex => ({
|
|
136
|
+
bind: function(unit) {
|
|
137
|
+
gl.activeTexture(gl["TEXTURE" + unit]);
|
|
138
|
+
gl.bindTexture(gl.TEXTURE_2D, tex);
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
}));
|
|
185
142
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
143
|
+
this.depthTexture = depthTexture && {
|
|
144
|
+
bind: function(unit) {
|
|
145
|
+
gl.activeTexture(gl["TEXTURE" + unit]);
|
|
146
|
+
gl.bindTexture(gl.TEXTURE_2D, depthTexture);
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
};
|
|
192
150
|
}
|
|
193
151
|
|
|
194
152
|
read(pickX, pickY, glFormat = null, glType = null, arrayType = Uint8Array, arrayMultiplier = 4, colorBufferIndex = 0) {
|
|
195
|
-
const x = pickX;
|
|
196
|
-
const y = this.buffer.height ? (this.buffer.height - pickY - 1) : (this.gl.drawingBufferHeight - pickY);
|
|
197
153
|
const pix = new arrayType(arrayMultiplier);
|
|
198
154
|
const gl = this.gl;
|
|
199
155
|
gl.readBuffer(gl.COLOR_ATTACHMENT0 + colorBufferIndex);
|
|
200
|
-
gl.readPixels(
|
|
156
|
+
gl.readPixels(pickX, this.buffer.height - pickY - 1, 1, 1, glFormat || gl.RGBA, glType || gl.UNSIGNED_BYTE, pix, 0);
|
|
201
157
|
return pix;
|
|
202
158
|
}
|
|
203
159
|
|
|
204
|
-
readArray(glFormat = null, glType = null, arrayType = Uint8Array, arrayMultiplier = 4, colorBufferIndex = 0) {
|
|
205
|
-
const pix = new arrayType(this.buffer.width*this.buffer.height * arrayMultiplier);
|
|
206
|
-
const gl = this.gl;
|
|
207
|
-
gl.readBuffer(gl.COLOR_ATTACHMENT0 + colorBufferIndex);
|
|
208
|
-
gl.readPixels(0, 0, this.buffer.width, this.buffer.height, glFormat || gl.RGBA, glType || gl.UNSIGNED_BYTE, pix, 0);
|
|
209
|
-
return pix;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Returns an HTMLCanvas containing the contents of the RenderBuffer as an image.
|
|
214
|
-
*
|
|
215
|
-
* - The HTMLCanvas has a CanvasRenderingContext2D.
|
|
216
|
-
* - Expects the caller to draw more things on the HTMLCanvas (annotations etc).
|
|
217
|
-
*
|
|
218
|
-
* @returns {HTMLCanvasElement}
|
|
219
|
-
*/
|
|
220
|
-
readImageAsCanvas() {
|
|
221
|
-
const gl = this.gl;
|
|
222
|
-
const imageDataCache = this._getImageDataCache();
|
|
223
|
-
const pixelData = imageDataCache.pixelData;
|
|
224
|
-
const canvas = imageDataCache.canvas;
|
|
225
|
-
const imageData = imageDataCache.imageData;
|
|
226
|
-
const context = imageDataCache.context;
|
|
227
|
-
gl.readPixels(0, 0, this.buffer.width, this.buffer.height, gl.RGBA, gl.UNSIGNED_BYTE, pixelData);
|
|
228
|
-
const width = this.buffer.width;
|
|
229
|
-
const height = this.buffer.height;
|
|
230
|
-
const halfHeight = height / 2 | 0; // the | 0 keeps the result an int
|
|
231
|
-
const bytesPerRow = width * 4;
|
|
232
|
-
const temp = new Uint8Array(width * 4);
|
|
233
|
-
for (let y = 0; y < halfHeight; ++y) {
|
|
234
|
-
const topOffset = y * bytesPerRow;
|
|
235
|
-
const bottomOffset = (height - y - 1) * bytesPerRow;
|
|
236
|
-
temp.set(pixelData.subarray(topOffset, topOffset + bytesPerRow));
|
|
237
|
-
pixelData.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow);
|
|
238
|
-
pixelData.set(temp, bottomOffset);
|
|
239
|
-
}
|
|
240
|
-
imageData.data.set(pixelData);
|
|
241
|
-
context.putImageData(imageData, 0, 0);
|
|
242
|
-
return canvas;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
readImage(params) {
|
|
246
|
-
const gl = this.gl;
|
|
247
|
-
const imageDataCache = this._getImageDataCache();
|
|
248
|
-
const pixelData = imageDataCache.pixelData;
|
|
249
|
-
const canvas = imageDataCache.canvas;
|
|
250
|
-
const imageData = imageDataCache.imageData;
|
|
251
|
-
const context = imageDataCache.context;
|
|
252
|
-
const { width, height } = this.buffer;
|
|
253
|
-
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixelData);
|
|
254
|
-
imageData.data.set(pixelData);
|
|
255
|
-
context.putImageData(imageData, 0, 0);
|
|
256
|
-
|
|
257
|
-
// flip Y
|
|
258
|
-
context.save();
|
|
259
|
-
context.globalCompositeOperation = 'copy';
|
|
260
|
-
context.scale(1, -1);
|
|
261
|
-
context.drawImage(canvas, 0, -height, width, height);
|
|
262
|
-
context.restore();
|
|
263
|
-
|
|
264
|
-
let format = params.format || "png";
|
|
265
|
-
if (format !== "jpeg" && format !== "png" && format !== "bmp") {
|
|
266
|
-
console.error("Unsupported image format: '" + format + "' - supported types are 'jpeg', 'bmp' and 'png' - defaulting to 'png'");
|
|
267
|
-
format = "png";
|
|
268
|
-
}
|
|
269
|
-
return canvas.toDataURL(`image/${format}`);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
_getImageDataCache(type = Uint8Array, multiplier = 4) {
|
|
273
|
-
|
|
274
|
-
const bufferWidth = this.buffer.width;
|
|
275
|
-
const bufferHeight = this.buffer.height;
|
|
276
|
-
|
|
277
|
-
let imageDataCache = this._imageDataCache;
|
|
278
|
-
|
|
279
|
-
if (imageDataCache) {
|
|
280
|
-
if (imageDataCache.width !== bufferWidth || imageDataCache.height !== bufferHeight) {
|
|
281
|
-
this._imageDataCache = null;
|
|
282
|
-
imageDataCache = null;
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
if (!imageDataCache) {
|
|
287
|
-
const canvas = document.createElement('canvas');
|
|
288
|
-
const context = canvas.getContext('2d');
|
|
289
|
-
canvas.width = bufferWidth;
|
|
290
|
-
canvas.height = bufferHeight;
|
|
291
|
-
imageDataCache = {
|
|
292
|
-
pixelData: new type(bufferWidth * bufferHeight * multiplier),
|
|
293
|
-
canvas: canvas,
|
|
294
|
-
context: context,
|
|
295
|
-
imageData: context.createImageData(bufferWidth, bufferHeight),
|
|
296
|
-
width: bufferWidth,
|
|
297
|
-
height: bufferHeight
|
|
298
|
-
};
|
|
299
|
-
|
|
300
|
-
this._imageDataCache = imageDataCache;
|
|
301
|
-
}
|
|
302
|
-
imageDataCache.context.resetTransform(); // Prevents strange scale-accumulation effect with html2canvas
|
|
303
|
-
return imageDataCache;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
160
|
unbind() {
|
|
307
161
|
const gl = this.gl;
|
|
308
162
|
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
309
163
|
this.bound = false;
|
|
310
164
|
}
|
|
311
165
|
|
|
312
|
-
getTexture(index = 0) {
|
|
313
|
-
const self = this;
|
|
314
|
-
return this._texture || (this._texture = {
|
|
315
|
-
renderBuffer: this,
|
|
316
|
-
bind: function (unit) {
|
|
317
|
-
if (self.buffer && self.buffer.textures[index]) {
|
|
318
|
-
self.gl.activeTexture(self.gl["TEXTURE" + unit]);
|
|
319
|
-
self.gl.bindTexture(self.gl.TEXTURE_2D, self.buffer.textures[index]);
|
|
320
|
-
return true;
|
|
321
|
-
}
|
|
322
|
-
return false;
|
|
323
|
-
},
|
|
324
|
-
unbind: function (unit) {
|
|
325
|
-
if (self.buffer && self.buffer.textures[index]) {
|
|
326
|
-
self.gl.activeTexture(self.gl["TEXTURE" + unit]);
|
|
327
|
-
self.gl.bindTexture(self.gl.TEXTURE_2D, null);
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
});
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
hasDepthTexture() {
|
|
334
|
-
return this._hasDepthTexture;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
getDepthTexture() {
|
|
338
|
-
if (!this._hasDepthTexture) {
|
|
339
|
-
return null;
|
|
340
|
-
}
|
|
341
|
-
const self = this;
|
|
342
|
-
return this._depthTexture || (this._dethTexture = {
|
|
343
|
-
renderBuffer: this,
|
|
344
|
-
bind: function (unit) {
|
|
345
|
-
if (self.buffer && self.buffer.depthTexture) {
|
|
346
|
-
self.gl.activeTexture(self.gl["TEXTURE" + unit]);
|
|
347
|
-
self.gl.bindTexture(self.gl.TEXTURE_2D, self.buffer.depthTexture);
|
|
348
|
-
return true;
|
|
349
|
-
}
|
|
350
|
-
return false;
|
|
351
|
-
},
|
|
352
|
-
unbind: function (unit) {
|
|
353
|
-
if (self.buffer && self.buffer.depthTexture) {
|
|
354
|
-
self.gl.activeTexture(self.gl["TEXTURE" + unit]);
|
|
355
|
-
self.gl.bindTexture(self.gl.TEXTURE_2D, null);
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
});
|
|
359
|
-
}
|
|
360
|
-
|
|
361
166
|
destroy() {
|
|
362
167
|
if (this.allocated) {
|
|
363
|
-
|
|
364
|
-
this.buffer.textures.forEach(texture => gl.deleteTexture(texture));
|
|
365
|
-
gl.deleteTexture(this.buffer.depthTexture);
|
|
366
|
-
gl.deleteFramebuffer(this.buffer.framebuf);
|
|
367
|
-
gl.deleteRenderbuffer(this.buffer.renderbuf);
|
|
168
|
+
this.buffer.cleanup();
|
|
368
169
|
this.allocated = false;
|
|
369
170
|
this.buffer = null;
|
|
370
171
|
this.bound = false;
|
|
371
172
|
}
|
|
372
|
-
this.
|
|
373
|
-
this.
|
|
374
|
-
this._depthTexture = null;
|
|
173
|
+
this.colorTextures = null;
|
|
174
|
+
this.depthTexture = null;
|
|
375
175
|
}
|
|
376
176
|
}
|
|
377
177
|
|