@xeokit/xeokit-sdk 2.5.2-beta-13 → 2.5.2-beta-17
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 +31 -10
- package/dist/xeokit-sdk.es.js +31 -10
- package/dist/xeokit-sdk.es5.js +68 -66
- package/dist/xeokit-sdk.min.cjs.js +1 -1
- package/dist/xeokit-sdk.min.es.js +1 -1
- package/dist/xeokit-sdk.min.es5.js +1 -1
- package/package.json +1 -1
- package/src/viewer/metadata/MetaModel.js +16 -1
- package/src/viewer/metadata/MetaScene.js +15 -9
- package/src/plugins/XKTLoaderPlugin/parsers/ParserV11.js +0 -663
- package/src/src/extras/ContextMenu/ContextMenu.js +0 -907
- package/src/src/extras/ContextMenu/index.js +0 -1
- package/src/src/extras/MarqueePicker/MarqueePicker.js +0 -352
- package/src/src/extras/MarqueePicker/MarqueePickerMouseControl.js +0 -174
- package/src/src/extras/MarqueePicker/index.js +0 -2
- package/src/src/extras/PointerLens/PointerLens.js +0 -312
- package/src/src/extras/PointerLens/index.js +0 -1
- package/src/src/extras/collision/ObjectsKdTree3.js +0 -149
- package/src/src/extras/collision/index.js +0 -1
- package/src/src/extras/index.js +0 -4
- package/src/src/index.js +0 -3
- package/src/src/plugins/AngleMeasurementsPlugin/AngleMeasurement.js +0 -731
- package/src/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsControl.js +0 -84
- package/src/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsMouseControl.js +0 -435
- package/src/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsPlugin.js +0 -406
- package/src/src/plugins/AngleMeasurementsPlugin/index.js +0 -3
- package/src/src/plugins/AnnotationsPlugin/Annotation.js +0 -368
- package/src/src/plugins/AnnotationsPlugin/AnnotationsPlugin.js +0 -583
- package/src/src/plugins/AnnotationsPlugin/index.js +0 -1
- package/src/src/plugins/AxisGizmoPlugin/AxisGizmoPlugin.js +0 -333
- package/src/src/plugins/AxisGizmoPlugin/index.js +0 -1
- package/src/src/plugins/BCFViewpointsPlugin/BCFViewpointsPlugin.js +0 -977
- package/src/src/plugins/BCFViewpointsPlugin/index.js +0 -1
- package/src/src/plugins/CityJSONLoaderPlugin/CityJSONDefaultDataSource.js +0 -29
- package/src/src/plugins/CityJSONLoaderPlugin/CityJSONLoaderPlugin.js +0 -751
- package/src/src/plugins/CityJSONLoaderPlugin/index.js +0 -1
- package/src/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurement.js +0 -963
- package/src/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsControl.js +0 -84
- package/src/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsMouseControl.js +0 -399
- package/src/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsPlugin.js +0 -505
- package/src/src/plugins/DistanceMeasurementsPlugin/index.js +0 -3
- package/src/src/plugins/FaceAlignedSectionPlanesPlugin/FaceAlignedSectionPlanesControl.js +0 -639
- package/src/src/plugins/FaceAlignedSectionPlanesPlugin/FaceAlignedSectionPlanesPlugin.js +0 -436
- package/src/src/plugins/FaceAlignedSectionPlanesPlugin/Overview.js +0 -247
- package/src/src/plugins/FaceAlignedSectionPlanesPlugin/Plane.js +0 -167
- package/src/src/plugins/FaceAlignedSectionPlanesPlugin/index.js +0 -1
- package/src/src/plugins/FastNavPlugin/FastNavPlugin.js +0 -429
- package/src/src/plugins/FastNavPlugin/index.js +0 -1
- package/src/src/plugins/GLTFLoaderPlugin/GLTFDefaultDataSource.js +0 -140
- package/src/src/plugins/GLTFLoaderPlugin/GLTFLoaderPlugin.js +0 -421
- package/src/src/plugins/GLTFLoaderPlugin/GLTFSceneModelLoader.js +0 -669
- package/src/src/plugins/GLTFLoaderPlugin/index.js +0 -2
- package/src/src/plugins/LASLoaderPlugin/LASDefaultDataSource.js +0 -58
- package/src/src/plugins/LASLoaderPlugin/LASLoaderPlugin.js +0 -563
- package/src/src/plugins/LASLoaderPlugin/index.js +0 -1
- package/src/src/plugins/LASLoaderPlugin/loadLASHeader.js +0 -183
- package/src/src/plugins/NavCubePlugin/CubeTextureCanvas.js +0 -290
- package/src/src/plugins/NavCubePlugin/NavCubePlugin.js +0 -753
- package/src/src/plugins/NavCubePlugin/index.js +0 -1
- package/src/src/plugins/OBJLoaderPlugin/OBJLoaderPlugin.js +0 -145
- package/src/src/plugins/OBJLoaderPlugin/OBJSceneGraphLoader.js +0 -777
- package/src/src/plugins/OBJLoaderPlugin/index.js +0 -1
- package/src/src/plugins/STLLoaderPlugin/STLDefaultDataSource.js +0 -33
- package/src/src/plugins/STLLoaderPlugin/STLLoaderPlugin.js +0 -274
- package/src/src/plugins/STLLoaderPlugin/STLSceneGraphLoader.js +0 -313
- package/src/src/plugins/STLLoaderPlugin/index.js +0 -2
- package/src/src/plugins/SectionPlanesPlugin/Control.js +0 -1328
- package/src/src/plugins/SectionPlanesPlugin/Overview.js +0 -249
- package/src/src/plugins/SectionPlanesPlugin/Plane.js +0 -169
- package/src/src/plugins/SectionPlanesPlugin/SectionPlanesPlugin.js +0 -404
- package/src/src/plugins/SectionPlanesPlugin/index.js +0 -1
- package/src/src/plugins/SkyboxesPlugin/SkyboxesPlugin.js +0 -134
- package/src/src/plugins/SkyboxesPlugin/index.js +0 -1
- package/src/src/plugins/StoreyViewsPlugin/Storey.js +0 -84
- package/src/src/plugins/StoreyViewsPlugin/StoreyMap.js +0 -57
- package/src/src/plugins/StoreyViewsPlugin/StoreyViewsPlugin.js +0 -773
- package/src/src/plugins/StoreyViewsPlugin/index.js +0 -1
- package/src/src/plugins/TreeViewPlugin/RenderService.js +0 -169
- package/src/src/plugins/TreeViewPlugin/TreeViewNode.js +0 -101
- package/src/src/plugins/TreeViewPlugin/TreeViewPlugin.js +0 -1370
- package/src/src/plugins/TreeViewPlugin/index.js +0 -1
- package/src/src/plugins/ViewCullPlugin/ViewCullPlugin.js +0 -295
- package/src/src/plugins/ViewCullPlugin/index.js +0 -1
- package/src/src/plugins/WebIFCLoaderPlugin/WebIFCDefaultDataSource.js +0 -58
- package/src/src/plugins/WebIFCLoaderPlugin/WebIFCLoaderPlugin.js +0 -942
- package/src/src/plugins/WebIFCLoaderPlugin/index.js +0 -1
- package/src/src/plugins/XKTLoaderPlugin/XKTDefaultDataSource.js +0 -95
- package/src/src/plugins/XKTLoaderPlugin/XKTLoaderPlugin.js +0 -1194
- package/src/src/plugins/XKTLoaderPlugin/index.js +0 -2
- package/src/src/plugins/XKTLoaderPlugin/parsers/ParserV1.js +0 -169
- package/src/src/plugins/XKTLoaderPlugin/parsers/ParserV10.js +0 -660
- package/src/src/plugins/XKTLoaderPlugin/parsers/ParserV11.js +0 -663
- package/src/src/plugins/XKTLoaderPlugin/parsers/ParserV2.js +0 -230
- package/src/src/plugins/XKTLoaderPlugin/parsers/ParserV3.js +0 -223
- package/src/src/plugins/XKTLoaderPlugin/parsers/ParserV4.js +0 -283
- package/src/src/plugins/XKTLoaderPlugin/parsers/ParserV5.js +0 -246
- package/src/src/plugins/XKTLoaderPlugin/parsers/ParserV6.js +0 -301
- package/src/src/plugins/XKTLoaderPlugin/parsers/ParserV7.js +0 -439
- package/src/src/plugins/XKTLoaderPlugin/parsers/ParserV8.js +0 -563
- package/src/src/plugins/XKTLoaderPlugin/parsers/ParserV9.js +0 -518
- package/src/src/plugins/XKTLoaderPlugin/parsers/lib/pako.js +0 -2
- package/src/src/plugins/XML3DLoaderPlugin/XML3DLoaderPlugin.js +0 -238
- package/src/src/plugins/XML3DLoaderPlugin/XML3DSceneGraphLoader.js +0 -1279
- package/src/src/plugins/XML3DLoaderPlugin/index.js +0 -1
- package/src/src/plugins/XML3DLoaderPlugin/zipjs/.jshintrc +0 -11
- package/src/src/plugins/XML3DLoaderPlugin/zipjs/deflate.js +0 -2060
- package/src/src/plugins/XML3DLoaderPlugin/zipjs/inflate.js +0 -2155
- package/src/src/plugins/XML3DLoaderPlugin/zipjs/mime-types.js +0 -1002
- package/src/src/plugins/XML3DLoaderPlugin/zipjs/pako/codecs.js +0 -64
- package/src/src/plugins/XML3DLoaderPlugin/zipjs/z-worker.js +0 -153
- package/src/src/plugins/XML3DLoaderPlugin/zipjs/zip-ext.js +0 -267
- package/src/src/plugins/XML3DLoaderPlugin/zipjs/zip-fs.js +0 -553
- package/src/src/plugins/XML3DLoaderPlugin/zipjs/zip.js +0 -991
- package/src/src/plugins/XML3DLoaderPlugin/zipjs/zlib-asm/codecs.js +0 -49
- package/src/src/plugins/index.js +0 -21
- package/src/src/plugins/lib/culling/ObjectCullStates.js +0 -208
- package/src/src/plugins/lib/earcut.js +0 -677
- package/src/src/plugins/lib/html/Dot.js +0 -179
- package/src/src/plugins/lib/html/Label.js +0 -174
- package/src/src/plugins/lib/html/Wire.js +0 -220
- package/src/src/viewer/Configs.js +0 -127
- package/src/src/viewer/Plugin.js +0 -233
- package/src/src/viewer/Viewer.js +0 -542
- package/src/src/viewer/index.js +0 -5
- package/src/src/viewer/localization/LocaleService.js +0 -475
- package/src/src/viewer/metadata/IFCObjectDefaultColors.js +0 -163
- package/src/src/viewer/metadata/IFCObjectDefaults.js +0 -17
- package/src/src/viewer/metadata/MetaModel.js +0 -414
- package/src/src/viewer/metadata/MetaObject.js +0 -223
- package/src/src/viewer/metadata/MetaScene.js +0 -336
- package/src/src/viewer/metadata/Property.js +0 -55
- package/src/src/viewer/metadata/PropertySet.js +0 -77
- package/src/src/viewer/scene/Bitmap/Bitmap.js +0 -473
- package/src/src/viewer/scene/Bitmap/index.js +0 -1
- package/src/src/viewer/scene/CameraControl/CameraControl.js +0 -1750
- package/src/src/viewer/scene/CameraControl/lib/CameraUpdater.js +0 -312
- package/src/src/viewer/scene/CameraControl/lib/controllers/PanController.js +0 -112
- package/src/src/viewer/scene/CameraControl/lib/controllers/PickController.js +0 -265
- package/src/src/viewer/scene/CameraControl/lib/controllers/PivotController.js +0 -384
- package/src/src/viewer/scene/CameraControl/lib/handlers/KeyboardAxisViewHandler.js +0 -122
- package/src/src/viewer/scene/CameraControl/lib/handlers/KeyboardPanRotateDollyHandler.js +0 -183
- package/src/src/viewer/scene/CameraControl/lib/handlers/MouseMiscHandler.js +0 -68
- package/src/src/viewer/scene/CameraControl/lib/handlers/MousePanRotateDollyHandler.js +0 -345
- package/src/src/viewer/scene/CameraControl/lib/handlers/MousePickHandler.js +0 -376
- package/src/src/viewer/scene/CameraControl/lib/handlers/TouchPanRotateAndDollyHandler.js +0 -288
- package/src/src/viewer/scene/CameraControl/lib/handlers/TouchPickHandler.js +0 -235
- package/src/src/viewer/scene/Component.js +0 -915
- package/src/src/viewer/scene/Entity.js +0 -502
- package/src/src/viewer/scene/ImagePlane/ImagePlane.js +0 -570
- package/src/src/viewer/scene/ImagePlane/index.js +0 -1
- package/src/src/viewer/scene/LineSet/LineSet.js +0 -163
- package/src/src/viewer/scene/LineSet/index.js +0 -1
- package/src/src/viewer/scene/camera/Camera.js +0 -912
- package/src/src/viewer/scene/camera/CameraFlightAnimation.js +0 -669
- package/src/src/viewer/scene/camera/CameraPath.js +0 -194
- package/src/src/viewer/scene/camera/CameraPathAnimation.js +0 -326
- package/src/src/viewer/scene/camera/CustomProjection.js +0 -149
- package/src/src/viewer/scene/camera/Frustum.js +0 -316
- package/src/src/viewer/scene/camera/Ortho.js +0 -286
- package/src/src/viewer/scene/camera/Perspective.js +0 -304
- package/src/src/viewer/scene/camera/index.js +0 -2
- package/src/src/viewer/scene/canvas/Canvas.js +0 -490
- package/src/src/viewer/scene/canvas/Spinner.js +0 -323
- package/src/src/viewer/scene/constants/constants.js +0 -371
- package/src/src/viewer/scene/core.js +0 -268
- package/src/src/viewer/scene/geometry/Geometry.js +0 -33
- package/src/src/viewer/scene/geometry/ReadableGeometry.js +0 -682
- package/src/src/viewer/scene/geometry/VBOGeometry.js +0 -319
- package/src/src/viewer/scene/geometry/builders/buildBoxGeometry.js +0 -238
- package/src/src/viewer/scene/geometry/builders/buildBoxLinesGeometry.js +0 -106
- package/src/src/viewer/scene/geometry/builders/buildCylinderGeometry.js +0 -271
- package/src/src/viewer/scene/geometry/builders/buildGridGeometry.js +0 -102
- package/src/src/viewer/scene/geometry/builders/buildPlaneGeometry.js +0 -168
- package/src/src/viewer/scene/geometry/builders/buildSphereGeometry.js +0 -161
- package/src/src/viewer/scene/geometry/builders/buildTorusGeometry.js +0 -172
- package/src/src/viewer/scene/geometry/builders/buildVectorTextGeometry.js +0 -1721
- package/src/src/viewer/scene/geometry/builders/index.js +0 -8
- package/src/src/viewer/scene/geometry/index.js +0 -4
- package/src/src/viewer/scene/geometry/loaders/index.js +0 -2
- package/src/src/viewer/scene/geometry/loaders/load3DSGeometry.js +0 -103
- package/src/src/viewer/scene/geometry/loaders/loadOBJGeometry.js +0 -130
- package/src/src/viewer/scene/index.js +0 -21
- package/src/src/viewer/scene/input/Input.js +0 -1333
- package/src/src/viewer/scene/libs/k3d.js +0 -1032
- package/src/src/viewer/scene/lights/AmbientLight.js +0 -175
- package/src/src/viewer/scene/lights/CubeTexture.js +0 -156
- package/src/src/viewer/scene/lights/DirLight.js +0 -314
- package/src/src/viewer/scene/lights/Light.js +0 -29
- package/src/src/viewer/scene/lights/LightMap.js +0 -77
- package/src/src/viewer/scene/lights/PointLight.js +0 -395
- package/src/src/viewer/scene/lights/ReflectionMap.js +0 -79
- package/src/src/viewer/scene/lights/Shadow.js +0 -138
- package/src/src/viewer/scene/lights/index.js +0 -5
- package/src/src/viewer/scene/marker/Marker.js +0 -383
- package/src/src/viewer/scene/marker/SpriteMarker.js +0 -356
- package/src/src/viewer/scene/marker/index.js +0 -2
- package/src/src/viewer/scene/materials/EdgeMaterial.js +0 -359
- package/src/src/viewer/scene/materials/EmphasisMaterial.js +0 -613
- package/src/src/viewer/scene/materials/Fresnel.js +0 -222
- package/src/src/viewer/scene/materials/LambertMaterial.js +0 -378
- package/src/src/viewer/scene/materials/LinesMaterial.js +0 -169
- package/src/src/viewer/scene/materials/Material.js +0 -39
- package/src/src/viewer/scene/materials/MetallicMaterial.js +0 -820
- package/src/src/viewer/scene/materials/PhongMaterial.js +0 -860
- package/src/src/viewer/scene/materials/PointsMaterial.js +0 -409
- package/src/src/viewer/scene/materials/SpecularMaterial.js +0 -807
- package/src/src/viewer/scene/materials/Texture.js +0 -513
- package/src/src/viewer/scene/materials/index.js +0 -8
- package/src/src/viewer/scene/math/Frustum.js +0 -118
- package/src/src/viewer/scene/math/buildEdgeIndices.js +0 -162
- package/src/src/viewer/scene/math/geometryCompressionUtils.js +0 -365
- package/src/src/viewer/scene/math/index.js +0 -3
- package/src/src/viewer/scene/math/math.js +0 -5386
- package/src/src/viewer/scene/math/rtcCoords.js +0 -139
- package/src/src/viewer/scene/mementos/CameraMemento.js +0 -200
- package/src/src/viewer/scene/mementos/ModelMemento.js +0 -263
- package/src/src/viewer/scene/mementos/ObjectsMemento.js +0 -259
- package/src/src/viewer/scene/mementos/index.js +0 -3
- package/src/src/viewer/scene/mesh/Mesh.js +0 -2202
- package/src/src/viewer/scene/mesh/draw/DrawRenderer.js +0 -996
- package/src/src/viewer/scene/mesh/draw/DrawShaderSource.js +0 -1570
- package/src/src/viewer/scene/mesh/emphasis/EmphasisEdgesRenderer.js +0 -259
- package/src/src/viewer/scene/mesh/emphasis/EmphasisEdgesShaderSource.js +0 -159
- package/src/src/viewer/scene/mesh/emphasis/EmphasisFillRenderer.js +0 -286
- package/src/src/viewer/scene/mesh/emphasis/EmphasisFillShaderSource.js +0 -262
- package/src/src/viewer/scene/mesh/index.js +0 -1
- package/src/src/viewer/scene/mesh/occlusion/OcclusionRenderer.js +0 -217
- package/src/src/viewer/scene/mesh/occlusion/OcclusionShaderSource.js +0 -157
- package/src/src/viewer/scene/mesh/pick/PickMeshRenderer.js +0 -223
- package/src/src/viewer/scene/mesh/pick/PickMeshShaderSource.js +0 -151
- package/src/src/viewer/scene/mesh/pick/PickTriangleRenderer.js +0 -200
- package/src/src/viewer/scene/mesh/pick/PickTriangleShaderSource.js +0 -124
- package/src/src/viewer/scene/mesh/shadow/ShadowRenderer.js +0 -214
- package/src/src/viewer/scene/mesh/shadow/ShadowShaderSource.js +0 -98
- package/src/src/viewer/scene/metriqs/Metriqs.js +0 -259
- package/src/src/viewer/scene/model/ENTITY_FLAGS.js +0 -21
- package/src/src/viewer/scene/model/PerformanceModel.js +0 -26
- package/src/src/viewer/scene/model/RENDER_PASSES.js +0 -34
- package/src/src/viewer/scene/model/SceneModel.js +0 -4018
- package/src/src/viewer/scene/model/SceneModelEntity.js +0 -715
- package/src/src/viewer/scene/model/SceneModelMesh.js +0 -341
- package/src/src/viewer/scene/model/SceneModelTexture.js +0 -38
- package/src/src/viewer/scene/model/SceneModelTextureSet.js +0 -59
- package/src/src/viewer/scene/model/SceneModelTransform.js +0 -404
- package/src/src/viewer/scene/model/VBOSceneModel.js +0 -26
- package/src/src/viewer/scene/model/calculateUniquePositions.js +0 -126
- package/src/src/viewer/scene/model/compression.js +0 -227
- package/src/src/viewer/scene/model/dtx/BindableDataTexture.js +0 -31
- package/src/src/viewer/scene/model/dtx/lines/DTXLinesBuffer.js +0 -27
- package/src/src/viewer/scene/model/dtx/lines/DTXLinesLayer.js +0 -891
- package/src/src/viewer/scene/model/dtx/lines/DTXLinesState.js +0 -46
- package/src/src/viewer/scene/model/dtx/lines/DTXLinesTextureFactory.js +0 -411
- package/src/src/viewer/scene/model/dtx/lines/dataTextureRamStats.js +0 -49
- package/src/src/viewer/scene/model/dtx/lines/rebucketPositions.js +0 -208
- package/src/src/viewer/scene/model/dtx/lines/renderers/DTXLinesColorRenderer.js +0 -389
- package/src/src/viewer/scene/model/dtx/lines/renderers/DTXLinesRenderers.js +0 -65
- package/src/src/viewer/scene/model/dtx/triangles/DTXTrianglesLayer.js +0 -1322
- package/src/src/viewer/scene/model/dtx/triangles/lib/DTXTrianglesBuffer.js +0 -46
- package/src/src/viewer/scene/model/dtx/triangles/lib/DTXTrianglesState.js +0 -250
- package/src/src/viewer/scene/model/dtx/triangles/lib/DTXTrianglesTextureFactory.js +0 -518
- package/src/src/viewer/scene/model/dtx/triangles/lib/dataTextureRamStats.js +0 -54
- package/src/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesColorRenderer.js +0 -619
- package/src/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesDepthRenderer.js +0 -464
- package/src/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesEdgesColorRenderer.js +0 -414
- package/src/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesEdgesRenderer.js +0 -422
- package/src/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesNormalsRenderer.js +0 -345
- package/src/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesOcclusionRenderer.js +0 -436
- package/src/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickDepthRenderer.js +0 -462
- package/src/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickMeshRenderer.js +0 -436
- package/src/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickNormalsFlatRenderer.js +0 -455
- package/src/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickNormalsRenderer.js +0 -440
- package/src/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesRenderers.js +0 -307
- package/src/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSilhouetteRenderer.js +0 -465
- package/src/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSnapInitRenderer.js +0 -466
- package/src/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSnapRenderer.js +0 -427
- package/src/src/viewer/scene/model/index.js +0 -5
- package/src/src/viewer/scene/model/rebucketPositions.js +0 -354
- package/src/src/viewer/scene/model/vbo/ScratchMemory.js +0 -63
- package/src/src/viewer/scene/model/vbo/VBORenderer.js +0 -646
- package/src/src/viewer/scene/model/vbo/batching/lines/VBOBatchingLinesLayer.js +0 -699
- package/src/src/viewer/scene/model/vbo/batching/lines/lib/VBOBatchingLinesBuffer.js +0 -19
- package/src/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLineSnapInitRenderer.js +0 -316
- package/src/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesColorRenderer.js +0 -114
- package/src/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesRenderers.js +0 -99
- package/src/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesSilhouetteRenderer.js +0 -124
- package/src/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesSnapInitRenderer.js +0 -311
- package/src/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesSnapRenderer.js +0 -309
- package/src/src/viewer/scene/model/vbo/batching/lines/renderers/VBOSceneModelLineBatchingRenderer.js +0 -24
- package/src/src/viewer/scene/model/vbo/batching/points/VBOBatchingPointsBuffer.js +0 -20
- package/src/src/viewer/scene/model/vbo/batching/points/VBOBatchingPointsLayer.js +0 -718
- package/src/src/viewer/scene/model/vbo/batching/points/VBOBatchingPointsRenderer.js +0 -24
- package/src/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsColorRenderer.js +0 -168
- package/src/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsOcclusionRenderer.js +0 -136
- package/src/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsPickDepthRenderer.js +0 -156
- package/src/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsPickMeshRenderer.js +0 -148
- package/src/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsRenderers.js +0 -144
- package/src/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsShadowRenderer.js +0 -107
- package/src/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsSilhouetteRenderer.js +0 -146
- package/src/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsSnapInitRenderer.js +0 -309
- package/src/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsSnapRenderer.js +0 -303
- package/src/src/viewer/scene/model/vbo/batching/triangles/VBOBatchingTrianglesBuffer.js +0 -24
- package/src/src/viewer/scene/model/vbo/batching/triangles/VBOBatchingTrianglesLayer.js +0 -1257
- package/src/src/viewer/scene/model/vbo/batching/triangles/renderers/EdgesColorRenderer.js +0 -131
- package/src/src/viewer/scene/model/vbo/batching/triangles/renderers/EdgesEmphasisRenderer.js +0 -135
- package/src/src/viewer/scene/model/vbo/batching/triangles/renderers/EdgesRenderer.js +0 -12
- package/src/src/viewer/scene/model/vbo/batching/triangles/renderers/Renderers.js +0 -375
- package/src/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesBatchingRenderer.js +0 -34
- package/src/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesColorRenderer.js +0 -238
- package/src/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesColorTextureRenderer.js +0 -270
- package/src/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesDepthRenderer.js +0 -126
- package/src/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesFlatColorRenderer.js +0 -235
- package/src/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesNormalsRenderer.js +0 -139
- package/src/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesOcclusionRenderer.js +0 -125
- package/src/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPBRRenderer.js +0 -561
- package/src/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPickDepthRenderer.js +0 -144
- package/src/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPickMeshRenderer.js +0 -130
- package/src/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPickNormalsFlatRenderer.js +0 -121
- package/src/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPickNormalsRenderer.js +0 -131
- package/src/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesShadowRenderer.js +0 -107
- package/src/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesSilhouetteRenderer.js +0 -136
- package/src/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesSnapInitRenderer.js +0 -311
- package/src/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesSnapRenderer.js +0 -308
- package/src/src/viewer/scene/model/vbo/float16.js +0 -760
- package/src/src/viewer/scene/model/vbo/instancing/lines/VBOInstancingLinesLayer.js +0 -704
- package/src/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesColorRenderer.js +0 -148
- package/src/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesRenderer.js +0 -26
- package/src/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesRenderers.js +0 -139
- package/src/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesSilhouetteRenderer.js +0 -127
- package/src/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesSnapInitRenderer.js +0 -331
- package/src/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesSnapRenderer.js +0 -316
- package/src/src/viewer/scene/model/vbo/instancing/points/VBOInstancingPointsLayer.js +0 -728
- package/src/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsColorRenderer.js +0 -174
- package/src/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsDepthRenderer.js +0 -156
- package/src/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsOcclusionRenderer.js +0 -149
- package/src/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsPickDepthRenderer.js +0 -170
- package/src/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsPickMeshRenderer.js +0 -152
- package/src/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsRenderer.js +0 -26
- package/src/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsRenderers.js +0 -174
- package/src/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsShadowRenderer.js +0 -119
- package/src/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsSilhouetteRenderer.js +0 -154
- package/src/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsSnapInitRenderer.js +0 -330
- package/src/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsSnapRenderer.js +0 -311
- package/src/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingTrianglesRenderer.js +0 -150
- package/src/src/viewer/scene/model/vbo/instancing/triangles/VBOInstancingTrianglesLayer.js +0 -1190
- package/src/src/viewer/scene/model/vbo/instancing/triangles/renderers/EdgesColorRenderer.js +0 -136
- package/src/src/viewer/scene/model/vbo/instancing/triangles/renderers/EdgesEmphasisRenderer.js +0 -137
- package/src/src/viewer/scene/model/vbo/instancing/triangles/renderers/EdgesRenderer.js +0 -12
- package/src/src/viewer/scene/model/vbo/instancing/triangles/renderers/Renderers.js +0 -376
- package/src/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesColorRenderer.js +0 -253
- package/src/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesColorTextureRenderer.js +0 -278
- package/src/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesDepthRenderer.js +0 -126
- package/src/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesFlatColorRenderer.js +0 -244
- package/src/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesFlatNormalsRenderer.js +0 -130
- package/src/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesInstancingRenderer.js +0 -29
- package/src/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesNormalsRenderer.js +0 -138
- package/src/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesOcclusionRenderer.js +0 -128
- package/src/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPBRRenderer.js +0 -561
- package/src/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPickDepthRenderer.js +0 -149
- package/src/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPickMeshRenderer.js +0 -136
- package/src/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPickNormalsFlatRenderer.js +0 -130
- package/src/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPickNormalsRenderer.js +0 -145
- package/src/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesShadowRenderer.js +0 -113
- package/src/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesSilhouetteRenderer.js +0 -139
- package/src/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesSnapInitRenderer.js +0 -342
- package/src/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesSnapRenderer.js +0 -325
- package/src/src/viewer/scene/nodes/Node.js +0 -1383
- package/src/src/viewer/scene/nodes/index.js +0 -1
- package/src/src/viewer/scene/paths/CubicBezierCurve.js +0 -194
- package/src/src/viewer/scene/paths/Curve.js +0 -183
- package/src/src/viewer/scene/paths/Path.js +0 -239
- package/src/src/viewer/scene/paths/QuadraticBezierCurve.js +0 -161
- package/src/src/viewer/scene/paths/SplineCurve.js +0 -133
- package/src/src/viewer/scene/paths/index.js +0 -5
- package/src/src/viewer/scene/postfx/SAO.js +0 -543
- package/src/src/viewer/scene/scene/Scene.js +0 -2802
- package/src/src/viewer/scene/sectionPlane/SectionPlane.js +0 -198
- package/src/src/viewer/scene/sectionPlane/SectionPlaneCache.js +0 -101
- package/src/src/viewer/scene/sectionPlane/index.js +0 -1
- package/src/src/viewer/scene/skybox/Skybox.js +0 -123
- package/src/src/viewer/scene/skybox/index.js +0 -1
- package/src/src/viewer/scene/stats.js +0 -44
- package/src/src/viewer/scene/utils/Cache.js +0 -29
- package/src/src/viewer/scene/utils/FileLoader.js +0 -161
- package/src/src/viewer/scene/utils/Loader.js +0 -55
- package/src/src/viewer/scene/utils/LoadingManager.js +0 -86
- package/src/src/viewer/scene/utils/Map.js +0 -45
- package/src/src/viewer/scene/utils/Queue.js +0 -56
- package/src/src/viewer/scene/utils/WorkerPool.js +0 -73
- package/src/src/viewer/scene/utils/index.js +0 -6
- package/src/src/viewer/scene/utils/textureTranscoders/KTX2TextureTranscoder/KTX2TextureTranscoder.js +0 -650
- package/src/src/viewer/scene/utils/textureTranscoders/KTX2TextureTranscoder/index.js +0 -1
- package/src/src/viewer/scene/utils/textureTranscoders/TextureTranscoder.js +0 -31
- package/src/src/viewer/scene/utils/textureTranscoders/index.js +0 -2
- package/src/src/viewer/scene/utils.js +0 -453
- package/src/src/viewer/scene/viewport/Viewport.js +0 -212
- package/src/src/viewer/scene/webgl/ArrayBuf.js +0 -121
- package/src/src/viewer/scene/webgl/Attribute.js +0 -23
- package/src/src/viewer/scene/webgl/Drawable.js +0 -270
- package/src/src/viewer/scene/webgl/FrameContext.js +0 -313
- package/src/src/viewer/scene/webgl/PickResult.js +0 -364
- package/src/src/viewer/scene/webgl/Pickable.js +0 -69
- package/src/src/viewer/scene/webgl/Program.js +0 -181
- package/src/src/viewer/scene/webgl/RenderBuffer.js +0 -378
- package/src/src/viewer/scene/webgl/RenderBufferManager.js +0 -34
- package/src/src/viewer/scene/webgl/RenderFlags.js +0 -203
- package/src/src/viewer/scene/webgl/RenderState.js +0 -40
- package/src/src/viewer/scene/webgl/Renderer.js +0 -1781
- package/src/src/viewer/scene/webgl/Sampler.js +0 -18
- package/src/src/viewer/scene/webgl/Shader.js +0 -49
- package/src/src/viewer/scene/webgl/Texture2D.js +0 -442
- package/src/src/viewer/scene/webgl/convertConstant.js +0 -244
- package/src/src/viewer/scene/webgl/getExtension.js +0 -32
- package/src/src/viewer/scene/webgl/occlusion/OcclusionLayer.js +0 -214
- package/src/src/viewer/scene/webgl/occlusion/OcclusionTester.js +0 -426
- package/src/src/viewer/scene/webgl/sao/SAODepthLimitedBlurRenderer.js +0 -324
- package/src/src/viewer/scene/webgl/sao/SAOOcclusionRenderer.js +0 -376
- package/src/src/viewer/scene/webgl/webglEnums.js +0 -61
- package/src/src/viewer/scene/webglInfo.js +0 -47
|
@@ -1,4018 +0,0 @@
|
|
|
1
|
-
import {Component} from "../Component.js";
|
|
2
|
-
import {math} from "../math/math.js";
|
|
3
|
-
import {buildEdgeIndices} from '../math/buildEdgeIndices.js';
|
|
4
|
-
import {SceneModelMesh} from './SceneModelMesh.js';
|
|
5
|
-
import {getScratchMemory, putScratchMemory} from "./vbo/ScratchMemory.js";
|
|
6
|
-
import {VBOBatchingTrianglesLayer} from './vbo/batching/triangles/VBOBatchingTrianglesLayer.js';
|
|
7
|
-
import {VBOInstancingTrianglesLayer} from './vbo/instancing/triangles/VBOInstancingTrianglesLayer.js';
|
|
8
|
-
import {VBOBatchingLinesLayer} from './vbo/batching/lines/VBOBatchingLinesLayer.js';
|
|
9
|
-
import {VBOInstancingLinesLayer} from './vbo/instancing/lines/VBOInstancingLinesLayer.js';
|
|
10
|
-
import {VBOBatchingPointsLayer} from './vbo/batching/points/VBOBatchingPointsLayer.js';
|
|
11
|
-
import {VBOInstancingPointsLayer} from './vbo/instancing/points/VBOInstancingPointsLayer.js';
|
|
12
|
-
import {DTXLinesLayer} from "./dtx/lines/DTXLinesLayer.js";
|
|
13
|
-
import {DTXTrianglesLayer} from "./dtx/triangles/DTXTrianglesLayer.js";
|
|
14
|
-
import {ENTITY_FLAGS} from './ENTITY_FLAGS.js';
|
|
15
|
-
import {RenderFlags} from "../webgl/RenderFlags.js";
|
|
16
|
-
import {worldToRTCPositions} from "../math/rtcCoords.js";
|
|
17
|
-
import {SceneModelTextureSet} from "./SceneModelTextureSet.js";
|
|
18
|
-
import {SceneModelTexture} from "./SceneModelTexture.js";
|
|
19
|
-
import {Texture2D} from "../webgl/Texture2D.js";
|
|
20
|
-
import {utils} from "../utils.js";
|
|
21
|
-
import {getKTX2TextureTranscoder} from "../utils/textureTranscoders/KTX2TextureTranscoder/KTX2TextureTranscoder.js";
|
|
22
|
-
import {
|
|
23
|
-
ClampToEdgeWrapping,
|
|
24
|
-
LinearEncoding,
|
|
25
|
-
LinearFilter,
|
|
26
|
-
LinearMipmapLinearFilter,
|
|
27
|
-
LinearMipMapNearestFilter,
|
|
28
|
-
MirroredRepeatWrapping,
|
|
29
|
-
NearestFilter,
|
|
30
|
-
NearestMipMapLinearFilter,
|
|
31
|
-
NearestMipMapNearestFilter,
|
|
32
|
-
RepeatWrapping,
|
|
33
|
-
sRGBEncoding
|
|
34
|
-
} from "../constants/constants.js";
|
|
35
|
-
import {createPositionsDecodeMatrix, quantizePositions} from "./compression.js";
|
|
36
|
-
import {uniquifyPositions} from "./calculateUniquePositions.js";
|
|
37
|
-
import {rebucketPositions} from "./rebucketPositions.js";
|
|
38
|
-
import {SceneModelEntity} from "./SceneModelEntity.js";
|
|
39
|
-
import {geometryCompressionUtils} from "../math/geometryCompressionUtils.js";
|
|
40
|
-
import {SceneModelTransform} from "./SceneModelTransform.js";
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const tempVec3a = math.vec3();
|
|
44
|
-
|
|
45
|
-
const tempOBB3 = math.OBB3();
|
|
46
|
-
|
|
47
|
-
const DEFAULT_SCALE = math.vec3([1, 1, 1]);
|
|
48
|
-
const DEFAULT_POSITION = math.vec3([0, 0, 0]);
|
|
49
|
-
const DEFAULT_ROTATION = math.vec3([0, 0, 0]);
|
|
50
|
-
const DEFAULT_QUATERNION = math.identityQuaternion();
|
|
51
|
-
const DEFAULT_MATRIX = math.identityMat4();
|
|
52
|
-
|
|
53
|
-
const DEFAULT_COLOR_TEXTURE_ID = "defaultColorTexture";
|
|
54
|
-
const DEFAULT_METAL_ROUGH_TEXTURE_ID = "defaultMetalRoughTexture";
|
|
55
|
-
const DEFAULT_NORMALS_TEXTURE_ID = "defaultNormalsTexture";
|
|
56
|
-
const DEFAULT_EMISSIVE_TEXTURE_ID = "defaultEmissiveTexture";
|
|
57
|
-
const DEFAULT_OCCLUSION_TEXTURE_ID = "defaultOcclusionTexture";
|
|
58
|
-
const DEFAULT_TEXTURE_SET_ID = "defaultTextureSet";
|
|
59
|
-
|
|
60
|
-
const defaultCompressedColor = new Uint8Array([255, 255, 255]);
|
|
61
|
-
|
|
62
|
-
const VBO_INSTANCED = 0;
|
|
63
|
-
const VBO_BATCHED = 1;
|
|
64
|
-
const DTX = 2;
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* @desc A high-performance model representation for efficient rendering and low memory usage.
|
|
68
|
-
*
|
|
69
|
-
* # Examples
|
|
70
|
-
*
|
|
71
|
-
* Internally, SceneModel uses a combination of several different techniques to render and represent
|
|
72
|
-
* the different parts of a typical model. Each of the live examples at these links is designed to "unit test" one of these
|
|
73
|
-
* techniques, in isolation. If some bug occurs in SceneModel, we use these tests to debug, but they also
|
|
74
|
-
* serve to demonstrate how to use the capabilities of SceneModel programmatically.
|
|
75
|
-
*
|
|
76
|
-
* * [Loading building models into SceneModels](/examples/buildings)
|
|
77
|
-
* * [Loading city models into SceneModels](/examples/cities)
|
|
78
|
-
* * [Loading LiDAR scans into SceneModels](/examples/lidar)
|
|
79
|
-
* * [Loading CAD models into SceneModels](/examples/cad)
|
|
80
|
-
* * [SceneModel feature tests](/examples/scenemodel)
|
|
81
|
-
*
|
|
82
|
-
* # Overview
|
|
83
|
-
*
|
|
84
|
-
* While xeokit's standard [scene graph](https://github.com/xeokit/xeokit-sdk/wiki/Scene-Graphs) is great for gizmos and medium-sized models, it doesn't scale up to millions of objects in terms of memory and rendering efficiency.
|
|
85
|
-
*
|
|
86
|
-
* For huge models, we have the ````SceneModel```` representation, which is optimized to pack large amounts of geometry into memory and render it efficiently using WebGL.
|
|
87
|
-
*
|
|
88
|
-
* ````SceneModel```` is the default model representation loaded by (at least) {@link GLTFLoaderPlugin}, {@link XKTLoaderPlugin} and {@link WebIFCLoaderPlugin}.
|
|
89
|
-
*
|
|
90
|
-
* In this tutorial you'll learn how to use ````SceneModel```` to create high-detail content programmatically. Ordinarily you'd be learning about ````SceneModel```` if you were writing your own model loader plugins.
|
|
91
|
-
*
|
|
92
|
-
* # Contents
|
|
93
|
-
*
|
|
94
|
-
* - [SceneModel](#DataTextureSceneModel)
|
|
95
|
-
* - [GPU-Resident Geometry](#gpu-resident-geometry)
|
|
96
|
-
* - [Picking](#picking)
|
|
97
|
-
* - [Example 1: Geometry Instancing](#example-1--geometry-instancing)
|
|
98
|
-
* - [Finalizing a SceneModel](#finalizing-a-DataTextureSceneModel)
|
|
99
|
-
* - [Finding Entities](#finding-entities)
|
|
100
|
-
* - [Example 2: Geometry Batching](#example-2--geometry-batching)
|
|
101
|
-
* - [Classifying with Metadata](#classifying-with-metadata)
|
|
102
|
-
* - [Querying Metadata](#querying-metadata)
|
|
103
|
-
* - [Metadata Structure](#metadata-structure)
|
|
104
|
-
* - [RTC Coordinates](#rtc-coordinates-for-double-precision)
|
|
105
|
-
* - [Example 3: RTC Coordinates with Geometry Instancing](#example-2--rtc-coordinates-with-geometry-instancing)
|
|
106
|
-
* - [Example 4: RTC Coordinates with Geometry Batching](#example-2--rtc-coordinates-with-geometry-batching)
|
|
107
|
-
*
|
|
108
|
-
* ## SceneModel
|
|
109
|
-
*
|
|
110
|
-
* ````SceneModel```` uses two rendering techniques internally:
|
|
111
|
-
*
|
|
112
|
-
* 1. ***Geometry batching*** for unique geometries, combining those into a single WebGL geometry buffer, to render in one draw call, and
|
|
113
|
-
* 2. ***geometry instancing*** for geometries that are shared by multiple meshes, rendering all instances of each shared geometry in one draw call.
|
|
114
|
-
*
|
|
115
|
-
* <br>
|
|
116
|
-
* These techniques come with certain limitations:
|
|
117
|
-
*
|
|
118
|
-
* * Non-realistic rendering - while scene graphs can use xeokit's full set of material workflows, ````SceneModel```` uses simple Lambertian shading without textures.
|
|
119
|
-
* * Static transforms - transforms within a ````SceneModel```` are static and cannot be dynamically translated, rotated and scaled the way {@link Node}s and {@link Mesh}es in scene graphs can.
|
|
120
|
-
* * Immutable model representation - while scene graph {@link Node}s and
|
|
121
|
-
* {@link Mesh}es can be dynamically plugged together, ````SceneModel```` is immutable,
|
|
122
|
-
* since it packs its geometries into buffers and instanced arrays.
|
|
123
|
-
*
|
|
124
|
-
* ````SceneModel````'s API allows us to exploit batching and instancing, while exposing its elements as
|
|
125
|
-
* abstract {@link Entity} types.
|
|
126
|
-
*
|
|
127
|
-
* {@link Entity} is the abstract base class for
|
|
128
|
-
* the various xeokit components that represent models, objects, or anonymous visible elements. An Entity has a unique ID and can be
|
|
129
|
-
* individually shown, hidden, selected, highlighted, ghosted, culled, picked and clipped, and has its own World-space boundary.
|
|
130
|
-
*
|
|
131
|
-
* * A ````SceneModel```` is an {@link Entity} that represents a model.
|
|
132
|
-
* * A ````SceneModel```` represents each of its objects with an {@link Entity}.
|
|
133
|
-
* * Each {@link Entity} has one or more meshes that define its shape.
|
|
134
|
-
* * Each mesh has either its own unique geometry, or shares a geometry with other meshes.
|
|
135
|
-
*
|
|
136
|
-
* ## GPU-Resident Geometry
|
|
137
|
-
*
|
|
138
|
-
* For a low memory footprint, ````SceneModel```` stores its geometries in GPU memory only, compressed (quantized) as integers. Unfortunately, GPU-resident geometry is
|
|
139
|
-
* not readable by JavaScript.
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
* ## Example 1: Geometry Instancing
|
|
143
|
-
*
|
|
144
|
-
* In the example below, we'll use a ````SceneModel````
|
|
145
|
-
* to build a simple table model using geometry instancing.
|
|
146
|
-
*
|
|
147
|
-
* We'll start by adding a reusable box-shaped geometry to our ````SceneModel````.
|
|
148
|
-
*
|
|
149
|
-
* Then, for each object in our model we'll add an {@link Entity}
|
|
150
|
-
* that has a mesh that instances our box geometry, transforming and coloring the instance.
|
|
151
|
-
*
|
|
152
|
-
* [](https://xeokit.github.io/xeokit-sdk/examples/#sceneRepresentation_SceneModel_instancing)
|
|
153
|
-
*
|
|
154
|
-
* ````javascript
|
|
155
|
-
* import {Viewer, SceneModel} from "xeokit-sdk.es.js";
|
|
156
|
-
*
|
|
157
|
-
* const viewer = new Viewer({
|
|
158
|
-
* canvasId: "myCanvas",
|
|
159
|
-
* transparent: true
|
|
160
|
-
* });
|
|
161
|
-
*
|
|
162
|
-
* viewer.scene.camera.eye = [-21.80, 4.01, 6.56];
|
|
163
|
-
* viewer.scene.camera.look = [0, -5.75, 0];
|
|
164
|
-
* viewer.scene.camera.up = [0.37, 0.91, -0.11];
|
|
165
|
-
*
|
|
166
|
-
* // Build a SceneModel representing a table
|
|
167
|
-
* // with four legs, using geometry instancing
|
|
168
|
-
*
|
|
169
|
-
* const sceneModel = new SceneModel(viewer.scene, {
|
|
170
|
-
* id: "table",
|
|
171
|
-
* isModel: true, // <--- Registers SceneModel in viewer.scene.models
|
|
172
|
-
* position: [0, 0, 0],
|
|
173
|
-
* scale: [1, 1, 1],
|
|
174
|
-
* rotation: [0, 0, 0]
|
|
175
|
-
* });
|
|
176
|
-
*
|
|
177
|
-
* // Create a reusable geometry within the SceneModel
|
|
178
|
-
* // We'll instance this geometry by five meshes
|
|
179
|
-
*
|
|
180
|
-
* sceneModel.createGeometry({
|
|
181
|
-
*
|
|
182
|
-
* id: "myBoxGeometry",
|
|
183
|
-
*
|
|
184
|
-
* // The primitive type - allowed values are "points", "lines" and "triangles".
|
|
185
|
-
* // See the OpenGL/WebGL specification docs
|
|
186
|
-
* // for how the coordinate arrays are supposed to be laid out.
|
|
187
|
-
* primitive: "triangles",
|
|
188
|
-
*
|
|
189
|
-
* // The vertices - eight for our cube, each
|
|
190
|
-
* // one spanning three array elements for X,Y and Z
|
|
191
|
-
* positions: [
|
|
192
|
-
* 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, // v0-v1-v2-v3 front
|
|
193
|
-
* 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, // v0-v3-v4-v1 right
|
|
194
|
-
* 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, // v0-v1-v6-v1 top
|
|
195
|
-
* -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, // v1-v6-v7-v2 left
|
|
196
|
-
* -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, // v7-v4-v3-v2 bottom
|
|
197
|
-
* 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1 // v4-v7-v6-v1 back
|
|
198
|
-
* ],
|
|
199
|
-
*
|
|
200
|
-
* // Normal vectors, one for each vertex
|
|
201
|
-
* normals: [
|
|
202
|
-
* 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // v0-v1-v2-v3 front
|
|
203
|
-
* 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0-v3-v4-v5 right
|
|
204
|
-
* 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, // v0-v5-v6-v1 top
|
|
205
|
-
* -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, // v1-v6-v7-v2 left
|
|
206
|
-
* 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, // v7-v4-v3-v2 bottom
|
|
207
|
-
* 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1 // v4-v7-v6-v5 back
|
|
208
|
-
* ],
|
|
209
|
-
*
|
|
210
|
-
* // Indices - these organise the positions and and normals
|
|
211
|
-
* // into geometric primitives in accordance with the "primitive" parameter,
|
|
212
|
-
* // in this case a set of three indices for each triangle.
|
|
213
|
-
* //
|
|
214
|
-
* // Note that each triangle is specified in counter-clockwise winding order.
|
|
215
|
-
* //
|
|
216
|
-
* indices: [
|
|
217
|
-
* 0, 1, 2, 0, 2, 3, // front
|
|
218
|
-
* 4, 5, 6, 4, 6, 7, // right
|
|
219
|
-
* 8, 9, 10, 8, 10, 11, // top
|
|
220
|
-
* 12, 13, 14, 12, 14, 15, // left
|
|
221
|
-
* 16, 17, 18, 16, 18, 19, // bottom
|
|
222
|
-
* 20, 21, 22, 20, 22, 23
|
|
223
|
-
* ]
|
|
224
|
-
* });
|
|
225
|
-
*
|
|
226
|
-
* // Red table leg
|
|
227
|
-
*
|
|
228
|
-
* sceneModel.createMesh({
|
|
229
|
-
* id: "redLegMesh",
|
|
230
|
-
* geometryId: "myBoxGeometry",
|
|
231
|
-
* position: [-4, -6, -4],
|
|
232
|
-
* scale: [1, 3, 1],
|
|
233
|
-
* rotation: [0, 0, 0],
|
|
234
|
-
* color: [1, 0.3, 0.3]
|
|
235
|
-
* });
|
|
236
|
-
*
|
|
237
|
-
* sceneModel.createEntity({
|
|
238
|
-
* id: "redLeg",
|
|
239
|
-
* meshIds: ["redLegMesh"],
|
|
240
|
-
* isObject: true // <---- Registers Entity by ID on viewer.scene.objects
|
|
241
|
-
* });
|
|
242
|
-
*
|
|
243
|
-
* // Green table leg
|
|
244
|
-
*
|
|
245
|
-
* sceneModel.createMesh({
|
|
246
|
-
* id: "greenLegMesh",
|
|
247
|
-
* geometryId: "myBoxGeometry",
|
|
248
|
-
* position: [4, -6, -4],
|
|
249
|
-
* scale: [1, 3, 1],
|
|
250
|
-
* rotation: [0, 0, 0],
|
|
251
|
-
* color: [0.3, 1.0, 0.3]
|
|
252
|
-
* });
|
|
253
|
-
*
|
|
254
|
-
* sceneModel.createEntity({
|
|
255
|
-
* id: "greenLeg",
|
|
256
|
-
* meshIds: ["greenLegMesh"],
|
|
257
|
-
* isObject: true // <---- Registers Entity by ID on viewer.scene.objects
|
|
258
|
-
* });
|
|
259
|
-
*
|
|
260
|
-
* // Blue table leg
|
|
261
|
-
*
|
|
262
|
-
* sceneModel.createMesh({
|
|
263
|
-
* id: "blueLegMesh",
|
|
264
|
-
* geometryId: "myBoxGeometry",
|
|
265
|
-
* position: [4, -6, 4],
|
|
266
|
-
* scale: [1, 3, 1],
|
|
267
|
-
* rotation: [0, 0, 0],
|
|
268
|
-
* color: [0.3, 0.3, 1.0]
|
|
269
|
-
* });
|
|
270
|
-
*
|
|
271
|
-
* sceneModel.createEntity({
|
|
272
|
-
* id: "blueLeg",
|
|
273
|
-
* meshIds: ["blueLegMesh"],
|
|
274
|
-
* isObject: true // <---- Registers Entity by ID on viewer.scene.objects
|
|
275
|
-
* });
|
|
276
|
-
*
|
|
277
|
-
* // Yellow table leg
|
|
278
|
-
*
|
|
279
|
-
* sceneModel.createMesh({
|
|
280
|
-
* id: "yellowLegMesh",
|
|
281
|
-
* geometryId: "myBoxGeometry",
|
|
282
|
-
* position: [-4, -6, 4],
|
|
283
|
-
* scale: [1, 3, 1],
|
|
284
|
-
* rotation: [0, 0, 0],
|
|
285
|
-
* color: [1.0, 1.0, 0.0]
|
|
286
|
-
* });
|
|
287
|
-
*
|
|
288
|
-
* sceneModel.createEntity({
|
|
289
|
-
* id: "yellowLeg",
|
|
290
|
-
* meshIds: ["yellowLegMesh"],
|
|
291
|
-
* isObject: true // <---- Registers Entity by ID on viewer.scene.objects
|
|
292
|
-
* });
|
|
293
|
-
*
|
|
294
|
-
* // Purple table top
|
|
295
|
-
*
|
|
296
|
-
* sceneModel.createMesh({
|
|
297
|
-
* id: "purpleTableTopMesh",
|
|
298
|
-
* geometryId: "myBoxGeometry",
|
|
299
|
-
* position: [0, -3, 0],
|
|
300
|
-
* scale: [6, 0.5, 6],
|
|
301
|
-
* rotation: [0, 0, 0],
|
|
302
|
-
* color: [1.0, 0.3, 1.0]
|
|
303
|
-
* });
|
|
304
|
-
*
|
|
305
|
-
* sceneModel.createEntity({
|
|
306
|
-
* id: "purpleTableTop",
|
|
307
|
-
* meshIds: ["purpleTableTopMesh"],
|
|
308
|
-
* isObject: true // <---- Registers Entity by ID on viewer.scene.objects
|
|
309
|
-
* });
|
|
310
|
-
* ````
|
|
311
|
-
*
|
|
312
|
-
* ## Finalizing a SceneModel
|
|
313
|
-
*
|
|
314
|
-
* Before we can view and interact with our ````SceneModel````, we need to **finalize** it. Internally, this causes the ````SceneModel```` to build the
|
|
315
|
-
* vertex buffer objects (VBOs) that support our geometry instances. When using geometry batching (see next example),
|
|
316
|
-
* this causes ````SceneModel```` to build the VBOs that combine the batched geometries. Note that you can do both instancing and
|
|
317
|
-
* batching within the same ````SceneModel````.
|
|
318
|
-
*
|
|
319
|
-
* Once finalized, we can't add anything more to our ````SceneModel````.
|
|
320
|
-
*
|
|
321
|
-
* ```` javascript
|
|
322
|
-
* SceneModel.finalize();
|
|
323
|
-
* ````
|
|
324
|
-
*
|
|
325
|
-
* ## Finding Entities
|
|
326
|
-
*
|
|
327
|
-
* As mentioned earlier, {@link Entity} is
|
|
328
|
-
* the abstract base class for components that represent models, objects, or just
|
|
329
|
-
* anonymous visible elements.
|
|
330
|
-
*
|
|
331
|
-
* Since we created configured our ````SceneModel```` with ````isModel: true````,
|
|
332
|
-
* we're able to find it as an Entity by ID in ````viewer.scene.models````. Likewise, since
|
|
333
|
-
* we configured each of its Entities with ````isObject: true````, we're able to
|
|
334
|
-
* find them in ````viewer.scene.objects````.
|
|
335
|
-
*
|
|
336
|
-
*
|
|
337
|
-
* ````javascript
|
|
338
|
-
* // Get the whole table model Entity
|
|
339
|
-
* const table = viewer.scene.models["table"];
|
|
340
|
-
*
|
|
341
|
-
* // Get some leg object Entities
|
|
342
|
-
* const redLeg = viewer.scene.objects["redLeg"];
|
|
343
|
-
* const greenLeg = viewer.scene.objects["greenLeg"];
|
|
344
|
-
* const blueLeg = viewer.scene.objects["blueLeg"];
|
|
345
|
-
* ````
|
|
346
|
-
*
|
|
347
|
-
* ## Example 2: Geometry Batching
|
|
348
|
-
*
|
|
349
|
-
* Let's once more use a ````SceneModel````
|
|
350
|
-
* to build the simple table model, this time exploiting geometry batching.
|
|
351
|
-
*
|
|
352
|
-
* [](https://xeokit.github.io/xeokit-sdk/examples/#sceneRepresentation_SceneModel_batching)
|
|
353
|
-
*
|
|
354
|
-
* ````javascript
|
|
355
|
-
* import {Viewer, SceneModel} from "xeokit-sdk.es.js";
|
|
356
|
-
*
|
|
357
|
-
* const viewer = new Viewer({
|
|
358
|
-
* canvasId: "myCanvas",
|
|
359
|
-
* transparent: true
|
|
360
|
-
* });
|
|
361
|
-
*
|
|
362
|
-
* viewer.scene.camera.eye = [-21.80, 4.01, 6.56];
|
|
363
|
-
* viewer.scene.camera.look = [0, -5.75, 0];
|
|
364
|
-
* viewer.scene.camera.up = [0.37, 0.91, -0.11];
|
|
365
|
-
*
|
|
366
|
-
* // Create a SceneModel representing a table with four legs, using geometry batching
|
|
367
|
-
* const sceneModel = new SceneModel(viewer.scene, {
|
|
368
|
-
* id: "table",
|
|
369
|
-
* isModel: true, // <--- Registers SceneModel in viewer.scene.models
|
|
370
|
-
* position: [0, 0, 0],
|
|
371
|
-
* scale: [1, 1, 1],
|
|
372
|
-
* rotation: [0, 0, 0]
|
|
373
|
-
* });
|
|
374
|
-
*
|
|
375
|
-
* // Red table leg
|
|
376
|
-
*
|
|
377
|
-
* sceneModel.createMesh({
|
|
378
|
-
* id: "redLegMesh",
|
|
379
|
-
*
|
|
380
|
-
* // Geometry arrays are same as for the earlier batching example
|
|
381
|
-
* primitive: "triangles",
|
|
382
|
-
* positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
|
|
383
|
-
* normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
|
|
384
|
-
* indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
|
|
385
|
-
* position: [-4, -6, -4],
|
|
386
|
-
* scale: [1, 3, 1],
|
|
387
|
-
* rotation: [0, 0, 0],
|
|
388
|
-
* color: [1, 0.3, 0.3]
|
|
389
|
-
* });
|
|
390
|
-
*
|
|
391
|
-
* sceneModel.createEntity({
|
|
392
|
-
* id: "redLeg",
|
|
393
|
-
* meshIds: ["redLegMesh"],
|
|
394
|
-
* isObject: true // <---- Registers Entity by ID on viewer.scene.objects
|
|
395
|
-
* });
|
|
396
|
-
*
|
|
397
|
-
* // Green table leg
|
|
398
|
-
*
|
|
399
|
-
* sceneModel.createMesh({
|
|
400
|
-
* id: "greenLegMesh",
|
|
401
|
-
* primitive: "triangles",
|
|
402
|
-
* primitive: "triangles",
|
|
403
|
-
* positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
|
|
404
|
-
* normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
|
|
405
|
-
* indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
|
|
406
|
-
* position: [4, -6, -4],
|
|
407
|
-
* scale: [1, 3, 1],
|
|
408
|
-
* rotation: [0, 0, 0],
|
|
409
|
-
* color: [0.3, 1.0, 0.3]
|
|
410
|
-
* });
|
|
411
|
-
*
|
|
412
|
-
* sceneModel.createEntity({
|
|
413
|
-
* id: "greenLeg",
|
|
414
|
-
* meshIds: ["greenLegMesh"],
|
|
415
|
-
* isObject: true // <---- Registers Entity by ID on viewer.scene.objects
|
|
416
|
-
* });
|
|
417
|
-
*
|
|
418
|
-
* // Blue table leg
|
|
419
|
-
*
|
|
420
|
-
* sceneModel.createMesh({
|
|
421
|
-
* id: "blueLegMesh",
|
|
422
|
-
* primitive: "triangles",
|
|
423
|
-
* positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
|
|
424
|
-
* normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
|
|
425
|
-
* indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
|
|
426
|
-
* position: [4, -6, 4],
|
|
427
|
-
* scale: [1, 3, 1],
|
|
428
|
-
* rotation: [0, 0, 0],
|
|
429
|
-
* color: [0.3, 0.3, 1.0]
|
|
430
|
-
* });
|
|
431
|
-
*
|
|
432
|
-
* sceneModel.createEntity({
|
|
433
|
-
* id: "blueLeg",
|
|
434
|
-
* meshIds: ["blueLegMesh"],
|
|
435
|
-
* isObject: true // <---- Registers Entity by ID on viewer.scene.objects
|
|
436
|
-
* });
|
|
437
|
-
*
|
|
438
|
-
* // Yellow table leg object
|
|
439
|
-
*
|
|
440
|
-
* sceneModel.createMesh({
|
|
441
|
-
* id: "yellowLegMesh",
|
|
442
|
-
* positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
|
|
443
|
-
* normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
|
|
444
|
-
* indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
|
|
445
|
-
* position: [-4, -6, 4],
|
|
446
|
-
* scale: [1, 3, 1],
|
|
447
|
-
* rotation: [0, 0, 0],
|
|
448
|
-
* color: [1.0, 1.0, 0.0]
|
|
449
|
-
* });
|
|
450
|
-
*
|
|
451
|
-
* sceneModel.createEntity({
|
|
452
|
-
* id: "yellowLeg",
|
|
453
|
-
* meshIds: ["yellowLegMesh"],
|
|
454
|
-
* isObject: true // <---- Registers Entity by ID on viewer.scene.objects
|
|
455
|
-
* });
|
|
456
|
-
*
|
|
457
|
-
* // Purple table top
|
|
458
|
-
*
|
|
459
|
-
* sceneModel.createMesh({
|
|
460
|
-
* id: "purpleTableTopMesh",
|
|
461
|
-
* positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
|
|
462
|
-
* normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
|
|
463
|
-
* indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
|
|
464
|
-
* position: [0, -3, 0],
|
|
465
|
-
* scale: [6, 0.5, 6],
|
|
466
|
-
* rotation: [0, 0, 0],
|
|
467
|
-
* color: [1.0, 0.3, 1.0]
|
|
468
|
-
* });
|
|
469
|
-
*
|
|
470
|
-
* sceneModel.createEntity({
|
|
471
|
-
* id: "purpleTableTop",
|
|
472
|
-
* meshIds: ["purpleTableTopMesh"],
|
|
473
|
-
* isObject: true // <---- Registers Entity by ID on viewer.scene.objects
|
|
474
|
-
* });
|
|
475
|
-
*
|
|
476
|
-
* // Finalize the SceneModel.
|
|
477
|
-
*
|
|
478
|
-
* SceneModel.finalize();
|
|
479
|
-
*
|
|
480
|
-
* // Find BigModelNodes by their model and object IDs
|
|
481
|
-
*
|
|
482
|
-
* // Get the whole table model
|
|
483
|
-
* const table = viewer.scene.models["table"];
|
|
484
|
-
*
|
|
485
|
-
* // Get some leg objects
|
|
486
|
-
* const redLeg = viewer.scene.objects["redLeg"];
|
|
487
|
-
* const greenLeg = viewer.scene.objects["greenLeg"];
|
|
488
|
-
* const blueLeg = viewer.scene.objects["blueLeg"];
|
|
489
|
-
* ````
|
|
490
|
-
*
|
|
491
|
-
* ## Classifying with Metadata
|
|
492
|
-
*
|
|
493
|
-
* In the previous examples, we used ````SceneModel```` to build
|
|
494
|
-
* two versions of the same table model, to demonstrate geometry batching and geometry instancing.
|
|
495
|
-
*
|
|
496
|
-
* We'll now classify our {@link Entity}s with metadata. This metadata
|
|
497
|
-
* will work the same for both our examples, since they create the exact same structure of {@link Entity}s
|
|
498
|
-
* to represent their models and objects. The abstract Entity type is, after all, intended to provide an abstract interface through which differently-implemented scene content can be accessed uniformly.
|
|
499
|
-
*
|
|
500
|
-
* To create the metadata, we'll create a {@link MetaModel} for our model,
|
|
501
|
-
* with a {@link MetaObject} for each of it's objects. The MetaModel and MetaObjects
|
|
502
|
-
* get the same IDs as the {@link Entity}s that represent their model and objects within our scene.
|
|
503
|
-
*
|
|
504
|
-
* ```` javascript
|
|
505
|
-
* const furnitureMetaModel = viewer.metaScene.createMetaModel("furniture", { // Creates a MetaModel in the MetaScene
|
|
506
|
-
*
|
|
507
|
-
* "projectId": "myTableProject",
|
|
508
|
-
* "revisionId": "V1.0",
|
|
509
|
-
*
|
|
510
|
-
* "metaObjects": [
|
|
511
|
-
* { // Creates a MetaObject in the MetaModel
|
|
512
|
-
* "id": "table",
|
|
513
|
-
* "name": "Table", // Same ID as an object Entity
|
|
514
|
-
* "type": "furniture", // Arbitrary type, could be IFC type
|
|
515
|
-
* "properties": { // Arbitrary properties, could be IfcPropertySet
|
|
516
|
-
* "cost": "200"
|
|
517
|
-
* }
|
|
518
|
-
* },
|
|
519
|
-
* {
|
|
520
|
-
* "id": "redLeg",
|
|
521
|
-
* "name": "Red table Leg",
|
|
522
|
-
* "type": "leg",
|
|
523
|
-
* "parent": "table", // References first MetaObject as parent
|
|
524
|
-
* "properties": {
|
|
525
|
-
* "material": "wood"
|
|
526
|
-
* }
|
|
527
|
-
* },
|
|
528
|
-
* {
|
|
529
|
-
* "id": "greenLeg", // Node with corresponding id does not need to exist
|
|
530
|
-
* "name": "Green table leg", // and MetaObject does not need to exist for Node with an id
|
|
531
|
-
* "type": "leg",
|
|
532
|
-
* "parent": "table",
|
|
533
|
-
* "properties": {
|
|
534
|
-
* "material": "wood"
|
|
535
|
-
* }
|
|
536
|
-
* },
|
|
537
|
-
* {
|
|
538
|
-
* "id": "blueLeg",
|
|
539
|
-
* "name": "Blue table leg",
|
|
540
|
-
* "type": "leg",
|
|
541
|
-
* "parent": "table",
|
|
542
|
-
* "properties": {
|
|
543
|
-
* "material": "wood"
|
|
544
|
-
* }
|
|
545
|
-
* },
|
|
546
|
-
* {
|
|
547
|
-
* "id": "yellowLeg",
|
|
548
|
-
* "name": "Yellow table leg",
|
|
549
|
-
* "type": "leg",
|
|
550
|
-
* "parent": "table",
|
|
551
|
-
* "properties": {
|
|
552
|
-
* "material": "wood"
|
|
553
|
-
* }
|
|
554
|
-
* },
|
|
555
|
-
* {
|
|
556
|
-
* "id": "tableTop",
|
|
557
|
-
* "name": "Purple table top",
|
|
558
|
-
* "type": "surface",
|
|
559
|
-
* "parent": "table",
|
|
560
|
-
* "properties": {
|
|
561
|
-
* "material": "formica",
|
|
562
|
-
* "width": "60",
|
|
563
|
-
* "depth": "60",
|
|
564
|
-
* "thickness": "5"
|
|
565
|
-
* }
|
|
566
|
-
* }
|
|
567
|
-
* ]
|
|
568
|
-
* });
|
|
569
|
-
* ````
|
|
570
|
-
*
|
|
571
|
-
* ## Querying Metadata
|
|
572
|
-
*
|
|
573
|
-
* Having created and classified our model (either the instancing or batching example), we can now find the {@link MetaModel}
|
|
574
|
-
* and {@link MetaObject}s using the IDs of their
|
|
575
|
-
* corresponding {@link Entity}s.
|
|
576
|
-
*
|
|
577
|
-
* ````JavaScript
|
|
578
|
-
* const furnitureMetaModel = scene.metaScene.metaModels["furniture"];
|
|
579
|
-
*
|
|
580
|
-
* const redLegMetaObject = scene.metaScene.metaObjects["redLeg"];
|
|
581
|
-
* ````
|
|
582
|
-
*
|
|
583
|
-
* In the snippet below, we'll log metadata on each {@link Entity} we click on:
|
|
584
|
-
*
|
|
585
|
-
* ````JavaScript
|
|
586
|
-
* viewer.scene.input.on("mouseclicked", function (coords) {
|
|
587
|
-
*
|
|
588
|
-
* const hit = viewer.scene.pick({
|
|
589
|
-
* canvasPos: coords
|
|
590
|
-
* });
|
|
591
|
-
*
|
|
592
|
-
* if (hit) {
|
|
593
|
-
* const entity = hit.entity;
|
|
594
|
-
* const metaObject = viewer.metaScene.metaObjects[entity.id];
|
|
595
|
-
* if (metaObject) {
|
|
596
|
-
* console.log(JSON.stringify(metaObject.getJSON(), null, "\t"));
|
|
597
|
-
* }
|
|
598
|
-
* }
|
|
599
|
-
* });
|
|
600
|
-
* ````
|
|
601
|
-
*
|
|
602
|
-
* ## Metadata Structure
|
|
603
|
-
*
|
|
604
|
-
* The {@link MetaModel}
|
|
605
|
-
* organizes its {@link MetaObject}s in
|
|
606
|
-
* a tree that describes their structural composition:
|
|
607
|
-
*
|
|
608
|
-
* ````JavaScript
|
|
609
|
-
* // Get metadata on the root object
|
|
610
|
-
* const tableMetaObject = furnitureMetaModel.rootMetaObject;
|
|
611
|
-
*
|
|
612
|
-
* // Get metadata on the leg objects
|
|
613
|
-
* const redLegMetaObject = tableMetaObject.children[0];
|
|
614
|
-
* const greenLegMetaObject = tableMetaObject.children[1];
|
|
615
|
-
* const blueLegMetaObject = tableMetaObject.children[2];
|
|
616
|
-
* const yellowLegMetaObject = tableMetaObject.children[3];
|
|
617
|
-
* ````
|
|
618
|
-
*
|
|
619
|
-
* Given an {@link Entity}, we can find the object or model of which it is a part, or the objects that comprise it. We can also generate UI
|
|
620
|
-
* components from the metadata, such as the tree view demonstrated in [this demo](https://xeokit.github.io/xeokit-sdk/examples/#BIMOffline_glTF_OTCConferenceCenter).
|
|
621
|
-
*
|
|
622
|
-
* This hierarchy allows us to express the hierarchical structure of a model while representing it in
|
|
623
|
-
* various ways in the 3D scene (such as with ````SceneModel````, which
|
|
624
|
-
* has a non-hierarchical scene representation).
|
|
625
|
-
*
|
|
626
|
-
* Note also that a {@link MetaObject} does not need to have a corresponding
|
|
627
|
-
* {@link Entity} and vice-versa.
|
|
628
|
-
*
|
|
629
|
-
* # RTC Coordinates for Double Precision
|
|
630
|
-
*
|
|
631
|
-
* ````SceneModel```` can emulate 64-bit precision on GPUs using relative-to-center (RTC) coordinates.
|
|
632
|
-
*
|
|
633
|
-
* Consider a model that contains many small objects, but with such large spatial extents that 32 bits of GPU precision (accurate to ~7 digits) will not be sufficient to render all of the the objects without jittering.
|
|
634
|
-
*
|
|
635
|
-
* To prevent jittering, we could spatially subdivide the objects into "tiles". Each tile would have a center position, and the positions of the objects within the tile would be relative to that center ("RTC coordinates").
|
|
636
|
-
*
|
|
637
|
-
* While the center positions of the tiles would be 64-bit values, the object positions only need to be 32-bit.
|
|
638
|
-
*
|
|
639
|
-
* Internally, when rendering an object with RTC coordinates, xeokit first temporarily translates the camera viewing matrix by the object's tile's RTC center, on the CPU, using 64-bit math.
|
|
640
|
-
*
|
|
641
|
-
* Then xeokit loads the viewing matrix into its WebGL shaders, where math happens at 32-bit precision. Within the shaders, the matrix is effectively down-cast to 32-bit precision, and the object's 32-bit vertex positions are transformed by the matrix.
|
|
642
|
-
*
|
|
643
|
-
* We see no jittering, because with RTC a detectable loss of GPU accuracy only starts happening to objects as they become very distant from the camera viewpoint, at which point they are too small to be discernible anyway.
|
|
644
|
-
*
|
|
645
|
-
* ## RTC Coordinates with Geometry Instancing
|
|
646
|
-
*
|
|
647
|
-
* To use RTC with ````SceneModel```` geometry instancing, we specify an RTC center for the geometry via its ````origin```` parameter. Then ````SceneModel```` assumes that all meshes that instance that geometry are within the same RTC coordinate system, ie. the meshes ````position```` and ````rotation```` properties are assumed to be relative to the geometry's ````origin````.
|
|
648
|
-
*
|
|
649
|
-
* For simplicity, our example's meshes all instance the same geometry. Therefore, our example model has only one RTC center.
|
|
650
|
-
*
|
|
651
|
-
* Note that the axis-aligned World-space boundary (AABB) of our model is ````[ -6, -9, -6, 1000000006, -2.5, 1000000006]````.
|
|
652
|
-
*
|
|
653
|
-
* [](https://xeokit.github.io/xeokit-sdk/examples/#sceneRepresentation_SceneModel_batching)
|
|
654
|
-
*
|
|
655
|
-
* ````javascript
|
|
656
|
-
* const origin = [100000000, 0, 100000000];
|
|
657
|
-
*
|
|
658
|
-
* sceneModel.createGeometry({
|
|
659
|
-
* id: "box",
|
|
660
|
-
* primitive: "triangles",
|
|
661
|
-
* positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
|
|
662
|
-
* normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
|
|
663
|
-
* indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
|
|
664
|
-
* });
|
|
665
|
-
*
|
|
666
|
-
* sceneModel.createMesh({
|
|
667
|
-
* id: "leg1",
|
|
668
|
-
* geometryId: "box",
|
|
669
|
-
* position: [-4, -6, -4],
|
|
670
|
-
* scale: [1, 3, 1],
|
|
671
|
-
* rotation: [0, 0, 0],
|
|
672
|
-
* color: [1, 0.3, 0.3],
|
|
673
|
-
* origin: origin
|
|
674
|
-
* });
|
|
675
|
-
*
|
|
676
|
-
* sceneModel.createEntity({
|
|
677
|
-
* meshIds: ["leg1"],
|
|
678
|
-
* isObject: true
|
|
679
|
-
* });
|
|
680
|
-
*
|
|
681
|
-
* sceneModel.createMesh({
|
|
682
|
-
* id: "leg2",
|
|
683
|
-
* geometryId: "box",
|
|
684
|
-
* position: [4, -6, -4],
|
|
685
|
-
* scale: [1, 3, 1],
|
|
686
|
-
* rotation: [0, 0, 0],
|
|
687
|
-
* color: [0.3, 1.0, 0.3],
|
|
688
|
-
* origin: origin
|
|
689
|
-
* });
|
|
690
|
-
*
|
|
691
|
-
* sceneModel.createEntity({
|
|
692
|
-
* meshIds: ["leg2"],
|
|
693
|
-
* isObject: true
|
|
694
|
-
* });
|
|
695
|
-
*
|
|
696
|
-
* sceneModel.createMesh({
|
|
697
|
-
* id: "leg3",
|
|
698
|
-
* geometryId: "box",
|
|
699
|
-
* position: [4, -6, 4],
|
|
700
|
-
* scale: [1, 3, 1],
|
|
701
|
-
* rotation: [0, 0, 0],
|
|
702
|
-
* color: [0.3, 0.3, 1.0],
|
|
703
|
-
* origin: origin
|
|
704
|
-
* });
|
|
705
|
-
*
|
|
706
|
-
* sceneModel.createEntity({
|
|
707
|
-
* meshIds: ["leg3"],
|
|
708
|
-
* isObject: true
|
|
709
|
-
* });
|
|
710
|
-
*
|
|
711
|
-
* sceneModel.createMesh({
|
|
712
|
-
* id: "leg4",
|
|
713
|
-
* geometryId: "box",
|
|
714
|
-
* position: [-4, -6, 4],
|
|
715
|
-
* scale: [1, 3, 1],
|
|
716
|
-
* rotation: [0, 0, 0],
|
|
717
|
-
* color: [1.0, 1.0, 0.0],
|
|
718
|
-
* origin: origin
|
|
719
|
-
* });
|
|
720
|
-
*
|
|
721
|
-
* sceneModel.createEntity({
|
|
722
|
-
* meshIds: ["leg4"],
|
|
723
|
-
* isObject: true
|
|
724
|
-
* });
|
|
725
|
-
*
|
|
726
|
-
* sceneModel.createMesh({
|
|
727
|
-
* id: "top",
|
|
728
|
-
* geometryId: "box",
|
|
729
|
-
* position: [0, -3, 0],
|
|
730
|
-
* scale: [6, 0.5, 6],
|
|
731
|
-
* rotation: [0, 0, 0],
|
|
732
|
-
* color: [1.0, 0.3, 1.0],
|
|
733
|
-
* origin: origin
|
|
734
|
-
* });
|
|
735
|
-
*
|
|
736
|
-
* sceneModel.createEntity({
|
|
737
|
-
* meshIds: ["top"],
|
|
738
|
-
* isObject: true
|
|
739
|
-
* });
|
|
740
|
-
* ````
|
|
741
|
-
*
|
|
742
|
-
* ## RTC Coordinates with Geometry Batching
|
|
743
|
-
*
|
|
744
|
-
* To use RTC with ````SceneModel```` geometry batching, we specify an RTC center (````origin````) for each mesh. For performance, we try to have as many meshes share the same value for ````origin```` as possible. Each mesh's ````positions````, ````position```` and ````rotation```` properties are assumed to be relative to ````origin````.
|
|
745
|
-
*
|
|
746
|
-
* For simplicity, the meshes in our example all share the same RTC center.
|
|
747
|
-
*
|
|
748
|
-
* The axis-aligned World-space boundary (AABB) of our model is ````[ -6, -9, -6, 1000000006, -2.5, 1000000006]````.
|
|
749
|
-
*
|
|
750
|
-
* [](https://xeokit.github.io/xeokit-sdk/examples/#sceneRepresentation_SceneModel_batching)
|
|
751
|
-
*
|
|
752
|
-
* ````javascript
|
|
753
|
-
* const origin = [100000000, 0, 100000000];
|
|
754
|
-
*
|
|
755
|
-
* sceneModel.createMesh({
|
|
756
|
-
* id: "leg1",
|
|
757
|
-
* origin: origin, // This mesh's positions and transforms are relative to the RTC center
|
|
758
|
-
* primitive: "triangles",
|
|
759
|
-
* positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
|
|
760
|
-
* normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
|
|
761
|
-
* indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
|
|
762
|
-
* position: [-4, -6, -4],
|
|
763
|
-
* scale: [1, 3, 1],
|
|
764
|
-
* rotation: [0, 0, 0],
|
|
765
|
-
* color: [1, 0.3, 0.3]
|
|
766
|
-
* });
|
|
767
|
-
*
|
|
768
|
-
* sceneModel.createEntity({
|
|
769
|
-
* meshIds: ["leg1"],
|
|
770
|
-
* isObject: true
|
|
771
|
-
* });
|
|
772
|
-
*
|
|
773
|
-
* sceneModel.createMesh({
|
|
774
|
-
* id: "leg2",
|
|
775
|
-
* origin: origin, // This mesh's positions and transforms are relative to the RTC center
|
|
776
|
-
* primitive: "triangles",
|
|
777
|
-
* positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
|
|
778
|
-
* normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
|
|
779
|
-
* indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
|
|
780
|
-
* position: [4, -6, -4],
|
|
781
|
-
* scale: [1, 3, 1],
|
|
782
|
-
* rotation: [0, 0, 0],
|
|
783
|
-
* color: [0.3, 1.0, 0.3]
|
|
784
|
-
* });
|
|
785
|
-
*
|
|
786
|
-
* sceneModel.createEntity({
|
|
787
|
-
* meshIds: ["leg2"],
|
|
788
|
-
* isObject: true
|
|
789
|
-
* });
|
|
790
|
-
*
|
|
791
|
-
* sceneModel.createMesh({
|
|
792
|
-
* id: "leg3",
|
|
793
|
-
* origin: origin, // This mesh's positions and transforms are relative to the RTC center
|
|
794
|
-
* primitive: "triangles",
|
|
795
|
-
* positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
|
|
796
|
-
* normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
|
|
797
|
-
* indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
|
|
798
|
-
* position: [4, -6, 4],
|
|
799
|
-
* scale: [1, 3, 1],
|
|
800
|
-
* rotation: [0, 0, 0],
|
|
801
|
-
* color: [0.3, 0.3, 1.0]
|
|
802
|
-
* });
|
|
803
|
-
*
|
|
804
|
-
* sceneModel.createEntity({
|
|
805
|
-
* meshIds: ["leg3"],
|
|
806
|
-
* isObject: true
|
|
807
|
-
* });
|
|
808
|
-
*
|
|
809
|
-
* sceneModel.createMesh({
|
|
810
|
-
* id: "leg4",
|
|
811
|
-
* origin: origin, // This mesh's positions and transforms are relative to the RTC center
|
|
812
|
-
* primitive: "triangles",
|
|
813
|
-
* positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
|
|
814
|
-
* normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
|
|
815
|
-
* indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
|
|
816
|
-
* position: [-4, -6, 4],
|
|
817
|
-
* scale: [1, 3, 1],
|
|
818
|
-
* rotation: [0, 0, 0],
|
|
819
|
-
* color: [1.0, 1.0, 0.0]
|
|
820
|
-
* });
|
|
821
|
-
*
|
|
822
|
-
* sceneModel.createEntity({
|
|
823
|
-
* meshIds: ["leg4"],
|
|
824
|
-
* isObject: true
|
|
825
|
-
* });
|
|
826
|
-
*
|
|
827
|
-
* sceneModel.createMesh({
|
|
828
|
-
* id: "top",
|
|
829
|
-
* origin: origin, // This mesh's positions and transforms are relative to the RTC center
|
|
830
|
-
* primitive: "triangles",
|
|
831
|
-
* positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
|
|
832
|
-
* normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
|
|
833
|
-
* indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
|
|
834
|
-
* position: [0, -3, 0],
|
|
835
|
-
* scale: [6, 0.5, 6],
|
|
836
|
-
* rotation: [0, 0, 0],
|
|
837
|
-
* color: [1.0, 0.3, 1.0]
|
|
838
|
-
* });
|
|
839
|
-
*
|
|
840
|
-
* sceneModel.createEntity({
|
|
841
|
-
* meshIds: ["top"],
|
|
842
|
-
* isObject: true
|
|
843
|
-
* });
|
|
844
|
-
* ````
|
|
845
|
-
*
|
|
846
|
-
* ## Positioning at World-space coordinates
|
|
847
|
-
*
|
|
848
|
-
* To position a SceneModel at given double-precision World coordinates, we can
|
|
849
|
-
* configure the ````origin```` of the SceneModel itself. The ````origin```` is a double-precision
|
|
850
|
-
* 3D World-space position at which the SceneModel will be located.
|
|
851
|
-
*
|
|
852
|
-
* Note that ````position```` is a single-precision offset relative to ````origin````.
|
|
853
|
-
*
|
|
854
|
-
* ````javascript
|
|
855
|
-
* const origin = [100000000, 0, 100000000];
|
|
856
|
-
*
|
|
857
|
-
* const sceneModel = new SceneModel(viewer.scene, {
|
|
858
|
-
* id: "table",
|
|
859
|
-
* isModel: true,
|
|
860
|
-
* origin: origin, // Everything in this SceneModel is relative to this RTC center
|
|
861
|
-
* position: [0, 0, 0],
|
|
862
|
-
* scale: [1, 1, 1],
|
|
863
|
-
* rotation: [0, 0, 0]
|
|
864
|
-
* });
|
|
865
|
-
*
|
|
866
|
-
* sceneModel.createGeometry({
|
|
867
|
-
* id: "box",
|
|
868
|
-
* primitive: "triangles",
|
|
869
|
-
* positions: [ 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1 ... ],
|
|
870
|
-
* normals: [ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ... ],
|
|
871
|
-
* indices: [ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, ... ],
|
|
872
|
-
* });
|
|
873
|
-
*
|
|
874
|
-
* sceneModel.createMesh({
|
|
875
|
-
* id: "leg1",
|
|
876
|
-
* geometryId: "box",
|
|
877
|
-
* position: [-4, -6, -4],
|
|
878
|
-
* scale: [1, 3, 1],
|
|
879
|
-
* rotation: [0, 0, 0],
|
|
880
|
-
* color: [1, 0.3, 0.3]
|
|
881
|
-
* });
|
|
882
|
-
*
|
|
883
|
-
* sceneModel.createEntity({
|
|
884
|
-
* meshIds: ["leg1"],
|
|
885
|
-
* isObject: true
|
|
886
|
-
* });
|
|
887
|
-
*
|
|
888
|
-
* sceneModel.createMesh({
|
|
889
|
-
* id: "leg2",
|
|
890
|
-
* geometryId: "box",
|
|
891
|
-
* position: [4, -6, -4],
|
|
892
|
-
* scale: [1, 3, 1],
|
|
893
|
-
* rotation: [0, 0, 0],
|
|
894
|
-
* color: [0.3, 1.0, 0.3]
|
|
895
|
-
* });
|
|
896
|
-
*
|
|
897
|
-
* sceneModel.createEntity({
|
|
898
|
-
* meshIds: ["leg2"],
|
|
899
|
-
* isObject: true
|
|
900
|
-
* });
|
|
901
|
-
*
|
|
902
|
-
* sceneModel.createMesh({
|
|
903
|
-
* id: "leg3",
|
|
904
|
-
* geometryId: "box",
|
|
905
|
-
* position: [4, -6, 4],
|
|
906
|
-
* scale: [1, 3, 1],
|
|
907
|
-
* rotation: [0, 0, 0],
|
|
908
|
-
* color: [0.3, 0.3, 1.0]
|
|
909
|
-
* });
|
|
910
|
-
*
|
|
911
|
-
* sceneModel.createEntity({
|
|
912
|
-
* meshIds: ["leg3"],
|
|
913
|
-
* isObject: true
|
|
914
|
-
* });
|
|
915
|
-
*
|
|
916
|
-
* sceneModel.createMesh({
|
|
917
|
-
* id: "leg4",
|
|
918
|
-
* geometryId: "box",
|
|
919
|
-
* position: [-4, -6, 4],
|
|
920
|
-
* scale: [1, 3, 1],
|
|
921
|
-
* rotation: [0, 0, 0],
|
|
922
|
-
* color: [1.0, 1.0, 0.0]
|
|
923
|
-
* });
|
|
924
|
-
*
|
|
925
|
-
* sceneModel.createEntity({
|
|
926
|
-
* meshIds: ["leg4"],
|
|
927
|
-
* isObject: true
|
|
928
|
-
* });
|
|
929
|
-
*
|
|
930
|
-
* sceneModel.createMesh({
|
|
931
|
-
* id: "top",
|
|
932
|
-
* geometryId: "box",
|
|
933
|
-
* position: [0, -3, 0],
|
|
934
|
-
* scale: [6, 0.5, 6],
|
|
935
|
-
* rotation: [0, 0, 0],
|
|
936
|
-
* color: [1.0, 0.3, 1.0]
|
|
937
|
-
* });
|
|
938
|
-
*
|
|
939
|
-
* sceneModel.createEntity({
|
|
940
|
-
* meshIds: ["top"],
|
|
941
|
-
* isObject: true
|
|
942
|
-
* });
|
|
943
|
-
* ````
|
|
944
|
-
*
|
|
945
|
-
* # Textures
|
|
946
|
-
*
|
|
947
|
-
* ## Loading KTX2 Texture Files into a SceneModel
|
|
948
|
-
*
|
|
949
|
-
* A {@link SceneModel} that is configured with a {@link KTX2TextureTranscoder} will
|
|
950
|
-
* allow us to load textures into it from KTX2 buffers or files.
|
|
951
|
-
*
|
|
952
|
-
* In the example below, we'll create a {@link Viewer}, containing a {@link SceneModel} configured with a
|
|
953
|
-
* {@link KTX2TextureTranscoder}. We'll then programmatically create a simple object within the SceneModel, consisting of
|
|
954
|
-
* a single mesh with a texture loaded from a KTX2 file, which our SceneModel internally transcodes, using
|
|
955
|
-
* its {@link KTX2TextureTranscoder}. Note how we configure our {@link KTX2TextureTranscoder} with a path to the Basis Universal
|
|
956
|
-
* transcoder WASM module.
|
|
957
|
-
*
|
|
958
|
-
* ````javascript
|
|
959
|
-
* const viewer = new Viewer({
|
|
960
|
-
* canvasId: "myCanvas",
|
|
961
|
-
* transparent: true
|
|
962
|
-
* });
|
|
963
|
-
*
|
|
964
|
-
* viewer.scene.camera.eye = [-21.80, 4.01, 6.56];
|
|
965
|
-
* viewer.scene.camera.look = [0, -5.75, 0];
|
|
966
|
-
* viewer.scene.camera.up = [0.37, 0.91, -0.11];
|
|
967
|
-
*
|
|
968
|
-
* const textureTranscoder = new KTX2TextureTranscoder({
|
|
969
|
-
* viewer,
|
|
970
|
-
* transcoderPath: "https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/basis/" // <------ Path to BasisU transcoder module
|
|
971
|
-
* });
|
|
972
|
-
*
|
|
973
|
-
* const sceneModel = new SceneModel(viewer.scene, {
|
|
974
|
-
* id: "myModel",
|
|
975
|
-
* textureTranscoder // <<-------------------- Configure model with our transcoder
|
|
976
|
-
* });
|
|
977
|
-
*
|
|
978
|
-
* sceneModel.createTexture({
|
|
979
|
-
* id: "myColorTexture",
|
|
980
|
-
* src: "../assets/textures/compressed/sample_uastc_zstd.ktx2" // <<----- KTX2 texture asset
|
|
981
|
-
* });
|
|
982
|
-
*
|
|
983
|
-
* sceneModel.createTexture({
|
|
984
|
-
* id: "myMetallicRoughnessTexture",
|
|
985
|
-
* src: "../assets/textures/alpha/crosshatchAlphaMap.jpg" // <<----- JPEG texture asset
|
|
986
|
-
* });
|
|
987
|
-
*
|
|
988
|
-
* sceneModel.createTextureSet({
|
|
989
|
-
* id: "myTextureSet",
|
|
990
|
-
* colorTextureId: "myColorTexture",
|
|
991
|
-
* metallicRoughnessTextureId: "myMetallicRoughnessTexture"
|
|
992
|
-
* });
|
|
993
|
-
*
|
|
994
|
-
* sceneModel.createMesh({
|
|
995
|
-
* id: "myMesh",
|
|
996
|
-
* textureSetId: "myTextureSet",
|
|
997
|
-
* primitive: "triangles",
|
|
998
|
-
* positions: [1, 1, 1, ...],
|
|
999
|
-
* normals: [0, 0, 1, 0, ...],
|
|
1000
|
-
* uv: [1, 0, 0, ...],
|
|
1001
|
-
* indices: [0, 1, 2, ...],
|
|
1002
|
-
* });
|
|
1003
|
-
*
|
|
1004
|
-
* sceneModel.createEntity({
|
|
1005
|
-
* id: "myEntity",
|
|
1006
|
-
* meshIds: ["myMesh"]
|
|
1007
|
-
* });
|
|
1008
|
-
*
|
|
1009
|
-
* sceneModel.finalize();
|
|
1010
|
-
* ````
|
|
1011
|
-
*
|
|
1012
|
-
* ## Loading KTX2 Textures from ArrayBuffers into a SceneModel
|
|
1013
|
-
*
|
|
1014
|
-
* A SceneModel that is configured with a {@link KTX2TextureTranscoder} will allow us to load textures into
|
|
1015
|
-
* it from KTX2 ArrayBuffers.
|
|
1016
|
-
*
|
|
1017
|
-
* In the example below, we'll create a {@link Viewer}, containing a {@link SceneModel} configured with a
|
|
1018
|
-
* {@link KTX2TextureTranscoder}. We'll then programmatically create a simple object within the SceneModel, consisting of
|
|
1019
|
-
* a single mesh with a texture loaded from a KTX2 ArrayBuffer, which our SceneModel internally transcodes, using
|
|
1020
|
-
* its {@link KTX2TextureTranscoder}.
|
|
1021
|
-
*
|
|
1022
|
-
* ````javascript
|
|
1023
|
-
* const viewer = new Viewer({
|
|
1024
|
-
* canvasId: "myCanvas",
|
|
1025
|
-
* transparent: true
|
|
1026
|
-
* });
|
|
1027
|
-
*
|
|
1028
|
-
* viewer.scene.camera.eye = [-21.80, 4.01, 6.56];
|
|
1029
|
-
* viewer.scene.camera.look = [0, -5.75, 0];
|
|
1030
|
-
* viewer.scene.camera.up = [0.37, 0.91, -0.11];
|
|
1031
|
-
*
|
|
1032
|
-
* const textureTranscoder = new KTX2TextureTranscoder({
|
|
1033
|
-
* viewer,
|
|
1034
|
-
* transcoderPath: "https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/basis/" // <------ Path to BasisU transcoder module
|
|
1035
|
-
* });
|
|
1036
|
-
*
|
|
1037
|
-
* const sceneModel = new SceneModel(viewer.scene, {
|
|
1038
|
-
* id: "myModel",
|
|
1039
|
-
* textureTranscoder // <<-------------------- Configure model with our transcoder
|
|
1040
|
-
* });
|
|
1041
|
-
*
|
|
1042
|
-
* utils.loadArraybuffer("../assets/textures/compressed/sample_uastc_zstd.ktx2",(arrayBuffer) => {
|
|
1043
|
-
*
|
|
1044
|
-
* sceneModel.createTexture({
|
|
1045
|
-
* id: "myColorTexture",
|
|
1046
|
-
* buffers: [arrayBuffer] // <<----- KTX2 texture asset
|
|
1047
|
-
* });
|
|
1048
|
-
*
|
|
1049
|
-
* sceneModel.createTexture({
|
|
1050
|
-
* id: "myMetallicRoughnessTexture",
|
|
1051
|
-
* src: "../assets/textures/alpha/crosshatchAlphaMap.jpg" // <<----- JPEG texture asset
|
|
1052
|
-
* });
|
|
1053
|
-
*
|
|
1054
|
-
* sceneModel.createTextureSet({
|
|
1055
|
-
* id: "myTextureSet",
|
|
1056
|
-
* colorTextureId: "myColorTexture",
|
|
1057
|
-
* metallicRoughnessTextureId: "myMetallicRoughnessTexture"
|
|
1058
|
-
* });
|
|
1059
|
-
*
|
|
1060
|
-
* sceneModel.createMesh({
|
|
1061
|
-
* id: "myMesh",
|
|
1062
|
-
* textureSetId: "myTextureSet",
|
|
1063
|
-
* primitive: "triangles",
|
|
1064
|
-
* positions: [1, 1, 1, ...],
|
|
1065
|
-
* normals: [0, 0, 1, 0, ...],
|
|
1066
|
-
* uv: [1, 0, 0, ...],
|
|
1067
|
-
* indices: [0, 1, 2, ...],
|
|
1068
|
-
* });
|
|
1069
|
-
*
|
|
1070
|
-
* sceneModel.createEntity({
|
|
1071
|
-
* id: "myEntity",
|
|
1072
|
-
* meshIds: ["myMesh"]
|
|
1073
|
-
* });
|
|
1074
|
-
*
|
|
1075
|
-
* sceneModel.finalize();
|
|
1076
|
-
* });
|
|
1077
|
-
* ````
|
|
1078
|
-
*
|
|
1079
|
-
* @implements {Entity}
|
|
1080
|
-
*/
|
|
1081
|
-
export class SceneModel extends Component {
|
|
1082
|
-
|
|
1083
|
-
/**
|
|
1084
|
-
* @constructor
|
|
1085
|
-
* @param {Component} owner Owner component. When destroyed, the owner will destroy this component as well.
|
|
1086
|
-
* @param {*} [cfg] Configs
|
|
1087
|
-
* @param {String} [cfg.id] Optional ID, unique among all components in the parent scene, generated automatically when omitted.
|
|
1088
|
-
* @param {Boolean} [cfg.isModel] Specify ````true```` if this SceneModel represents a model, in which case the SceneModel will be registered by {@link SceneModel#id} in {@link Scene#models} and may also have a corresponding {@link MetaModel} with matching {@link MetaModel#id}, registered by that ID in {@link MetaScene#metaModels}.
|
|
1089
|
-
* @param {Number[]} [cfg.origin=[0,0,0]] World-space double-precision 3D origin.
|
|
1090
|
-
* @param {Number[]} [cfg.position=[0,0,0]] Local, single-precision 3D position, relative to the origin parameter.
|
|
1091
|
-
* @param {Number[]} [cfg.scale=[1,1,1]] Local scale.
|
|
1092
|
-
* @param {Number[]} [cfg.rotation=[0,0,0]] Local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.
|
|
1093
|
-
* @param {Number[]} [cfg.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1] Local modelling transform matrix. Overrides the position, scale and rotation parameters.
|
|
1094
|
-
* @param {Boolean} [cfg.visible=true] Indicates if the SceneModel is initially visible.
|
|
1095
|
-
* @param {Boolean} [cfg.culled=false] Indicates if the SceneModel is initially culled from view.
|
|
1096
|
-
* @param {Boolean} [cfg.pickable=true] Indicates if the SceneModel is initially pickable.
|
|
1097
|
-
* @param {Boolean} [cfg.clippable=true] Indicates if the SceneModel is initially clippable.
|
|
1098
|
-
* @param {Boolean} [cfg.collidable=true] Indicates if the SceneModel is initially included in boundary calculations.
|
|
1099
|
-
* @param {Boolean} [cfg.xrayed=false] Indicates if the SceneModel is initially xrayed.
|
|
1100
|
-
* @param {Boolean} [cfg.highlighted=false] Indicates if the SceneModel is initially highlighted.
|
|
1101
|
-
* @param {Boolean} [cfg.selected=false] Indicates if the SceneModel is initially selected.
|
|
1102
|
-
* @param {Boolean} [cfg.edges=false] Indicates if the SceneModel's edges are initially emphasized.
|
|
1103
|
-
* @param {Number[]} [cfg.colorize=[1.0,1.0,1.0]] SceneModel's initial RGB colorize color, multiplies by the rendered fragment colors.
|
|
1104
|
-
* @param {Number} [cfg.opacity=1.0] SceneModel's initial opacity factor, multiplies by the rendered fragment alpha.
|
|
1105
|
-
* @param {Number} [cfg.backfaces=false] When we set this ````true````, then we force rendering of backfaces for this SceneModel. When
|
|
1106
|
-
* we leave this ````false````, then we allow the Viewer to decide when to render backfaces. In that case, the
|
|
1107
|
-
* Viewer will hide backfaces on watertight meshes, show backfaces on open meshes, and always show backfaces on meshes when we slice them open with {@link SectionPlane}s.
|
|
1108
|
-
* @param {Boolean} [cfg.saoEnabled=true] Indicates if Scalable Ambient Obscurance (SAO) will apply to this SceneModel. SAO is configured by the Scene's {@link SAO} component.
|
|
1109
|
-
* @param {Boolean} [cfg.pbrEnabled=true] Indicates if physically-based rendering (PBR) will apply to the SceneModel when {@link Scene#pbrEnabled} is ````true````.
|
|
1110
|
-
* @param {Boolean} [cfg.colorTextureEnabled=true] Indicates if base color textures will be rendered for the SceneModel when {@link Scene#colorTextureEnabled} is ````true````.
|
|
1111
|
-
* @param {Number} [cfg.edgeThreshold=10] When xraying, highlighting, selecting or edging, this is the threshold angle between normals of adjacent triangles, below which their shared wireframe edge is not drawn.
|
|
1112
|
-
* @param {Number} [cfg.maxGeometryBatchSize=50000000] Maximum geometry batch size, as number of vertices. This is optionally supplied
|
|
1113
|
-
* to limit the size of the batched geometry arrays that SceneModel internally creates for batched geometries.
|
|
1114
|
-
* A lower value means less heap allocation/de-allocation while creating/loading batched geometries, but more draw calls and
|
|
1115
|
-
* slower rendering speed. A high value means larger heap allocation/de-allocation while creating/loading, but less draw calls
|
|
1116
|
-
* and faster rendering speed. It's recommended to keep this somewhere roughly between ````50000```` and ````50000000```.
|
|
1117
|
-
* @param {TextureTranscoder} [cfg.textureTranscoder] Transcoder that will be used internally by {@link SceneModel#createTexture}
|
|
1118
|
-
* to convert transcoded texture data. Only required when we'll be providing transcoded data
|
|
1119
|
-
* to {@link SceneModel#createTexture}. We assume that all transcoded texture data added to a ````SceneModel````
|
|
1120
|
-
* will then in a format supported by this transcoder.
|
|
1121
|
-
* @param {Boolean} [cfg.dtxEnabled=true] When ````true```` (default) use data textures (DTX), where appropriate, to
|
|
1122
|
-
* represent the returned model. Set false to always use vertex buffer objects (VBOs). Note that DTX is only applicable
|
|
1123
|
-
* to non-textured triangle meshes, and that VBOs are always used for meshes that have textures, line segments, or point
|
|
1124
|
-
* primitives. Only works while {@link DTX#enabled} is also ````true````.
|
|
1125
|
-
*/
|
|
1126
|
-
constructor(owner, cfg = {}) {
|
|
1127
|
-
|
|
1128
|
-
super(owner, cfg);
|
|
1129
|
-
|
|
1130
|
-
this._dtxEnabled = this.scene.dtxEnabled && (cfg.dtxEnabled !== false);
|
|
1131
|
-
|
|
1132
|
-
this._enableVertexWelding = false; // Not needed for most objects, and very expensive, so disabled
|
|
1133
|
-
this._enableIndexBucketing = false; // Until fixed: https://github.com/xeokit/xeokit-sdk/issues/1204
|
|
1134
|
-
|
|
1135
|
-
this._vboBatchingLayerScratchMemory = getScratchMemory();
|
|
1136
|
-
this._textureTranscoder = cfg.textureTranscoder || getKTX2TextureTranscoder(this.scene.viewer);
|
|
1137
|
-
|
|
1138
|
-
this._maxGeometryBatchSize = cfg.maxGeometryBatchSize;
|
|
1139
|
-
|
|
1140
|
-
this._aabb = math.collapseAABB3();
|
|
1141
|
-
this._aabbDirty = true;
|
|
1142
|
-
|
|
1143
|
-
this._quantizationRanges = {};
|
|
1144
|
-
|
|
1145
|
-
this._vboInstancingLayers = {};
|
|
1146
|
-
this._vboBatchingLayers = {};
|
|
1147
|
-
this._dtxLayers = {};
|
|
1148
|
-
|
|
1149
|
-
this.layerList = []; // For GL state efficiency when drawing, InstancingLayers are in first part, BatchingLayers are in second
|
|
1150
|
-
this._entityList = [];
|
|
1151
|
-
|
|
1152
|
-
this._geometries = {};
|
|
1153
|
-
this._dtxBuckets = {}; // Geometries with optimizations used for data texture representation
|
|
1154
|
-
this._textures = {};
|
|
1155
|
-
this._textureSets = {};
|
|
1156
|
-
this._transforms = {};
|
|
1157
|
-
this._meshes = {};
|
|
1158
|
-
this._entities = {};
|
|
1159
|
-
|
|
1160
|
-
this._scheduledMeshes = {};
|
|
1161
|
-
this._meshesCfgsBeforeMeshCreation = {};
|
|
1162
|
-
|
|
1163
|
-
/** @private **/
|
|
1164
|
-
this.renderFlags = new RenderFlags();
|
|
1165
|
-
|
|
1166
|
-
/**
|
|
1167
|
-
* @private
|
|
1168
|
-
*/
|
|
1169
|
-
this.numGeometries = 0; // Number of geometries created with createGeometry()
|
|
1170
|
-
|
|
1171
|
-
// These counts are used to avoid unnecessary render passes
|
|
1172
|
-
// They are incremented or decremented exclusively by BatchingLayer and InstancingLayer
|
|
1173
|
-
|
|
1174
|
-
/**
|
|
1175
|
-
* @private
|
|
1176
|
-
*/
|
|
1177
|
-
this.numPortions = 0;
|
|
1178
|
-
|
|
1179
|
-
/**
|
|
1180
|
-
* @private
|
|
1181
|
-
*/
|
|
1182
|
-
this.numVisibleLayerPortions = 0;
|
|
1183
|
-
|
|
1184
|
-
/**
|
|
1185
|
-
* @private
|
|
1186
|
-
*/
|
|
1187
|
-
this.numTransparentLayerPortions = 0;
|
|
1188
|
-
|
|
1189
|
-
/**
|
|
1190
|
-
* @private
|
|
1191
|
-
*/
|
|
1192
|
-
this.numXRayedLayerPortions = 0;
|
|
1193
|
-
|
|
1194
|
-
/**
|
|
1195
|
-
* @private
|
|
1196
|
-
*/
|
|
1197
|
-
this.numHighlightedLayerPortions = 0;
|
|
1198
|
-
|
|
1199
|
-
/**
|
|
1200
|
-
* @private
|
|
1201
|
-
*/
|
|
1202
|
-
this.numSelectedLayerPortions = 0;
|
|
1203
|
-
|
|
1204
|
-
/**
|
|
1205
|
-
* @private
|
|
1206
|
-
*/
|
|
1207
|
-
this.numEdgesLayerPortions = 0;
|
|
1208
|
-
|
|
1209
|
-
/**
|
|
1210
|
-
* @private
|
|
1211
|
-
*/
|
|
1212
|
-
this.numPickableLayerPortions = 0;
|
|
1213
|
-
|
|
1214
|
-
/**
|
|
1215
|
-
* @private
|
|
1216
|
-
*/
|
|
1217
|
-
this.numClippableLayerPortions = 0;
|
|
1218
|
-
|
|
1219
|
-
/**
|
|
1220
|
-
* @private
|
|
1221
|
-
*/
|
|
1222
|
-
this.numCulledLayerPortions = 0;
|
|
1223
|
-
|
|
1224
|
-
this.numEntities = 0;
|
|
1225
|
-
this._numTriangles = 0;
|
|
1226
|
-
this._numLines = 0;
|
|
1227
|
-
this._numPoints = 0;
|
|
1228
|
-
|
|
1229
|
-
this._edgeThreshold = cfg.edgeThreshold || 10;
|
|
1230
|
-
|
|
1231
|
-
// Build static matrix
|
|
1232
|
-
|
|
1233
|
-
this._origin = math.vec3(cfg.origin || [0, 0, 0]);
|
|
1234
|
-
this._position = math.vec3(cfg.position || [0, 0, 0]);
|
|
1235
|
-
this._rotation = math.vec3(cfg.rotation || [0, 0, 0]);
|
|
1236
|
-
this._quaternion = math.vec4(cfg.quaternion || [0, 0, 0, 1]);
|
|
1237
|
-
this._conjugateQuaternion = math.vec4(cfg.quaternion || [0, 0, 0, 1]);
|
|
1238
|
-
|
|
1239
|
-
if (cfg.rotation) {
|
|
1240
|
-
math.eulerToQuaternion(this._rotation, "XYZ", this._quaternion);
|
|
1241
|
-
}
|
|
1242
|
-
this._scale = math.vec3(cfg.scale || [1, 1, 1]);
|
|
1243
|
-
|
|
1244
|
-
this._worldRotationMatrix = math.mat4();
|
|
1245
|
-
this._worldRotationMatrixConjugate = math.mat4();
|
|
1246
|
-
this._matrix = math.mat4();
|
|
1247
|
-
this._matrixDirty = true;
|
|
1248
|
-
|
|
1249
|
-
this._rebuildMatrices();
|
|
1250
|
-
|
|
1251
|
-
this._worldNormalMatrix = math.mat4();
|
|
1252
|
-
math.inverseMat4(this._matrix, this._worldNormalMatrix);
|
|
1253
|
-
math.transposeMat4(this._worldNormalMatrix);
|
|
1254
|
-
|
|
1255
|
-
if (cfg.matrix || cfg.position || cfg.rotation || cfg.scale || cfg.quaternion) {
|
|
1256
|
-
this._viewMatrix = math.mat4();
|
|
1257
|
-
this._viewNormalMatrix = math.mat4();
|
|
1258
|
-
this._viewMatrixDirty = true;
|
|
1259
|
-
this._matrixNonIdentity = true;
|
|
1260
|
-
}
|
|
1261
|
-
|
|
1262
|
-
this._opacity = 1.0;
|
|
1263
|
-
this._colorize = [1, 1, 1];
|
|
1264
|
-
|
|
1265
|
-
this._saoEnabled = (cfg.saoEnabled !== false);
|
|
1266
|
-
this._pbrEnabled = (cfg.pbrEnabled !== false);
|
|
1267
|
-
this._colorTextureEnabled = (cfg.colorTextureEnabled !== false);
|
|
1268
|
-
|
|
1269
|
-
this._isModel = cfg.isModel;
|
|
1270
|
-
if (this._isModel) {
|
|
1271
|
-
this.scene._registerModel(this);
|
|
1272
|
-
}
|
|
1273
|
-
|
|
1274
|
-
this._onCameraViewMatrix = this.scene.camera.on("matrix", () => {
|
|
1275
|
-
this._viewMatrixDirty = true;
|
|
1276
|
-
});
|
|
1277
|
-
|
|
1278
|
-
this._meshesWithDirtyMatrices = [];
|
|
1279
|
-
this._numMeshesWithDirtyMatrices = 0;
|
|
1280
|
-
|
|
1281
|
-
this._onTick = this.scene.on("tick", () => {
|
|
1282
|
-
while (this._numMeshesWithDirtyMatrices > 0) {
|
|
1283
|
-
this._meshesWithDirtyMatrices[--this._numMeshesWithDirtyMatrices]._updateMatrix();
|
|
1284
|
-
}
|
|
1285
|
-
});
|
|
1286
|
-
|
|
1287
|
-
this._createDefaultTextureSet();
|
|
1288
|
-
|
|
1289
|
-
this.visible = cfg.visible;
|
|
1290
|
-
this.culled = cfg.culled;
|
|
1291
|
-
this.pickable = cfg.pickable;
|
|
1292
|
-
this.clippable = cfg.clippable;
|
|
1293
|
-
this.collidable = cfg.collidable;
|
|
1294
|
-
this.castsShadow = cfg.castsShadow;
|
|
1295
|
-
this.receivesShadow = cfg.receivesShadow;
|
|
1296
|
-
this.xrayed = cfg.xrayed;
|
|
1297
|
-
this.highlighted = cfg.highlighted;
|
|
1298
|
-
this.selected = cfg.selected;
|
|
1299
|
-
this.edges = cfg.edges;
|
|
1300
|
-
this.colorize = cfg.colorize;
|
|
1301
|
-
this.opacity = cfg.opacity;
|
|
1302
|
-
this.backfaces = cfg.backfaces;
|
|
1303
|
-
}
|
|
1304
|
-
|
|
1305
|
-
_meshMatrixDirty(mesh) {
|
|
1306
|
-
this._meshesWithDirtyMatrices[this._numMeshesWithDirtyMatrices++] = mesh;
|
|
1307
|
-
}
|
|
1308
|
-
|
|
1309
|
-
_createDefaultTextureSet() {
|
|
1310
|
-
// Every SceneModelMesh gets at least the default TextureSet,
|
|
1311
|
-
// which contains empty default textures filled with color
|
|
1312
|
-
const defaultColorTexture = new SceneModelTexture({
|
|
1313
|
-
id: DEFAULT_COLOR_TEXTURE_ID,
|
|
1314
|
-
texture: new Texture2D({
|
|
1315
|
-
gl: this.scene.canvas.gl,
|
|
1316
|
-
preloadColor: [1, 1, 1, 1] // [r, g, b, a]})
|
|
1317
|
-
})
|
|
1318
|
-
});
|
|
1319
|
-
const defaultMetalRoughTexture = new SceneModelTexture({
|
|
1320
|
-
id: DEFAULT_METAL_ROUGH_TEXTURE_ID,
|
|
1321
|
-
texture: new Texture2D({
|
|
1322
|
-
gl: this.scene.canvas.gl,
|
|
1323
|
-
preloadColor: [0, 1, 1, 1] // [unused, roughness, metalness, unused]
|
|
1324
|
-
})
|
|
1325
|
-
});
|
|
1326
|
-
const defaultNormalsTexture = new SceneModelTexture({
|
|
1327
|
-
id: DEFAULT_NORMALS_TEXTURE_ID,
|
|
1328
|
-
texture: new Texture2D({
|
|
1329
|
-
gl: this.scene.canvas.gl,
|
|
1330
|
-
preloadColor: [0, 0, 0, 0] // [x, y, z, unused] - these must be zeros
|
|
1331
|
-
})
|
|
1332
|
-
});
|
|
1333
|
-
const defaultEmissiveTexture = new SceneModelTexture({
|
|
1334
|
-
id: DEFAULT_EMISSIVE_TEXTURE_ID,
|
|
1335
|
-
texture: new Texture2D({
|
|
1336
|
-
gl: this.scene.canvas.gl,
|
|
1337
|
-
preloadColor: [0, 0, 0, 1] // [x, y, z, unused]
|
|
1338
|
-
})
|
|
1339
|
-
});
|
|
1340
|
-
const defaultOcclusionTexture = new SceneModelTexture({
|
|
1341
|
-
id: DEFAULT_OCCLUSION_TEXTURE_ID,
|
|
1342
|
-
texture: new Texture2D({
|
|
1343
|
-
gl: this.scene.canvas.gl,
|
|
1344
|
-
preloadColor: [1, 1, 1, 1] // [x, y, z, unused]
|
|
1345
|
-
})
|
|
1346
|
-
});
|
|
1347
|
-
this._textures[DEFAULT_COLOR_TEXTURE_ID] = defaultColorTexture;
|
|
1348
|
-
this._textures[DEFAULT_METAL_ROUGH_TEXTURE_ID] = defaultMetalRoughTexture;
|
|
1349
|
-
this._textures[DEFAULT_NORMALS_TEXTURE_ID] = defaultNormalsTexture;
|
|
1350
|
-
this._textures[DEFAULT_EMISSIVE_TEXTURE_ID] = defaultEmissiveTexture;
|
|
1351
|
-
this._textures[DEFAULT_OCCLUSION_TEXTURE_ID] = defaultOcclusionTexture;
|
|
1352
|
-
this._textureSets[DEFAULT_TEXTURE_SET_ID] = new SceneModelTextureSet({
|
|
1353
|
-
id: DEFAULT_TEXTURE_SET_ID,
|
|
1354
|
-
model: this,
|
|
1355
|
-
colorTexture: defaultColorTexture,
|
|
1356
|
-
metallicRoughnessTexture: defaultMetalRoughTexture,
|
|
1357
|
-
normalsTexture: defaultNormalsTexture,
|
|
1358
|
-
emissiveTexture: defaultEmissiveTexture,
|
|
1359
|
-
occlusionTexture: defaultOcclusionTexture
|
|
1360
|
-
});
|
|
1361
|
-
}
|
|
1362
|
-
|
|
1363
|
-
//------------------------------------------------------------------------------------------------------------------
|
|
1364
|
-
// SceneModel members
|
|
1365
|
-
//------------------------------------------------------------------------------------------------------------------
|
|
1366
|
-
|
|
1367
|
-
/**
|
|
1368
|
-
* Returns true to indicate that this Component is a SceneModel.
|
|
1369
|
-
* @type {Boolean}
|
|
1370
|
-
*/
|
|
1371
|
-
get isPerformanceModel() {
|
|
1372
|
-
return true;
|
|
1373
|
-
}
|
|
1374
|
-
|
|
1375
|
-
/**
|
|
1376
|
-
* The {@link SceneModelTransform}s in this SceneModel.
|
|
1377
|
-
*
|
|
1378
|
-
* Each {#link SceneModelTransform} is stored here against its {@link SceneModelTransform.id}.
|
|
1379
|
-
*
|
|
1380
|
-
* @returns {*|{}}
|
|
1381
|
-
*/
|
|
1382
|
-
get transforms() {
|
|
1383
|
-
return this._transforms;
|
|
1384
|
-
}
|
|
1385
|
-
|
|
1386
|
-
/**
|
|
1387
|
-
* The {@link SceneModelTexture}s in this SceneModel.
|
|
1388
|
-
*
|
|
1389
|
-
* * Each {@link SceneModelTexture} is created with {@link SceneModel.createTexture}.
|
|
1390
|
-
* * Each {@link SceneModelTexture} is stored here against its {@link SceneModelTexture.id}.
|
|
1391
|
-
*
|
|
1392
|
-
* @returns {*|{}}
|
|
1393
|
-
*/
|
|
1394
|
-
get textures() {
|
|
1395
|
-
return this._textures;
|
|
1396
|
-
}
|
|
1397
|
-
|
|
1398
|
-
/**
|
|
1399
|
-
* The {@link SceneModelTextureSet}s in this SceneModel.
|
|
1400
|
-
*
|
|
1401
|
-
* Each {@link SceneModelTextureSet} is stored here against its {@link SceneModelTextureSet.id}.
|
|
1402
|
-
*
|
|
1403
|
-
* @returns {*|{}}
|
|
1404
|
-
*/
|
|
1405
|
-
get textureSets() {
|
|
1406
|
-
return this._textureSets;
|
|
1407
|
-
}
|
|
1408
|
-
|
|
1409
|
-
/**
|
|
1410
|
-
* The {@link SceneModelMesh}es in this SceneModel.
|
|
1411
|
-
*
|
|
1412
|
-
* Each {@SceneModelMesh} is stored here against its {@link SceneModelMesh.id}.
|
|
1413
|
-
*
|
|
1414
|
-
* @returns {*|{}}
|
|
1415
|
-
*/
|
|
1416
|
-
get meshes() {
|
|
1417
|
-
return this._meshes;
|
|
1418
|
-
}
|
|
1419
|
-
|
|
1420
|
-
/**
|
|
1421
|
-
* The {@link SceneModelEntity}s in this SceneModel.
|
|
1422
|
-
*
|
|
1423
|
-
* Each {#link SceneModelEntity} in this SceneModel that represents an object is
|
|
1424
|
-
* stored here against its {@link SceneModelTransform.id}.
|
|
1425
|
-
*
|
|
1426
|
-
* @returns {*|{}}
|
|
1427
|
-
*/
|
|
1428
|
-
get objects() {
|
|
1429
|
-
return this._entities;
|
|
1430
|
-
}
|
|
1431
|
-
|
|
1432
|
-
/**
|
|
1433
|
-
* Gets the 3D World-space origin for this SceneModel.
|
|
1434
|
-
*
|
|
1435
|
-
* Each {@link SceneModelMesh.origin}, if supplied, is relative to this origin.
|
|
1436
|
-
*
|
|
1437
|
-
* Default value is ````[0,0,0]````.
|
|
1438
|
-
*
|
|
1439
|
-
* @type {Float64Array}
|
|
1440
|
-
*/
|
|
1441
|
-
get origin() {
|
|
1442
|
-
return this._origin;
|
|
1443
|
-
}
|
|
1444
|
-
|
|
1445
|
-
/**
|
|
1446
|
-
* Sets the SceneModel's local translation.
|
|
1447
|
-
*
|
|
1448
|
-
* Default value is ````[0,0,0]````.
|
|
1449
|
-
*
|
|
1450
|
-
* @type {Number[]}
|
|
1451
|
-
*/
|
|
1452
|
-
set position(value) {
|
|
1453
|
-
this._position.set(value || [0, 0, 0]);
|
|
1454
|
-
this._setWorldMatrixDirty();
|
|
1455
|
-
this._sceneModelDirty();
|
|
1456
|
-
this.glRedraw();
|
|
1457
|
-
}
|
|
1458
|
-
|
|
1459
|
-
/**
|
|
1460
|
-
* Gets the SceneModel's local translation.
|
|
1461
|
-
*
|
|
1462
|
-
* Default value is ````[0,0,0]````.
|
|
1463
|
-
*
|
|
1464
|
-
* @type {Number[]}
|
|
1465
|
-
*/
|
|
1466
|
-
get position() {
|
|
1467
|
-
return this._position;
|
|
1468
|
-
}
|
|
1469
|
-
|
|
1470
|
-
/**
|
|
1471
|
-
* Sets the SceneModel's local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.
|
|
1472
|
-
*
|
|
1473
|
-
* Default value is ````[0,0,0]````.
|
|
1474
|
-
*
|
|
1475
|
-
* @type {Number[]}
|
|
1476
|
-
*/
|
|
1477
|
-
set rotation(value) {
|
|
1478
|
-
this._rotation.set(value || [0, 0, 0]);
|
|
1479
|
-
math.eulerToQuaternion(this._rotation, "XYZ", this._quaternion);
|
|
1480
|
-
this._setWorldMatrixDirty();
|
|
1481
|
-
this._sceneModelDirty();
|
|
1482
|
-
this.glRedraw();
|
|
1483
|
-
}
|
|
1484
|
-
|
|
1485
|
-
/**
|
|
1486
|
-
* Gets the SceneModel's local rotation, as Euler angles given in degrees, for each of the X, Y and Z axis.
|
|
1487
|
-
*
|
|
1488
|
-
* Default value is ````[0,0,0]````.
|
|
1489
|
-
*
|
|
1490
|
-
* @type {Number[]}
|
|
1491
|
-
*/
|
|
1492
|
-
get rotation() {
|
|
1493
|
-
return this._rotation;
|
|
1494
|
-
}
|
|
1495
|
-
|
|
1496
|
-
/**
|
|
1497
|
-
* Sets the SceneModel's local rotation quaternion.
|
|
1498
|
-
*
|
|
1499
|
-
* Default value is ````[0,0,0,1]````.
|
|
1500
|
-
*
|
|
1501
|
-
* @type {Number[]}
|
|
1502
|
-
*/
|
|
1503
|
-
set quaternion(value) {
|
|
1504
|
-
this._quaternion.set(value || [0, 0, 0, 1]);
|
|
1505
|
-
math.quaternionToEuler(this._quaternion, "XYZ", this._rotation);
|
|
1506
|
-
this._setWorldMatrixDirty();
|
|
1507
|
-
this._sceneModelDirty();
|
|
1508
|
-
this.glRedraw();
|
|
1509
|
-
}
|
|
1510
|
-
|
|
1511
|
-
/**
|
|
1512
|
-
* Gets the SceneModel's local rotation quaternion.
|
|
1513
|
-
*
|
|
1514
|
-
* Default value is ````[0,0,0,1]````.
|
|
1515
|
-
*
|
|
1516
|
-
* @type {Number[]}
|
|
1517
|
-
*/
|
|
1518
|
-
get quaternion() {
|
|
1519
|
-
return this._quaternion;
|
|
1520
|
-
}
|
|
1521
|
-
|
|
1522
|
-
/**
|
|
1523
|
-
* Sets the SceneModel's local scale.
|
|
1524
|
-
*
|
|
1525
|
-
* Default value is ````[1,1,1]````.
|
|
1526
|
-
*
|
|
1527
|
-
* @type {Number[]}
|
|
1528
|
-
* @deprecated
|
|
1529
|
-
*/
|
|
1530
|
-
set scale(value) {
|
|
1531
|
-
// NOP - deprecated
|
|
1532
|
-
}
|
|
1533
|
-
|
|
1534
|
-
/**
|
|
1535
|
-
* Gets the SceneModel's local scale.
|
|
1536
|
-
*
|
|
1537
|
-
* Default value is ````[1,1,1]````.
|
|
1538
|
-
*
|
|
1539
|
-
* @type {Number[]}
|
|
1540
|
-
* @deprecated
|
|
1541
|
-
*/
|
|
1542
|
-
get scale() {
|
|
1543
|
-
return this._scale;
|
|
1544
|
-
}
|
|
1545
|
-
|
|
1546
|
-
/**
|
|
1547
|
-
* Sets the SceneModel's local modeling transform matrix.
|
|
1548
|
-
*
|
|
1549
|
-
* Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.
|
|
1550
|
-
*
|
|
1551
|
-
* @type {Number[]}
|
|
1552
|
-
*/
|
|
1553
|
-
set matrix(value) {
|
|
1554
|
-
this._matrix.set(value || DEFAULT_MATRIX);
|
|
1555
|
-
|
|
1556
|
-
math.quaternionToRotationMat4(this._quaternion, this._worldRotationMatrix);
|
|
1557
|
-
math.conjugateQuaternion(this._quaternion, this._conjugateQuaternion);
|
|
1558
|
-
math.quaternionToRotationMat4(this._quaternion, this._worldRotationMatrixConjugate);
|
|
1559
|
-
this._matrix.set(this._worldRotationMatrix);
|
|
1560
|
-
math.translateMat4v(this._position, this._matrix);
|
|
1561
|
-
|
|
1562
|
-
this._matrixDirty = false;
|
|
1563
|
-
this._setWorldMatrixDirty();
|
|
1564
|
-
this._sceneModelDirty();
|
|
1565
|
-
this.glRedraw();
|
|
1566
|
-
}
|
|
1567
|
-
|
|
1568
|
-
/**
|
|
1569
|
-
* Gets the SceneModel's local modeling transform matrix.
|
|
1570
|
-
*
|
|
1571
|
-
* Default value is ````[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]````.
|
|
1572
|
-
*
|
|
1573
|
-
* @type {Number[]}
|
|
1574
|
-
*/
|
|
1575
|
-
get matrix() {
|
|
1576
|
-
if (this._matrixDirty) {
|
|
1577
|
-
this._rebuildMatrices();
|
|
1578
|
-
}
|
|
1579
|
-
return this._matrix;
|
|
1580
|
-
}
|
|
1581
|
-
|
|
1582
|
-
/**
|
|
1583
|
-
* Gets the SceneModel's local modeling rotation transform matrix.
|
|
1584
|
-
*
|
|
1585
|
-
* @type {Number[]}
|
|
1586
|
-
*/
|
|
1587
|
-
get rotationMatrix() {
|
|
1588
|
-
if (this._matrixDirty) {
|
|
1589
|
-
this._rebuildMatrices();
|
|
1590
|
-
}
|
|
1591
|
-
return this._worldRotationMatrix;
|
|
1592
|
-
}
|
|
1593
|
-
|
|
1594
|
-
_rebuildMatrices() {
|
|
1595
|
-
if (this._matrixDirty) {
|
|
1596
|
-
math.quaternionToRotationMat4(this._quaternion, this._worldRotationMatrix);
|
|
1597
|
-
math.conjugateQuaternion(this._quaternion, this._conjugateQuaternion);
|
|
1598
|
-
math.quaternionToRotationMat4(this._quaternion, this._worldRotationMatrixConjugate);
|
|
1599
|
-
this._matrix.set(this._worldRotationMatrix);
|
|
1600
|
-
math.translateMat4v(this._position, this._matrix);
|
|
1601
|
-
this._matrixDirty = false;
|
|
1602
|
-
}
|
|
1603
|
-
}
|
|
1604
|
-
|
|
1605
|
-
/**
|
|
1606
|
-
* Gets the conjugate of the SceneModel's local modeling rotation transform matrix.
|
|
1607
|
-
*
|
|
1608
|
-
* This is used for RTC view matrix management in renderers.
|
|
1609
|
-
*
|
|
1610
|
-
* @type {Number[]}
|
|
1611
|
-
*/
|
|
1612
|
-
get rotationMatrixConjugate() {
|
|
1613
|
-
if (this._matrixDirty) {
|
|
1614
|
-
this._rebuildMatrices();
|
|
1615
|
-
}
|
|
1616
|
-
return this._worldRotationMatrixConjugate;
|
|
1617
|
-
}
|
|
1618
|
-
|
|
1619
|
-
_setWorldMatrixDirty() {
|
|
1620
|
-
this._matrixDirty = true;
|
|
1621
|
-
this._aabbDirty = true;
|
|
1622
|
-
}
|
|
1623
|
-
|
|
1624
|
-
_transformDirty() {
|
|
1625
|
-
this._matrixDirty = true;
|
|
1626
|
-
this._aabbDirty = true;
|
|
1627
|
-
this.scene._aabbDirty = true;
|
|
1628
|
-
}
|
|
1629
|
-
|
|
1630
|
-
_sceneModelDirty() {
|
|
1631
|
-
this.scene._aabbDirty = true;
|
|
1632
|
-
this._aabbDirty = true;
|
|
1633
|
-
this.scene._aabbDirty = true;
|
|
1634
|
-
this._matrixDirty = true;
|
|
1635
|
-
for (let i = 0, len = this._entityList.length; i < len; i++) {
|
|
1636
|
-
this._entityList[i]._sceneModelDirty(); // Entities need to retransform their World AABBs by SceneModel's worldMatrix
|
|
1637
|
-
}
|
|
1638
|
-
}
|
|
1639
|
-
|
|
1640
|
-
/**
|
|
1641
|
-
* Gets the SceneModel's World matrix.
|
|
1642
|
-
*
|
|
1643
|
-
* @property worldMatrix
|
|
1644
|
-
* @type {Number[]}
|
|
1645
|
-
*/
|
|
1646
|
-
get worldMatrix() {
|
|
1647
|
-
return this.matrix;
|
|
1648
|
-
}
|
|
1649
|
-
|
|
1650
|
-
/**
|
|
1651
|
-
* Gets the SceneModel's World normal matrix.
|
|
1652
|
-
*
|
|
1653
|
-
* @type {Number[]}
|
|
1654
|
-
*/
|
|
1655
|
-
get worldNormalMatrix() {
|
|
1656
|
-
return this._worldNormalMatrix;
|
|
1657
|
-
}
|
|
1658
|
-
|
|
1659
|
-
/**
|
|
1660
|
-
* Called by private renderers in ./lib, returns the view matrix with which to
|
|
1661
|
-
* render this SceneModel. The view matrix is the concatenation of the
|
|
1662
|
-
* Camera view matrix with the Performance model's world (modeling) matrix.
|
|
1663
|
-
*
|
|
1664
|
-
* @private
|
|
1665
|
-
*/
|
|
1666
|
-
get viewMatrix() {
|
|
1667
|
-
if (!this._viewMatrix) {
|
|
1668
|
-
return this.scene.camera.viewMatrix;
|
|
1669
|
-
}
|
|
1670
|
-
if (this._matrixDirty) {
|
|
1671
|
-
this._rebuildMatrices();
|
|
1672
|
-
this._viewMatrixDirty = true;
|
|
1673
|
-
}
|
|
1674
|
-
if (this._viewMatrixDirty) {
|
|
1675
|
-
math.mulMat4(this.scene.camera.viewMatrix, this._matrix, this._viewMatrix);
|
|
1676
|
-
math.inverseMat4(this._viewMatrix, this._viewNormalMatrix);
|
|
1677
|
-
math.transposeMat4(this._viewNormalMatrix);
|
|
1678
|
-
this._viewMatrixDirty = false;
|
|
1679
|
-
}
|
|
1680
|
-
return this._viewMatrix;
|
|
1681
|
-
}
|
|
1682
|
-
|
|
1683
|
-
/**
|
|
1684
|
-
* Called by private renderers in ./lib, returns the view normal matrix with which to render this SceneModel.
|
|
1685
|
-
*
|
|
1686
|
-
* @private
|
|
1687
|
-
*/
|
|
1688
|
-
get viewNormalMatrix() {
|
|
1689
|
-
if (!this._viewNormalMatrix) {
|
|
1690
|
-
return this.scene.camera.viewNormalMatrix;
|
|
1691
|
-
}
|
|
1692
|
-
if (this._matrixDirty) {
|
|
1693
|
-
this._rebuildMatrices();
|
|
1694
|
-
this._viewMatrixDirty = true;
|
|
1695
|
-
}
|
|
1696
|
-
if (this._viewMatrixDirty) {
|
|
1697
|
-
math.mulMat4(this.scene.camera.viewMatrix, this._matrix, this._viewMatrix);
|
|
1698
|
-
math.inverseMat4(this._viewMatrix, this._viewNormalMatrix);
|
|
1699
|
-
math.transposeMat4(this._viewNormalMatrix);
|
|
1700
|
-
this._viewMatrixDirty = false;
|
|
1701
|
-
}
|
|
1702
|
-
math.inverseMat4(this._viewMatrix, this._viewNormalMatrix);
|
|
1703
|
-
math.transposeMat4(this._viewNormalMatrix);
|
|
1704
|
-
return this._viewNormalMatrix;
|
|
1705
|
-
}
|
|
1706
|
-
|
|
1707
|
-
/**
|
|
1708
|
-
* Sets if backfaces are rendered for this SceneModel.
|
|
1709
|
-
*
|
|
1710
|
-
* Default is ````false````.
|
|
1711
|
-
*
|
|
1712
|
-
* @type {Boolean}
|
|
1713
|
-
*/
|
|
1714
|
-
get backfaces() {
|
|
1715
|
-
return this._backfaces;
|
|
1716
|
-
}
|
|
1717
|
-
|
|
1718
|
-
/**
|
|
1719
|
-
* Sets if backfaces are rendered for this SceneModel.
|
|
1720
|
-
*
|
|
1721
|
-
* Default is ````false````.
|
|
1722
|
-
*
|
|
1723
|
-
* When we set this ````true````, then backfaces are always rendered for this SceneModel.
|
|
1724
|
-
*
|
|
1725
|
-
* When we set this ````false````, then we allow the Viewer to decide whether to render backfaces. In this case,
|
|
1726
|
-
* the Viewer will:
|
|
1727
|
-
*
|
|
1728
|
-
* * hide backfaces on watertight meshes,
|
|
1729
|
-
* * show backfaces on open meshes, and
|
|
1730
|
-
* * always show backfaces on meshes when we slice them open with {@link SectionPlane}s.
|
|
1731
|
-
*
|
|
1732
|
-
* @type {Boolean}
|
|
1733
|
-
*/
|
|
1734
|
-
set backfaces(backfaces) {
|
|
1735
|
-
backfaces = !!backfaces;
|
|
1736
|
-
this._backfaces = backfaces;
|
|
1737
|
-
this.glRedraw();
|
|
1738
|
-
}
|
|
1739
|
-
|
|
1740
|
-
/**
|
|
1741
|
-
* Gets the list of {@link SceneModelEntity}s within this SceneModel.
|
|
1742
|
-
*
|
|
1743
|
-
* @returns {SceneModelEntity[]}
|
|
1744
|
-
*/
|
|
1745
|
-
get entityList() {
|
|
1746
|
-
return this._entityList;
|
|
1747
|
-
}
|
|
1748
|
-
|
|
1749
|
-
/**
|
|
1750
|
-
* Returns true to indicate that SceneModel is an {@link Entity}.
|
|
1751
|
-
* @type {Boolean}
|
|
1752
|
-
*/
|
|
1753
|
-
get isEntity() {
|
|
1754
|
-
return true;
|
|
1755
|
-
}
|
|
1756
|
-
|
|
1757
|
-
/**
|
|
1758
|
-
* Returns ````true```` if this SceneModel represents a model.
|
|
1759
|
-
*
|
|
1760
|
-
* When ````true```` the SceneModel will be registered by {@link SceneModel#id} in
|
|
1761
|
-
* {@link Scene#models} and may also have a {@link MetaObject} with matching {@link MetaObject#id}.
|
|
1762
|
-
*
|
|
1763
|
-
* @type {Boolean}
|
|
1764
|
-
*/
|
|
1765
|
-
get isModel() {
|
|
1766
|
-
return this._isModel;
|
|
1767
|
-
}
|
|
1768
|
-
|
|
1769
|
-
//------------------------------------------------------------------------------------------------------------------
|
|
1770
|
-
// SceneModel members
|
|
1771
|
-
//------------------------------------------------------------------------------------------------------------------
|
|
1772
|
-
|
|
1773
|
-
/**
|
|
1774
|
-
* Returns ````false```` to indicate that SceneModel never represents an object.
|
|
1775
|
-
*
|
|
1776
|
-
* @type {Boolean}
|
|
1777
|
-
*/
|
|
1778
|
-
get isObject() {
|
|
1779
|
-
return false;
|
|
1780
|
-
}
|
|
1781
|
-
|
|
1782
|
-
/**
|
|
1783
|
-
* Gets the SceneModel's World-space 3D axis-aligned bounding box.
|
|
1784
|
-
*
|
|
1785
|
-
* Represented by a six-element Float64Array containing the min/max extents of the
|
|
1786
|
-
* axis-aligned volume, ie. ````[xmin, ymin,zmin,xmax,ymax, zmax]````.
|
|
1787
|
-
*
|
|
1788
|
-
* @type {Number[]}
|
|
1789
|
-
*/
|
|
1790
|
-
get aabb() {
|
|
1791
|
-
if (this._aabbDirty) {
|
|
1792
|
-
math.collapseAABB3(this._aabb);
|
|
1793
|
-
for (let i = 0, len = this._entityList.length; i < len; i++) {
|
|
1794
|
-
math.expandAABB3(this._aabb, this._entityList[i].aabb);
|
|
1795
|
-
}
|
|
1796
|
-
this._aabbDirty = false;
|
|
1797
|
-
}
|
|
1798
|
-
return this._aabb;
|
|
1799
|
-
}
|
|
1800
|
-
|
|
1801
|
-
/**
|
|
1802
|
-
* The approximate number of triangle primitives in this SceneModel.
|
|
1803
|
-
*
|
|
1804
|
-
* @type {Number}
|
|
1805
|
-
*/
|
|
1806
|
-
get numTriangles() {
|
|
1807
|
-
return this._numTriangles;
|
|
1808
|
-
}
|
|
1809
|
-
|
|
1810
|
-
//------------------------------------------------------------------------------------------------------------------
|
|
1811
|
-
// Entity members
|
|
1812
|
-
//------------------------------------------------------------------------------------------------------------------
|
|
1813
|
-
|
|
1814
|
-
/**
|
|
1815
|
-
* The approximate number of line primitives in this SceneModel.
|
|
1816
|
-
*
|
|
1817
|
-
* @type {Number}
|
|
1818
|
-
*/
|
|
1819
|
-
get numLines() {
|
|
1820
|
-
return this._numLines;
|
|
1821
|
-
}
|
|
1822
|
-
|
|
1823
|
-
/**
|
|
1824
|
-
* The approximate number of point primitives in this SceneModel.
|
|
1825
|
-
*
|
|
1826
|
-
* @type {Number}
|
|
1827
|
-
*/
|
|
1828
|
-
get numPoints() {
|
|
1829
|
-
return this._numPoints;
|
|
1830
|
-
}
|
|
1831
|
-
|
|
1832
|
-
/**
|
|
1833
|
-
* Gets if any {@link SceneModelEntity}s in this SceneModel are visible.
|
|
1834
|
-
*
|
|
1835
|
-
* The SceneModel is only rendered when {@link SceneModel#visible} is ````true```` and {@link SceneModel#culled} is ````false````.
|
|
1836
|
-
*
|
|
1837
|
-
* @type {Boolean}
|
|
1838
|
-
*/
|
|
1839
|
-
get visible() {
|
|
1840
|
-
return (this.numVisibleLayerPortions > 0);
|
|
1841
|
-
}
|
|
1842
|
-
|
|
1843
|
-
/**
|
|
1844
|
-
* Sets if this SceneModel is visible.
|
|
1845
|
-
*
|
|
1846
|
-
* The SceneModel is only rendered when {@link SceneModel#visible} is ````true```` and {@link SceneModel#culled} is ````false````.
|
|
1847
|
-
**
|
|
1848
|
-
* @type {Boolean}
|
|
1849
|
-
*/
|
|
1850
|
-
set visible(visible) {
|
|
1851
|
-
visible = visible !== false;
|
|
1852
|
-
this._visible = visible;
|
|
1853
|
-
for (let i = 0, len = this._entityList.length; i < len; i++) {
|
|
1854
|
-
this._entityList[i].visible = visible;
|
|
1855
|
-
}
|
|
1856
|
-
this.glRedraw();
|
|
1857
|
-
}
|
|
1858
|
-
|
|
1859
|
-
/**
|
|
1860
|
-
* Gets if any {@link SceneModelEntity}s in this SceneModel are xrayed.
|
|
1861
|
-
*
|
|
1862
|
-
* @type {Boolean}
|
|
1863
|
-
*/
|
|
1864
|
-
get xrayed() {
|
|
1865
|
-
return (this.numXRayedLayerPortions > 0);
|
|
1866
|
-
}
|
|
1867
|
-
|
|
1868
|
-
/**
|
|
1869
|
-
* Sets if all {@link SceneModelEntity}s in this SceneModel are xrayed.
|
|
1870
|
-
*
|
|
1871
|
-
* @type {Boolean}
|
|
1872
|
-
*/
|
|
1873
|
-
set xrayed(xrayed) {
|
|
1874
|
-
xrayed = !!xrayed;
|
|
1875
|
-
this._xrayed = xrayed;
|
|
1876
|
-
for (let i = 0, len = this._entityList.length; i < len; i++) {
|
|
1877
|
-
this._entityList[i].xrayed = xrayed;
|
|
1878
|
-
}
|
|
1879
|
-
this.glRedraw();
|
|
1880
|
-
}
|
|
1881
|
-
|
|
1882
|
-
/**
|
|
1883
|
-
* Gets if any {@link SceneModelEntity}s in this SceneModel are highlighted.
|
|
1884
|
-
*
|
|
1885
|
-
* @type {Boolean}
|
|
1886
|
-
*/
|
|
1887
|
-
get highlighted() {
|
|
1888
|
-
return (this.numHighlightedLayerPortions > 0);
|
|
1889
|
-
}
|
|
1890
|
-
|
|
1891
|
-
/**
|
|
1892
|
-
* Sets if all {@link SceneModelEntity}s in this SceneModel are highlighted.
|
|
1893
|
-
*
|
|
1894
|
-
* @type {Boolean}
|
|
1895
|
-
*/
|
|
1896
|
-
set highlighted(highlighted) {
|
|
1897
|
-
highlighted = !!highlighted;
|
|
1898
|
-
this._highlighted = highlighted;
|
|
1899
|
-
for (let i = 0, len = this._entityList.length; i < len; i++) {
|
|
1900
|
-
this._entityList[i].highlighted = highlighted;
|
|
1901
|
-
}
|
|
1902
|
-
this.glRedraw();
|
|
1903
|
-
}
|
|
1904
|
-
|
|
1905
|
-
/**
|
|
1906
|
-
* Gets if any {@link SceneModelEntity}s in this SceneModel are selected.
|
|
1907
|
-
*
|
|
1908
|
-
* @type {Boolean}
|
|
1909
|
-
*/
|
|
1910
|
-
get selected() {
|
|
1911
|
-
return (this.numSelectedLayerPortions > 0);
|
|
1912
|
-
}
|
|
1913
|
-
|
|
1914
|
-
/**
|
|
1915
|
-
* Sets if all {@link SceneModelEntity}s in this SceneModel are selected.
|
|
1916
|
-
*
|
|
1917
|
-
* @type {Boolean}
|
|
1918
|
-
*/
|
|
1919
|
-
set selected(selected) {
|
|
1920
|
-
selected = !!selected;
|
|
1921
|
-
this._selected = selected;
|
|
1922
|
-
for (let i = 0, len = this._entityList.length; i < len; i++) {
|
|
1923
|
-
this._entityList[i].selected = selected;
|
|
1924
|
-
}
|
|
1925
|
-
this.glRedraw();
|
|
1926
|
-
}
|
|
1927
|
-
|
|
1928
|
-
/**
|
|
1929
|
-
* Gets if any {@link SceneModelEntity}s in this SceneModel have edges emphasised.
|
|
1930
|
-
*
|
|
1931
|
-
* @type {Boolean}
|
|
1932
|
-
*/
|
|
1933
|
-
get edges() {
|
|
1934
|
-
return (this.numEdgesLayerPortions > 0);
|
|
1935
|
-
}
|
|
1936
|
-
|
|
1937
|
-
/**
|
|
1938
|
-
* Sets if all {@link SceneModelEntity}s in this SceneModel have edges emphasised.
|
|
1939
|
-
*
|
|
1940
|
-
* @type {Boolean}
|
|
1941
|
-
*/
|
|
1942
|
-
set edges(edges) {
|
|
1943
|
-
edges = !!edges;
|
|
1944
|
-
this._edges = edges;
|
|
1945
|
-
for (let i = 0, len = this._entityList.length; i < len; i++) {
|
|
1946
|
-
this._entityList[i].edges = edges;
|
|
1947
|
-
}
|
|
1948
|
-
this.glRedraw();
|
|
1949
|
-
}
|
|
1950
|
-
|
|
1951
|
-
/**
|
|
1952
|
-
* Gets if this SceneModel is culled from view.
|
|
1953
|
-
*
|
|
1954
|
-
* The SceneModel is only rendered when {@link SceneModel#visible} is true and {@link SceneModel#culled} is false.
|
|
1955
|
-
*
|
|
1956
|
-
* @type {Boolean}
|
|
1957
|
-
*/
|
|
1958
|
-
get culled() {
|
|
1959
|
-
return this._culled;
|
|
1960
|
-
}
|
|
1961
|
-
|
|
1962
|
-
/**
|
|
1963
|
-
* Sets if this SceneModel is culled from view.
|
|
1964
|
-
*
|
|
1965
|
-
* The SceneModel is only rendered when {@link SceneModel#visible} is true and {@link SceneModel#culled} is false.
|
|
1966
|
-
*
|
|
1967
|
-
* @type {Boolean}
|
|
1968
|
-
*/
|
|
1969
|
-
set culled(culled) {
|
|
1970
|
-
culled = !!culled;
|
|
1971
|
-
this._culled = culled;
|
|
1972
|
-
for (let i = 0, len = this._entityList.length; i < len; i++) {
|
|
1973
|
-
this._entityList[i].culled = culled;
|
|
1974
|
-
}
|
|
1975
|
-
this.glRedraw();
|
|
1976
|
-
}
|
|
1977
|
-
|
|
1978
|
-
/**
|
|
1979
|
-
* Gets if {@link SceneModelEntity}s in this SceneModel are clippable.
|
|
1980
|
-
*
|
|
1981
|
-
* Clipping is done by the {@link SectionPlane}s in {@link Scene#sectionPlanes}.
|
|
1982
|
-
*
|
|
1983
|
-
* @type {Boolean}
|
|
1984
|
-
*/
|
|
1985
|
-
get clippable() {
|
|
1986
|
-
return this._clippable;
|
|
1987
|
-
}
|
|
1988
|
-
|
|
1989
|
-
/**
|
|
1990
|
-
* Sets if {@link SceneModelEntity}s in this SceneModel are clippable.
|
|
1991
|
-
*
|
|
1992
|
-
* Clipping is done by the {@link SectionPlane}s in {@link Scene#sectionPlanes}.
|
|
1993
|
-
*
|
|
1994
|
-
* @type {Boolean}
|
|
1995
|
-
*/
|
|
1996
|
-
set clippable(clippable) {
|
|
1997
|
-
clippable = clippable !== false;
|
|
1998
|
-
this._clippable = clippable;
|
|
1999
|
-
for (let i = 0, len = this._entityList.length; i < len; i++) {
|
|
2000
|
-
this._entityList[i].clippable = clippable;
|
|
2001
|
-
}
|
|
2002
|
-
this.glRedraw();
|
|
2003
|
-
}
|
|
2004
|
-
|
|
2005
|
-
/**
|
|
2006
|
-
* Gets if this SceneModel is collidable.
|
|
2007
|
-
*
|
|
2008
|
-
* @type {Boolean}
|
|
2009
|
-
*/
|
|
2010
|
-
get collidable() {
|
|
2011
|
-
return this._collidable;
|
|
2012
|
-
}
|
|
2013
|
-
|
|
2014
|
-
/**
|
|
2015
|
-
* Sets if {@link SceneModelEntity}s in this SceneModel are collidable.
|
|
2016
|
-
*
|
|
2017
|
-
* @type {Boolean}
|
|
2018
|
-
*/
|
|
2019
|
-
set collidable(collidable) {
|
|
2020
|
-
collidable = collidable !== false;
|
|
2021
|
-
this._collidable = collidable;
|
|
2022
|
-
for (let i = 0, len = this._entityList.length; i < len; i++) {
|
|
2023
|
-
this._entityList[i].collidable = collidable;
|
|
2024
|
-
}
|
|
2025
|
-
}
|
|
2026
|
-
|
|
2027
|
-
/**
|
|
2028
|
-
* Gets if this SceneModel is pickable.
|
|
2029
|
-
*
|
|
2030
|
-
* Picking is done via calls to {@link Scene#pick}.
|
|
2031
|
-
*
|
|
2032
|
-
* @type {Boolean}
|
|
2033
|
-
*/
|
|
2034
|
-
get pickable() {
|
|
2035
|
-
return (this.numPickableLayerPortions > 0);
|
|
2036
|
-
}
|
|
2037
|
-
|
|
2038
|
-
/**
|
|
2039
|
-
* Sets if {@link SceneModelEntity}s in this SceneModel are pickable.
|
|
2040
|
-
*
|
|
2041
|
-
* Picking is done via calls to {@link Scene#pick}.
|
|
2042
|
-
*
|
|
2043
|
-
* @type {Boolean}
|
|
2044
|
-
*/
|
|
2045
|
-
set pickable(pickable) {
|
|
2046
|
-
pickable = pickable !== false;
|
|
2047
|
-
this._pickable = pickable;
|
|
2048
|
-
for (let i = 0, len = this._entityList.length; i < len; i++) {
|
|
2049
|
-
this._entityList[i].pickable = pickable;
|
|
2050
|
-
}
|
|
2051
|
-
}
|
|
2052
|
-
|
|
2053
|
-
/**
|
|
2054
|
-
* Gets the RGB colorize color for this SceneModel.
|
|
2055
|
-
*
|
|
2056
|
-
* Each element of the color is in range ````[0..1]````.
|
|
2057
|
-
*
|
|
2058
|
-
* @type {Number[]}
|
|
2059
|
-
*/
|
|
2060
|
-
get colorize() {
|
|
2061
|
-
return this._colorize;
|
|
2062
|
-
}
|
|
2063
|
-
|
|
2064
|
-
/**
|
|
2065
|
-
* Sets the RGB colorize color for this SceneModel.
|
|
2066
|
-
*
|
|
2067
|
-
* Multiplies by rendered fragment colors.
|
|
2068
|
-
*
|
|
2069
|
-
* Each element of the color is in range ````[0..1]````.
|
|
2070
|
-
*
|
|
2071
|
-
* @type {Number[]}
|
|
2072
|
-
*/
|
|
2073
|
-
set colorize(colorize) {
|
|
2074
|
-
this._colorize = colorize;
|
|
2075
|
-
for (let i = 0, len = this._entityList.length; i < len; i++) {
|
|
2076
|
-
this._entityList[i].colorize = colorize;
|
|
2077
|
-
}
|
|
2078
|
-
}
|
|
2079
|
-
|
|
2080
|
-
/**
|
|
2081
|
-
* Gets this SceneModel's opacity factor.
|
|
2082
|
-
*
|
|
2083
|
-
* This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.
|
|
2084
|
-
*
|
|
2085
|
-
* @type {Number}
|
|
2086
|
-
*/
|
|
2087
|
-
get opacity() {
|
|
2088
|
-
return this._opacity;
|
|
2089
|
-
}
|
|
2090
|
-
|
|
2091
|
-
/**
|
|
2092
|
-
* Sets the opacity factor for this SceneModel.
|
|
2093
|
-
*
|
|
2094
|
-
* This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.
|
|
2095
|
-
*
|
|
2096
|
-
* @type {Number}
|
|
2097
|
-
*/
|
|
2098
|
-
set opacity(opacity) {
|
|
2099
|
-
this._opacity = opacity;
|
|
2100
|
-
for (let i = 0, len = this._entityList.length; i < len; i++) {
|
|
2101
|
-
this._entityList[i].opacity = opacity;
|
|
2102
|
-
}
|
|
2103
|
-
}
|
|
2104
|
-
|
|
2105
|
-
/**
|
|
2106
|
-
* Gets if this SceneModel casts a shadow.
|
|
2107
|
-
*
|
|
2108
|
-
* @type {Boolean}
|
|
2109
|
-
*/
|
|
2110
|
-
get castsShadow() {
|
|
2111
|
-
return this._castsShadow;
|
|
2112
|
-
}
|
|
2113
|
-
|
|
2114
|
-
/**
|
|
2115
|
-
* Sets if this SceneModel casts a shadow.
|
|
2116
|
-
*
|
|
2117
|
-
* @type {Boolean}
|
|
2118
|
-
*/
|
|
2119
|
-
set castsShadow(castsShadow) {
|
|
2120
|
-
castsShadow = (castsShadow !== false);
|
|
2121
|
-
if (castsShadow !== this._castsShadow) {
|
|
2122
|
-
this._castsShadow = castsShadow;
|
|
2123
|
-
this.glRedraw();
|
|
2124
|
-
}
|
|
2125
|
-
}
|
|
2126
|
-
|
|
2127
|
-
/**
|
|
2128
|
-
* Sets if this SceneModel can have shadow cast upon it.
|
|
2129
|
-
*
|
|
2130
|
-
* @type {Boolean}
|
|
2131
|
-
*/
|
|
2132
|
-
get receivesShadow() {
|
|
2133
|
-
return this._receivesShadow;
|
|
2134
|
-
}
|
|
2135
|
-
|
|
2136
|
-
/**
|
|
2137
|
-
* Sets if this SceneModel can have shadow cast upon it.
|
|
2138
|
-
*
|
|
2139
|
-
* @type {Boolean}
|
|
2140
|
-
*/
|
|
2141
|
-
set receivesShadow(receivesShadow) {
|
|
2142
|
-
receivesShadow = (receivesShadow !== false);
|
|
2143
|
-
if (receivesShadow !== this._receivesShadow) {
|
|
2144
|
-
this._receivesShadow = receivesShadow;
|
|
2145
|
-
this.glRedraw();
|
|
2146
|
-
}
|
|
2147
|
-
}
|
|
2148
|
-
|
|
2149
|
-
/**
|
|
2150
|
-
* Gets if Scalable Ambient Obscurance (SAO) will apply to this SceneModel.
|
|
2151
|
-
*
|
|
2152
|
-
* SAO is configured by the Scene's {@link SAO} component.
|
|
2153
|
-
*
|
|
2154
|
-
* Only works when {@link SAO#enabled} is also true.
|
|
2155
|
-
*
|
|
2156
|
-
* @type {Boolean}
|
|
2157
|
-
*/
|
|
2158
|
-
get saoEnabled() {
|
|
2159
|
-
return this._saoEnabled;
|
|
2160
|
-
}
|
|
2161
|
-
|
|
2162
|
-
/**
|
|
2163
|
-
* Gets if physically-based rendering (PBR) is enabled for this SceneModel.
|
|
2164
|
-
*
|
|
2165
|
-
* Only works when {@link Scene#pbrEnabled} is also true.
|
|
2166
|
-
*
|
|
2167
|
-
* @type {Boolean}
|
|
2168
|
-
*/
|
|
2169
|
-
get pbrEnabled() {
|
|
2170
|
-
return this._pbrEnabled;
|
|
2171
|
-
}
|
|
2172
|
-
|
|
2173
|
-
/**
|
|
2174
|
-
* Gets if color textures are enabled for this SceneModel.
|
|
2175
|
-
*
|
|
2176
|
-
* Only works when {@link Scene#colorTextureEnabled} is also true.
|
|
2177
|
-
*
|
|
2178
|
-
* @type {Boolean}
|
|
2179
|
-
*/
|
|
2180
|
-
get colorTextureEnabled() {
|
|
2181
|
-
return this._colorTextureEnabled;
|
|
2182
|
-
}
|
|
2183
|
-
|
|
2184
|
-
/**
|
|
2185
|
-
* Returns true to indicate that SceneModel is implements {@link Drawable}.
|
|
2186
|
-
*
|
|
2187
|
-
* @type {Boolean}
|
|
2188
|
-
*/
|
|
2189
|
-
get isDrawable() {
|
|
2190
|
-
return true;
|
|
2191
|
-
}
|
|
2192
|
-
|
|
2193
|
-
/** @private */
|
|
2194
|
-
get isStateSortable() {
|
|
2195
|
-
return false
|
|
2196
|
-
}
|
|
2197
|
-
|
|
2198
|
-
/**
|
|
2199
|
-
* Configures the appearance of xrayed {@link SceneModelEntity}s within this SceneModel.
|
|
2200
|
-
*
|
|
2201
|
-
* This is the {@link Scene#xrayMaterial}.
|
|
2202
|
-
*
|
|
2203
|
-
* @type {EmphasisMaterial}
|
|
2204
|
-
*/
|
|
2205
|
-
get xrayMaterial() {
|
|
2206
|
-
return this.scene.xrayMaterial;
|
|
2207
|
-
}
|
|
2208
|
-
|
|
2209
|
-
/**
|
|
2210
|
-
* Configures the appearance of highlighted {@link SceneModelEntity}s within this SceneModel.
|
|
2211
|
-
*
|
|
2212
|
-
* This is the {@link Scene#highlightMaterial}.
|
|
2213
|
-
*
|
|
2214
|
-
* @type {EmphasisMaterial}
|
|
2215
|
-
*/
|
|
2216
|
-
get highlightMaterial() {
|
|
2217
|
-
return this.scene.highlightMaterial;
|
|
2218
|
-
}
|
|
2219
|
-
|
|
2220
|
-
/**
|
|
2221
|
-
* Configures the appearance of selected {@link SceneModelEntity}s within this SceneModel.
|
|
2222
|
-
*
|
|
2223
|
-
* This is the {@link Scene#selectedMaterial}.
|
|
2224
|
-
*
|
|
2225
|
-
* @type {EmphasisMaterial}
|
|
2226
|
-
*/
|
|
2227
|
-
get selectedMaterial() {
|
|
2228
|
-
return this.scene.selectedMaterial;
|
|
2229
|
-
}
|
|
2230
|
-
|
|
2231
|
-
/**
|
|
2232
|
-
* Configures the appearance of edges of {@link SceneModelEntity}s within this SceneModel.
|
|
2233
|
-
*
|
|
2234
|
-
* This is the {@link Scene#edgeMaterial}.
|
|
2235
|
-
*
|
|
2236
|
-
* @type {EdgeMaterial}
|
|
2237
|
-
*/
|
|
2238
|
-
get edgeMaterial() {
|
|
2239
|
-
return this.scene.edgeMaterial;
|
|
2240
|
-
}
|
|
2241
|
-
|
|
2242
|
-
//------------------------------------------------------------------------------------------------------------------
|
|
2243
|
-
// Drawable members
|
|
2244
|
-
//------------------------------------------------------------------------------------------------------------------
|
|
2245
|
-
|
|
2246
|
-
/**
|
|
2247
|
-
* Called by private renderers in ./lib, returns the picking view matrix with which to
|
|
2248
|
-
* ray-pick on this SceneModel.
|
|
2249
|
-
*
|
|
2250
|
-
* @private
|
|
2251
|
-
*/
|
|
2252
|
-
getPickViewMatrix(pickViewMatrix) {
|
|
2253
|
-
if (!this._viewMatrix) {
|
|
2254
|
-
return pickViewMatrix;
|
|
2255
|
-
}
|
|
2256
|
-
return this._viewMatrix;
|
|
2257
|
-
}
|
|
2258
|
-
|
|
2259
|
-
/**
|
|
2260
|
-
*
|
|
2261
|
-
* @param cfg
|
|
2262
|
-
*/
|
|
2263
|
-
createQuantizationRange(cfg) {
|
|
2264
|
-
if (cfg.id === undefined || cfg.id === null) {
|
|
2265
|
-
this.error("[createQuantizationRange] Config missing: id");
|
|
2266
|
-
return;
|
|
2267
|
-
}
|
|
2268
|
-
if (cfg.aabb) {
|
|
2269
|
-
this.error("[createQuantizationRange] Config missing: aabb");
|
|
2270
|
-
return;
|
|
2271
|
-
}
|
|
2272
|
-
if (this._quantizationRanges[cfg.id]) {
|
|
2273
|
-
this.error("[createQuantizationRange] QuantizationRange already created: " + cfg.id);
|
|
2274
|
-
return;
|
|
2275
|
-
}
|
|
2276
|
-
this._quantizationRanges[cfg.id] = {
|
|
2277
|
-
id: cfg.id,
|
|
2278
|
-
aabb: cfg.aabb,
|
|
2279
|
-
matrix: createPositionsDecodeMatrix(cfg.aabb, math.mat4())
|
|
2280
|
-
}
|
|
2281
|
-
}
|
|
2282
|
-
|
|
2283
|
-
/**
|
|
2284
|
-
* Creates a reusable geometry within this SceneModel.
|
|
2285
|
-
*
|
|
2286
|
-
* We can then supply the geometry ID to {@link SceneModel#createMesh} when we want to create meshes that
|
|
2287
|
-
* instance the geometry.
|
|
2288
|
-
*
|
|
2289
|
-
* @param {*} cfg Geometry properties.
|
|
2290
|
-
* @param {String|Number} cfg.id Mandatory ID for the geometry, to refer to with {@link SceneModel#createMesh}.
|
|
2291
|
-
* @param {String} cfg.primitive The primitive type. Accepted values are 'points', 'lines', 'triangles', 'solid' and 'surface'.
|
|
2292
|
-
* @param {Number[]} [cfg.positions] Flat array of uncompressed 3D vertex positions positions. Required for all primitive types. Overridden by ````positionsCompressed````.
|
|
2293
|
-
* @param {Number[]} [cfg.positionsCompressed] Flat array of quantized 3D vertex positions. Overrides ````positions````, and must be accompanied by ````positionsDecodeMatrix````.
|
|
2294
|
-
* @param {Number[]} [cfg.positionsDecodeMatrix] A 4x4 matrix for decompressing ````positionsCompressed````. Must be accompanied by ````positionsCompressed````.
|
|
2295
|
-
* @param {Number[]} [cfg.normals] Flat array of normal vectors. Only used with "triangles", "solid" and "surface" primitives. When no normals are given, the geometry will be flat shaded using auto-generated face-aligned normals.
|
|
2296
|
-
* @param {Number[]} [cfg.normalsCompressed] Flat array of oct-encoded normal vectors. Overrides ````normals````. Only used with "triangles", "solid" and "surface" primitives. When no normals are given, the geometry will be flat shaded using auto-generated face-aligned normals.
|
|
2297
|
-
* @param {Number[]} [cfg.colors] Flat array of uncompressed RGBA vertex colors, as float values in range ````[0..1]````. Ignored when ````geometryId```` is given. Overridden by ````color```` and ````colorsCompressed````.
|
|
2298
|
-
* @param {Number[]} [cfg.colorsCompressed] Flat array of compressed RGBA vertex colors, as unsigned short integers in range ````[0..255]````. Ignored when ````geometryId```` is given. Overrides ````colors```` and is overridden by ````color````.
|
|
2299
|
-
* @param {Number[]} [cfg.uv] Flat array of uncompressed vertex UV coordinates. Only used with "triangles", "solid" and "surface" primitives. Required for textured rendering.
|
|
2300
|
-
* @param {Number[]} [cfg.uvCompressed] Flat array of compressed vertex UV coordinates. Only used with "triangles", "solid" and "surface" primitives. Overrides ````uv````. Must be accompanied by ````uvDecodeMatrix````. Only used with "triangles", "solid" and "surface" primitives. Required for textured rendering.
|
|
2301
|
-
* @param {Number[]} [cfg.uvDecodeMatrix] A 3x3 matrix for decompressing ````uvCompressed````.
|
|
2302
|
-
* @param {Number[]} [cfg.indices] Array of primitive connectivity indices. Not required for `points` primitives.
|
|
2303
|
-
* @param {Number[]} [cfg.edgeIndices] Array of edge line indices. Used only with 'triangles', 'solid' and 'surface' primitives. Automatically generated internally if not supplied, using the optional ````edgeThreshold```` given to the ````SceneModel```` constructor.
|
|
2304
|
-
*/
|
|
2305
|
-
createGeometry(cfg) {
|
|
2306
|
-
if (cfg.id === undefined || cfg.id === null) {
|
|
2307
|
-
this.error("[createGeometry] Config missing: id");
|
|
2308
|
-
return;
|
|
2309
|
-
}
|
|
2310
|
-
if (this._geometries[cfg.id]) {
|
|
2311
|
-
this.error("[createGeometry] Geometry already created: " + cfg.id);
|
|
2312
|
-
return;
|
|
2313
|
-
}
|
|
2314
|
-
if (cfg.primitive === undefined || cfg.primitive === null) {
|
|
2315
|
-
cfg.primitive = "triangles";
|
|
2316
|
-
}
|
|
2317
|
-
if (cfg.primitive !== "points" && cfg.primitive !== "lines" && cfg.primitive !== "triangles" && cfg.primitive !== "solid" && cfg.primitive !== "surface") {
|
|
2318
|
-
this.error(`[createGeometry] Unsupported value for 'primitive': '${cfg.primitive}' - supported values are 'points', 'lines', 'triangles', 'solid' and 'surface'. Defaulting to 'triangles'.`);
|
|
2319
|
-
return;
|
|
2320
|
-
}
|
|
2321
|
-
if (!cfg.positions && !cfg.positionsCompressed && !cfg.buckets) {
|
|
2322
|
-
this.error("[createGeometry] Param expected: `positions`, `positionsCompressed' or 'buckets");
|
|
2323
|
-
return null;
|
|
2324
|
-
}
|
|
2325
|
-
if (cfg.positionsCompressed && !cfg.positionsDecodeMatrix && !cfg.positionsDecodeBoundary) {
|
|
2326
|
-
this.error("[createGeometry] Param expected: `positionsDecodeMatrix` or 'positionsDecodeBoundary' (required for `positionsCompressed')");
|
|
2327
|
-
return null;
|
|
2328
|
-
}
|
|
2329
|
-
if (cfg.positionsDecodeMatrix && cfg.positionsDecodeBoundary) {
|
|
2330
|
-
this.error("[createGeometry] Only one of these params expected: `positionsDecodeMatrix` or 'positionsDecodeBoundary' (required for `positionsCompressed')");
|
|
2331
|
-
return null;
|
|
2332
|
-
}
|
|
2333
|
-
if (cfg.uvCompressed && !cfg.uvDecodeMatrix) {
|
|
2334
|
-
this.error("[createGeometry] Param expected: `uvDecodeMatrix` (required for `uvCompressed')");
|
|
2335
|
-
return null;
|
|
2336
|
-
}
|
|
2337
|
-
if (!cfg.buckets && !cfg.indices && cfg.primitive !== "points") {
|
|
2338
|
-
this.error(`[createGeometry] Param expected: indices (required for '${cfg.primitive}' primitive type)`);
|
|
2339
|
-
return null;
|
|
2340
|
-
}
|
|
2341
|
-
if (cfg.positionsDecodeBoundary) {
|
|
2342
|
-
cfg.positionsDecodeMatrix = createPositionsDecodeMatrix(cfg.positionsDecodeBoundary, math.mat4());
|
|
2343
|
-
}
|
|
2344
|
-
if (cfg.positions) {
|
|
2345
|
-
const aabb = math.collapseAABB3();
|
|
2346
|
-
cfg.positionsDecodeMatrix = math.mat4();
|
|
2347
|
-
math.expandAABB3Points3(aabb, cfg.positions);
|
|
2348
|
-
cfg.positionsCompressed = quantizePositions(cfg.positions, aabb, cfg.positionsDecodeMatrix);
|
|
2349
|
-
cfg.aabb = aabb;
|
|
2350
|
-
} else if (cfg.positionsCompressed) {
|
|
2351
|
-
const aabb = math.collapseAABB3();
|
|
2352
|
-
cfg.positionsDecodeMatrix = new Float64Array(cfg.positionsDecodeMatrix);
|
|
2353
|
-
cfg.positionsCompressed = new Uint16Array(cfg.positionsCompressed);
|
|
2354
|
-
math.expandAABB3Points3(aabb, cfg.positionsCompressed);
|
|
2355
|
-
geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);
|
|
2356
|
-
cfg.aabb = aabb;
|
|
2357
|
-
} else if (cfg.buckets) {
|
|
2358
|
-
const aabb = math.collapseAABB3();
|
|
2359
|
-
this._dtxBuckets[cfg.id] = cfg.buckets;
|
|
2360
|
-
for (let i = 0, len = cfg.buckets.length; i < len; i++) {
|
|
2361
|
-
const bucket = cfg.buckets[i];
|
|
2362
|
-
if (bucket.positions) {
|
|
2363
|
-
math.expandAABB3Points3(aabb, bucket.positions);
|
|
2364
|
-
} else if (bucket.positionsCompressed) {
|
|
2365
|
-
math.expandAABB3Points3(aabb, bucket.positionsCompressed);
|
|
2366
|
-
}
|
|
2367
|
-
}
|
|
2368
|
-
if (cfg.positionsDecodeMatrix) {
|
|
2369
|
-
geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);
|
|
2370
|
-
}
|
|
2371
|
-
cfg.aabb = aabb;
|
|
2372
|
-
}
|
|
2373
|
-
if (cfg.colorsCompressed && cfg.colorsCompressed.length > 0) {
|
|
2374
|
-
cfg.colorsCompressed = new Uint8Array(cfg.colorsCompressed);
|
|
2375
|
-
} else if (cfg.colors && cfg.colors.length > 0) {
|
|
2376
|
-
const colors = cfg.colors;
|
|
2377
|
-
const colorsCompressed = new Uint8Array(colors.length);
|
|
2378
|
-
for (let i = 0, len = colors.length; i < len; i++) {
|
|
2379
|
-
colorsCompressed[i] = colors[i] * 255;
|
|
2380
|
-
}
|
|
2381
|
-
cfg.colorsCompressed = colorsCompressed;
|
|
2382
|
-
}
|
|
2383
|
-
if (!cfg.buckets && !cfg.edgeIndices && (cfg.primitive === "triangles" || cfg.primitive === "solid" || cfg.primitive === "surface")) {
|
|
2384
|
-
if (cfg.positions) {
|
|
2385
|
-
cfg.edgeIndices = buildEdgeIndices(cfg.positions, cfg.indices, null, 5.0);
|
|
2386
|
-
} else {
|
|
2387
|
-
cfg.edgeIndices = buildEdgeIndices(cfg.positionsCompressed, cfg.indices, cfg.positionsDecodeMatrix, 2.0);
|
|
2388
|
-
}
|
|
2389
|
-
}
|
|
2390
|
-
if (cfg.uv) {
|
|
2391
|
-
const bounds = geometryCompressionUtils.getUVBounds(cfg.uv);
|
|
2392
|
-
const result = geometryCompressionUtils.compressUVs(cfg.uv, bounds.min, bounds.max);
|
|
2393
|
-
cfg.uvCompressed = result.quantized;
|
|
2394
|
-
cfg.uvDecodeMatrix = result.decodeMatrix;
|
|
2395
|
-
} else if (cfg.uvCompressed) {
|
|
2396
|
-
cfg.uvCompressed = new Uint16Array(cfg.uvCompressed);
|
|
2397
|
-
cfg.uvDecodeMatrix = new Float64Array(cfg.uvDecodeMatrix);
|
|
2398
|
-
}
|
|
2399
|
-
if (cfg.normals) { // HACK
|
|
2400
|
-
cfg.normals = null;
|
|
2401
|
-
}
|
|
2402
|
-
this._geometries [cfg.id] = cfg;
|
|
2403
|
-
this._numTriangles += (cfg.indices ? Math.round(cfg.indices.length / 3) : 0);
|
|
2404
|
-
this.numGeometries++;
|
|
2405
|
-
}
|
|
2406
|
-
|
|
2407
|
-
/**
|
|
2408
|
-
* Creates a texture within this SceneModel.
|
|
2409
|
-
*
|
|
2410
|
-
* We can then supply the texture ID to {@link SceneModel#createTextureSet} when we want to create texture sets that use the texture.
|
|
2411
|
-
*
|
|
2412
|
-
* @param {*} cfg Texture properties.
|
|
2413
|
-
* @param {String|Number} cfg.id Mandatory ID for the texture, to refer to with {@link SceneModel#createTextureSet}.
|
|
2414
|
-
* @param {String} [cfg.src] Image file for the texture. Assumed to be transcoded if not having a recognized image file
|
|
2415
|
-
* extension (jpg, jpeg, png etc.). If transcoded, then assumes ````SceneModel```` is configured with a {@link TextureTranscoder}.
|
|
2416
|
-
* @param {ArrayBuffer[]} [cfg.buffers] Transcoded texture data. Assumes ````SceneModel```` is
|
|
2417
|
-
* configured with a {@link TextureTranscoder}. This parameter is given as an array of buffers so we can potentially support multi-image textures, such as cube maps.
|
|
2418
|
-
* @param {HTMLImageElement} [cfg.image] HTML Image object to load into this texture. Overrides ````src```` and ````buffers````. Never transcoded.
|
|
2419
|
-
* @param {Number} [cfg.minFilter=LinearMipmapLinearFilter] How the texture is sampled when a texel covers less than one pixel.
|
|
2420
|
-
* Supported values are {@link LinearMipmapLinearFilter}, {@link LinearMipMapNearestFilter}, {@link NearestMipMapNearestFilter}, {@link NearestMipMapLinearFilter} and {@link LinearMipMapLinearFilter}.
|
|
2421
|
-
* @param {Number} [cfg.magFilter=LinearFilter] How the texture is sampled when a texel covers more than one pixel. Supported values are {@link LinearFilter} and {@link NearestFilter}.
|
|
2422
|
-
* @param {Number} [cfg.wrapS=RepeatWrapping] Wrap parameter for texture coordinate *S*. Supported values are {@link ClampToEdgeWrapping}, {@link MirroredRepeatWrapping} and {@link RepeatWrapping}.
|
|
2423
|
-
* @param {Number} [cfg.wrapT=RepeatWrapping] Wrap parameter for texture coordinate *T*. Supported values are {@link ClampToEdgeWrapping}, {@link MirroredRepeatWrapping} and {@link RepeatWrapping}..
|
|
2424
|
-
* @param {Number} [cfg.wrapR=RepeatWrapping] Wrap parameter for texture coordinate *R*. Supported values are {@link ClampToEdgeWrapping}, {@link MirroredRepeatWrapping} and {@link RepeatWrapping}.
|
|
2425
|
-
* @param {Boolean} [cfg.flipY=false] Flips this Texture's source data along its vertical axis when ````true````.
|
|
2426
|
-
* @param {Number} [cfg.encoding=LinearEncoding] Encoding format. Supported values are {@link LinearEncoding} and {@link sRGBEncoding}.
|
|
2427
|
-
*/
|
|
2428
|
-
createTexture(cfg) {
|
|
2429
|
-
const textureId = cfg.id;
|
|
2430
|
-
if (textureId === undefined || textureId === null) {
|
|
2431
|
-
this.error("[createTexture] Config missing: id");
|
|
2432
|
-
return;
|
|
2433
|
-
}
|
|
2434
|
-
if (this._textures[textureId]) {
|
|
2435
|
-
this.error("[createTexture] Texture already created: " + textureId);
|
|
2436
|
-
return;
|
|
2437
|
-
}
|
|
2438
|
-
if (!cfg.src && !cfg.image && !cfg.buffers) {
|
|
2439
|
-
this.error("[createTexture] Param expected: `src`, `image' or 'buffers'");
|
|
2440
|
-
return null;
|
|
2441
|
-
}
|
|
2442
|
-
let minFilter = cfg.minFilter || LinearMipmapLinearFilter;
|
|
2443
|
-
if (minFilter !== LinearFilter &&
|
|
2444
|
-
minFilter !== LinearMipMapNearestFilter &&
|
|
2445
|
-
minFilter !== LinearMipmapLinearFilter &&
|
|
2446
|
-
minFilter !== NearestMipMapLinearFilter &&
|
|
2447
|
-
minFilter !== NearestMipMapNearestFilter) {
|
|
2448
|
-
this.error(`[createTexture] Unsupported value for 'minFilter' -
|
|
2449
|
-
supported values are LinearFilter, LinearMipMapNearestFilter, NearestMipMapNearestFilter,
|
|
2450
|
-
NearestMipMapLinearFilter and LinearMipmapLinearFilter. Defaulting to LinearMipmapLinearFilter.`);
|
|
2451
|
-
minFilter = LinearMipmapLinearFilter;
|
|
2452
|
-
}
|
|
2453
|
-
let magFilter = cfg.magFilter || LinearFilter;
|
|
2454
|
-
if (magFilter !== LinearFilter && magFilter !== NearestFilter) {
|
|
2455
|
-
this.error(`[createTexture] Unsupported value for 'magFilter' - supported values are LinearFilter and NearestFilter. Defaulting to LinearFilter.`);
|
|
2456
|
-
magFilter = LinearFilter;
|
|
2457
|
-
}
|
|
2458
|
-
let wrapS = cfg.wrapS || RepeatWrapping;
|
|
2459
|
-
if (wrapS !== ClampToEdgeWrapping && wrapS !== MirroredRepeatWrapping && wrapS !== RepeatWrapping) {
|
|
2460
|
-
this.error(`[createTexture] Unsupported value for 'wrapS' - supported values are ClampToEdgeWrapping, MirroredRepeatWrapping and RepeatWrapping. Defaulting to RepeatWrapping.`);
|
|
2461
|
-
wrapS = RepeatWrapping;
|
|
2462
|
-
}
|
|
2463
|
-
let wrapT = cfg.wrapT || RepeatWrapping;
|
|
2464
|
-
if (wrapT !== ClampToEdgeWrapping && wrapT !== MirroredRepeatWrapping && wrapT !== RepeatWrapping) {
|
|
2465
|
-
this.error(`[createTexture] Unsupported value for 'wrapT' - supported values are ClampToEdgeWrapping, MirroredRepeatWrapping and RepeatWrapping. Defaulting to RepeatWrapping.`);
|
|
2466
|
-
wrapT = RepeatWrapping;
|
|
2467
|
-
}
|
|
2468
|
-
let wrapR = cfg.wrapR || RepeatWrapping;
|
|
2469
|
-
if (wrapR !== ClampToEdgeWrapping && wrapR !== MirroredRepeatWrapping && wrapR !== RepeatWrapping) {
|
|
2470
|
-
this.error(`[createTexture] Unsupported value for 'wrapR' - supported values are ClampToEdgeWrapping, MirroredRepeatWrapping and RepeatWrapping. Defaulting to RepeatWrapping.`);
|
|
2471
|
-
wrapR = RepeatWrapping;
|
|
2472
|
-
}
|
|
2473
|
-
let encoding = cfg.encoding || LinearEncoding;
|
|
2474
|
-
if (encoding !== LinearEncoding && encoding !== sRGBEncoding) {
|
|
2475
|
-
this.error("[createTexture] Unsupported value for 'encoding' - supported values are LinearEncoding and sRGBEncoding. Defaulting to LinearEncoding.");
|
|
2476
|
-
encoding = LinearEncoding;
|
|
2477
|
-
}
|
|
2478
|
-
const texture = new Texture2D({
|
|
2479
|
-
gl: this.scene.canvas.gl,
|
|
2480
|
-
minFilter,
|
|
2481
|
-
magFilter,
|
|
2482
|
-
wrapS,
|
|
2483
|
-
wrapT,
|
|
2484
|
-
wrapR,
|
|
2485
|
-
// flipY: cfg.flipY,
|
|
2486
|
-
encoding
|
|
2487
|
-
});
|
|
2488
|
-
if (cfg.preloadColor) {
|
|
2489
|
-
texture.setPreloadColor(cfg.preloadColor);
|
|
2490
|
-
}
|
|
2491
|
-
if (cfg.image) { // Ignore transcoder for Images
|
|
2492
|
-
const image = cfg.image;
|
|
2493
|
-
image.crossOrigin = "Anonymous";
|
|
2494
|
-
texture.setImage(image, {minFilter, magFilter, wrapS, wrapT, wrapR, flipY: cfg.flipY, encoding});
|
|
2495
|
-
} else if (cfg.src) {
|
|
2496
|
-
const ext = cfg.src.split('.').pop();
|
|
2497
|
-
switch (ext) { // Don't transcode recognized image file types
|
|
2498
|
-
case "jpeg":
|
|
2499
|
-
case "jpg":
|
|
2500
|
-
case "png":
|
|
2501
|
-
case "gif":
|
|
2502
|
-
const image = new Image();
|
|
2503
|
-
image.onload = () => {
|
|
2504
|
-
texture.setImage(image, {
|
|
2505
|
-
minFilter,
|
|
2506
|
-
magFilter,
|
|
2507
|
-
wrapS,
|
|
2508
|
-
wrapT,
|
|
2509
|
-
wrapR,
|
|
2510
|
-
flipY: cfg.flipY,
|
|
2511
|
-
encoding
|
|
2512
|
-
});
|
|
2513
|
-
this.glRedraw();
|
|
2514
|
-
};
|
|
2515
|
-
image.src = cfg.src; // URL or Base64 string
|
|
2516
|
-
break;
|
|
2517
|
-
default: // Assume other file types need transcoding
|
|
2518
|
-
if (!this._textureTranscoder) {
|
|
2519
|
-
this.error(`[createTexture] Can't create texture from 'src' - SceneModel needs to be configured with a TextureTranscoder for this file type ('${ext}')`);
|
|
2520
|
-
} else {
|
|
2521
|
-
utils.loadArraybuffer(cfg.src, (arrayBuffer) => {
|
|
2522
|
-
if (!arrayBuffer.byteLength) {
|
|
2523
|
-
this.error(`[createTexture] Can't create texture from 'src': file data is zero length`);
|
|
2524
|
-
return;
|
|
2525
|
-
}
|
|
2526
|
-
this._textureTranscoder.transcode([arrayBuffer], texture).then(() => {
|
|
2527
|
-
this.glRedraw();
|
|
2528
|
-
});
|
|
2529
|
-
},
|
|
2530
|
-
function (errMsg) {
|
|
2531
|
-
this.error(`[createTexture] Can't create texture from 'src': ${errMsg}`);
|
|
2532
|
-
});
|
|
2533
|
-
}
|
|
2534
|
-
break;
|
|
2535
|
-
}
|
|
2536
|
-
} else if (cfg.buffers) { // Buffers implicitly require transcoding
|
|
2537
|
-
if (!this._textureTranscoder) {
|
|
2538
|
-
this.error(`[createTexture] Can't create texture from 'buffers' - SceneModel needs to be configured with a TextureTranscoder for this option`);
|
|
2539
|
-
} else {
|
|
2540
|
-
this._textureTranscoder.transcode(cfg.buffers, texture).then(() => {
|
|
2541
|
-
this.glRedraw();
|
|
2542
|
-
});
|
|
2543
|
-
}
|
|
2544
|
-
}
|
|
2545
|
-
this._textures[textureId] = new SceneModelTexture({id: textureId, texture});
|
|
2546
|
-
}
|
|
2547
|
-
|
|
2548
|
-
/**
|
|
2549
|
-
* Creates a texture set within this SceneModel.
|
|
2550
|
-
*
|
|
2551
|
-
* * Stores the new {@link SceneModelTextureSet} in {@link SceneModel#textureSets}.
|
|
2552
|
-
*
|
|
2553
|
-
* A texture set is a collection of textures that can be shared among meshes. We can then supply the texture set
|
|
2554
|
-
* ID to {@link SceneModel#createMesh} when we want to create meshes that use the texture set.
|
|
2555
|
-
*
|
|
2556
|
-
* The textures can work as a texture atlas, where each mesh can have geometry UVs that index
|
|
2557
|
-
* a different part of the textures. This allows us to minimize the number of textures in our models, which
|
|
2558
|
-
* means faster rendering.
|
|
2559
|
-
*
|
|
2560
|
-
* @param {*} cfg Texture set properties.
|
|
2561
|
-
* @param {String|Number} cfg.id Mandatory ID for the texture set, to refer to with {@link SceneModel#createMesh}.
|
|
2562
|
-
* @param {*} [cfg.colorTextureId] ID of *RGBA* base color texture, with color in *RGB* and alpha in *A*.
|
|
2563
|
-
* @param {*} [cfg.metallicRoughnessTextureId] ID of *RGBA* metal-roughness texture, with the metallic factor in *R*, and roughness factor in *G*.
|
|
2564
|
-
* @param {*} [cfg.normalsTextureId] ID of *RGBA* normal map texture, with normal map vectors in *RGB*.
|
|
2565
|
-
* @param {*} [cfg.emissiveTextureId] ID of *RGBA* emissive map texture, with emissive color in *RGB*.
|
|
2566
|
-
* @param {*} [cfg.occlusionTextureId] ID of *RGBA* occlusion map texture, with occlusion factor in *R*.
|
|
2567
|
-
* @returns {SceneModelTransform} The new texture set.
|
|
2568
|
-
*/
|
|
2569
|
-
createTextureSet(cfg) {
|
|
2570
|
-
const textureSetId = cfg.id;
|
|
2571
|
-
if (textureSetId === undefined || textureSetId === null) {
|
|
2572
|
-
this.error("[createTextureSet] Config missing: id");
|
|
2573
|
-
return;
|
|
2574
|
-
}
|
|
2575
|
-
if (this._textureSets[textureSetId]) {
|
|
2576
|
-
this.error(`[createTextureSet] Texture set already created: ${textureSetId}`);
|
|
2577
|
-
return;
|
|
2578
|
-
}
|
|
2579
|
-
let colorTexture;
|
|
2580
|
-
if (cfg.colorTextureId !== undefined && cfg.colorTextureId !== null) {
|
|
2581
|
-
colorTexture = this._textures[cfg.colorTextureId];
|
|
2582
|
-
if (!colorTexture) {
|
|
2583
|
-
this.error(`[createTextureSet] Texture not found: ${cfg.colorTextureId} - ensure that you create it first with createTexture()`);
|
|
2584
|
-
return;
|
|
2585
|
-
}
|
|
2586
|
-
} else {
|
|
2587
|
-
colorTexture = this._textures[DEFAULT_COLOR_TEXTURE_ID];
|
|
2588
|
-
}
|
|
2589
|
-
let metallicRoughnessTexture;
|
|
2590
|
-
if (cfg.metallicRoughnessTextureId !== undefined && cfg.metallicRoughnessTextureId !== null) {
|
|
2591
|
-
metallicRoughnessTexture = this._textures[cfg.metallicRoughnessTextureId];
|
|
2592
|
-
if (!metallicRoughnessTexture) {
|
|
2593
|
-
this.error(`[createTextureSet] Texture not found: ${cfg.metallicRoughnessTextureId} - ensure that you create it first with createTexture()`);
|
|
2594
|
-
return;
|
|
2595
|
-
}
|
|
2596
|
-
} else {
|
|
2597
|
-
metallicRoughnessTexture = this._textures[DEFAULT_METAL_ROUGH_TEXTURE_ID];
|
|
2598
|
-
}
|
|
2599
|
-
let normalsTexture;
|
|
2600
|
-
if (cfg.normalsTextureId !== undefined && cfg.normalsTextureId !== null) {
|
|
2601
|
-
normalsTexture = this._textures[cfg.normalsTextureId];
|
|
2602
|
-
if (!normalsTexture) {
|
|
2603
|
-
this.error(`[createTextureSet] Texture not found: ${cfg.normalsTextureId} - ensure that you create it first with createTexture()`);
|
|
2604
|
-
return;
|
|
2605
|
-
}
|
|
2606
|
-
} else {
|
|
2607
|
-
normalsTexture = this._textures[DEFAULT_NORMALS_TEXTURE_ID];
|
|
2608
|
-
}
|
|
2609
|
-
let emissiveTexture;
|
|
2610
|
-
if (cfg.emissiveTextureId !== undefined && cfg.emissiveTextureId !== null) {
|
|
2611
|
-
emissiveTexture = this._textures[cfg.emissiveTextureId];
|
|
2612
|
-
if (!emissiveTexture) {
|
|
2613
|
-
this.error(`[createTextureSet] Texture not found: ${cfg.emissiveTextureId} - ensure that you create it first with createTexture()`);
|
|
2614
|
-
return;
|
|
2615
|
-
}
|
|
2616
|
-
} else {
|
|
2617
|
-
emissiveTexture = this._textures[DEFAULT_EMISSIVE_TEXTURE_ID];
|
|
2618
|
-
}
|
|
2619
|
-
let occlusionTexture;
|
|
2620
|
-
if (cfg.occlusionTextureId !== undefined && cfg.occlusionTextureId !== null) {
|
|
2621
|
-
occlusionTexture = this._textures[cfg.occlusionTextureId];
|
|
2622
|
-
if (!occlusionTexture) {
|
|
2623
|
-
this.error(`[createTextureSet] Texture not found: ${cfg.occlusionTextureId} - ensure that you create it first with createTexture()`);
|
|
2624
|
-
return;
|
|
2625
|
-
}
|
|
2626
|
-
} else {
|
|
2627
|
-
occlusionTexture = this._textures[DEFAULT_OCCLUSION_TEXTURE_ID];
|
|
2628
|
-
}
|
|
2629
|
-
const textureSet = new SceneModelTextureSet({
|
|
2630
|
-
id: textureSetId,
|
|
2631
|
-
model: this,
|
|
2632
|
-
colorTexture,
|
|
2633
|
-
metallicRoughnessTexture,
|
|
2634
|
-
normalsTexture,
|
|
2635
|
-
emissiveTexture,
|
|
2636
|
-
occlusionTexture
|
|
2637
|
-
});
|
|
2638
|
-
this._textureSets[textureSetId] = textureSet;
|
|
2639
|
-
return textureSet;
|
|
2640
|
-
}
|
|
2641
|
-
|
|
2642
|
-
/**
|
|
2643
|
-
* Creates a new {@link SceneModelTransform} within this SceneModel.
|
|
2644
|
-
*
|
|
2645
|
-
* * Stores the new {@link SceneModelTransform} in {@link SceneModel#transforms}.
|
|
2646
|
-
* * Can be connected into hierarchies
|
|
2647
|
-
* * Each {@link SceneModelTransform} can be used by unlimited {@link SceneModelMesh}es
|
|
2648
|
-
*
|
|
2649
|
-
* @param {*} cfg Transform creation parameters.
|
|
2650
|
-
* @param {String} cfg.id Mandatory ID for the new transform. Must not clash with any existing components within the {@link Scene}.
|
|
2651
|
-
* @param {String} [cfg.parentTransformId] ID of a parent transform, previously created with {@link SceneModel#createTextureSet}.
|
|
2652
|
-
* @param {Number[]} [cfg.position=[0,0,0]] Local 3D position of the mesh. Overridden by ````transformId````.
|
|
2653
|
-
* @param {Number[]} [cfg.scale=[1,1,1]] Scale of the transform.
|
|
2654
|
-
* @param {Number[]} [cfg.rotation=[0,0,0]] Rotation of the transform as Euler angles given in degrees, for each of the X, Y and Z axis.
|
|
2655
|
-
* @param {Number[]} [cfg.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]] Modelling transform matrix. Overrides the ````position````, ````scale```` and ````rotation```` parameters.
|
|
2656
|
-
* @returns {SceneModelTransform} The new transform.
|
|
2657
|
-
*/
|
|
2658
|
-
createTransform(cfg) {
|
|
2659
|
-
if (cfg.id === undefined || cfg.id === null) {
|
|
2660
|
-
this.error("[createTransform] SceneModel.createTransform() config missing: id");
|
|
2661
|
-
return;
|
|
2662
|
-
}
|
|
2663
|
-
if (this._transforms[cfg.id]) {
|
|
2664
|
-
this.error(`[createTransform] SceneModel already has a transform with this ID: ${cfg.id}`);
|
|
2665
|
-
return;
|
|
2666
|
-
}
|
|
2667
|
-
let parentTransform;
|
|
2668
|
-
if (this.parentTransformId) {
|
|
2669
|
-
parentTransform = this._transforms[cfg.parentTransformId];
|
|
2670
|
-
if (!parentTransform) {
|
|
2671
|
-
this.error("[createTransform] SceneModel.createTransform() config missing: id");
|
|
2672
|
-
return;
|
|
2673
|
-
}
|
|
2674
|
-
}
|
|
2675
|
-
const transform = new SceneModelTransform({
|
|
2676
|
-
id: cfg.id,
|
|
2677
|
-
model: this,
|
|
2678
|
-
parentTransform,
|
|
2679
|
-
matrix: cfg.matrix,
|
|
2680
|
-
position: cfg.position,
|
|
2681
|
-
scale: cfg.scale,
|
|
2682
|
-
rotation: cfg.rotation,
|
|
2683
|
-
quaternion: cfg.quaternion
|
|
2684
|
-
});
|
|
2685
|
-
this._transforms[transform.id] = transform;
|
|
2686
|
-
return transform;
|
|
2687
|
-
}
|
|
2688
|
-
|
|
2689
|
-
/**
|
|
2690
|
-
* Creates a new {@link SceneModelMesh} within this SceneModel.
|
|
2691
|
-
*
|
|
2692
|
-
* * It prepares and saves data for a SceneModelMesh {@link SceneModel#meshes} creation. SceneModelMesh will be created only once the SceneModelEntity (which references this particular SceneModelMesh) will be created.
|
|
2693
|
-
* * The SceneModelMesh can either define its own geometry or share it with other SceneModelMeshes. To define own geometry, provide the
|
|
2694
|
-
* various geometry arrays to this method. To share a geometry, provide the ID of a geometry created earlier
|
|
2695
|
-
* with {@link SceneModel#createGeometry}.
|
|
2696
|
-
* * If you accompany the arrays with an ````origin````, then ````createMesh()```` will assume
|
|
2697
|
-
* that the geometry ````positions```` are in relative-to-center (RTC) coordinates, with ````origin```` being the
|
|
2698
|
-
* origin of their RTC coordinate system.
|
|
2699
|
-
*
|
|
2700
|
-
* @param {object} cfg Object properties.
|
|
2701
|
-
* @param {String} cfg.id Mandatory ID for the new mesh. Must not clash with any existing components within the {@link Scene}.
|
|
2702
|
-
* @param {String|Number} [cfg.textureSetId] ID of a {@link SceneModelTextureSet} previously created with {@link SceneModel#createTextureSet}.
|
|
2703
|
-
* @param {String|Number} [cfg.transformId] ID of a {@link SceneModelTransform} to instance, previously created with {@link SceneModel#createTransform}. Overrides all other transform parameters given to this method.
|
|
2704
|
-
* @param {String|Number} [cfg.geometryId] ID of a geometry to instance, previously created with {@link SceneModel#createGeometry}. Overrides all other geometry parameters given to this method.
|
|
2705
|
-
* @param {String} cfg.primitive The primitive type. Accepted values are 'points', 'lines', 'triangles', 'solid' and 'surface'.
|
|
2706
|
-
* @param {Number[]} [cfg.positions] Flat array of uncompressed 3D vertex positions positions. Required for all primitive types. Overridden by ````positionsCompressed````.
|
|
2707
|
-
* @param {Number[]} [cfg.positionsCompressed] Flat array of quantized 3D vertex positions. Overrides ````positions````, and must be accompanied by ````positionsDecodeMatrix````.
|
|
2708
|
-
* @param {Number[]} [cfg.positionsDecodeMatrix] A 4x4 matrix for decompressing ````positionsCompressed````. Must be accompanied by ````positionsCompressed````.
|
|
2709
|
-
* @param {Number[]} [cfg.normals] Flat array of normal vectors. Only used with "triangles", "solid" and "surface" primitives. When no normals are given, the geometry will be flat shaded using auto-generated face-aligned normals.
|
|
2710
|
-
* @param {Number[]} [cfg.normalsCompressed] Flat array of oct-encoded normal vectors. Overrides ````normals````. Only used with "triangles", "solid" and "surface" primitives. When no normals are given, the geometry will be flat shaded using auto-generated face-aligned normals.
|
|
2711
|
-
* @param {Number[]} [cfg.colors] Flat array of uncompressed RGBA vertex colors, as float values in range ````[0..1]````. Ignored when ````geometryId```` is given. Overridden by ````color```` and ````colorsCompressed````.
|
|
2712
|
-
* @param {Number[]} [cfg.colorsCompressed] Flat array of compressed RGBA vertex colors, as unsigned short integers in range ````[0..255]````. Ignored when ````geometryId```` is given. Overrides ````colors```` and is overridden by ````color````.
|
|
2713
|
-
* @param {Number[]} [cfg.uv] Flat array of uncompressed vertex UV coordinates. Only used with "triangles", "solid" and "surface" primitives. Required for textured rendering.
|
|
2714
|
-
* @param {Number[]} [cfg.uvCompressed] Flat array of compressed vertex UV coordinates. Only used with "triangles", "solid" and "surface" primitives. Overrides ````uv````. Must be accompanied by ````uvDecodeMatrix````. Only used with "triangles", "solid" and "surface" primitives. Required for textured rendering.
|
|
2715
|
-
* @param {Number[]} [cfg.uvDecodeMatrix] A 3x3 matrix for decompressing ````uvCompressed````.
|
|
2716
|
-
* @param {Number[]} [cfg.indices] Array of primitive connectivity indices. Not required for `points` primitives.
|
|
2717
|
-
* @param {Number[]} [cfg.edgeIndices] Array of edge line indices. Used only with 'triangles', 'solid' and 'surface' primitives. Automatically generated internally if not supplied, using the optional ````edgeThreshold```` given to the ````SceneModel```` constructor.
|
|
2718
|
-
* @param {Number[]} [cfg.origin] Optional geometry origin, relative to {@link SceneModel#origin}. When this is given, then ````positions```` are assumed to be relative to this.
|
|
2719
|
-
* @param {Number[]} [cfg.position=[0,0,0]] Local 3D position of the mesh. Overridden by ````transformId````.
|
|
2720
|
-
* @param {Number[]} [cfg.scale=[1,1,1]] Scale of the mesh. Overridden by ````transformId````.
|
|
2721
|
-
* @param {Number[]} [cfg.rotation=[0,0,0]] Rotation of the mesh as Euler angles given in degrees, for each of the X, Y and Z axis. Overridden by ````transformId````.
|
|
2722
|
-
* @param {Number[]} [cfg.matrix=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]] Mesh modelling transform matrix. Overrides the ````position````, ````scale```` and ````rotation```` parameters. Also overridden by ````transformId````.
|
|
2723
|
-
* @param {Number[]} [cfg.color=[1,1,1]] RGB color in range ````[0..1, 0..1, 0..1]````. Overridden by texture set ````colorTexture````. Overrides ````colors```` and ````colorsCompressed````.
|
|
2724
|
-
* @param {Number} [cfg.opacity=1] Opacity in range ````[0..1]````. Overridden by texture set ````colorTexture````.
|
|
2725
|
-
* @param {Number} [cfg.metallic=0] Metallic factor in range ````[0..1]````. Overridden by texture set ````metallicRoughnessTexture````.
|
|
2726
|
-
* @param {Number} [cfg.roughness=1] Roughness factor in range ````[0..1]````. Overridden by texture set ````metallicRoughnessTexture````.
|
|
2727
|
-
* @returns {Boolean} True = successfully mesh was created. False = error during creation of a mesh.
|
|
2728
|
-
*/
|
|
2729
|
-
createMesh(cfg) {
|
|
2730
|
-
|
|
2731
|
-
if (cfg.id === undefined || cfg.id === null) {
|
|
2732
|
-
this.error("[createMesh] SceneModel.createMesh() config missing: id");
|
|
2733
|
-
return false;
|
|
2734
|
-
}
|
|
2735
|
-
|
|
2736
|
-
if (this._scheduledMeshes[cfg.id]) {
|
|
2737
|
-
this.error(`[createMesh] SceneModel already has a mesh with this ID: ${cfg.id}`);
|
|
2738
|
-
return false;
|
|
2739
|
-
}
|
|
2740
|
-
|
|
2741
|
-
const instancing = (cfg.geometryId !== undefined);
|
|
2742
|
-
const batching = !instancing;
|
|
2743
|
-
|
|
2744
|
-
if (batching) {
|
|
2745
|
-
|
|
2746
|
-
// Batched geometry
|
|
2747
|
-
|
|
2748
|
-
if (cfg.primitive === undefined || cfg.primitive === null) {
|
|
2749
|
-
cfg.primitive = "triangles";
|
|
2750
|
-
}
|
|
2751
|
-
if (cfg.primitive !== "points" && cfg.primitive !== "lines" && cfg.primitive !== "triangles" && cfg.primitive !== "solid" && cfg.primitive !== "surface") {
|
|
2752
|
-
this.error(`Unsupported value for 'primitive': '${primitive}' ('geometryId' is absent) - supported values are 'points', 'lines', 'triangles', 'solid' and 'surface'.`);
|
|
2753
|
-
return false;
|
|
2754
|
-
}
|
|
2755
|
-
if (!cfg.positions && !cfg.positionsCompressed && !cfg.buckets) {
|
|
2756
|
-
this.error("Param expected: 'positions', 'positionsCompressed' or `buckets` ('geometryId' is absent)");
|
|
2757
|
-
return false;
|
|
2758
|
-
}
|
|
2759
|
-
if (cfg.positions && (cfg.positionsDecodeMatrix || cfg.positionsDecodeBoundary)) {
|
|
2760
|
-
this.error("Illegal params: 'positions' not expected with 'positionsDecodeMatrix'/'positionsDecodeBoundary' ('geometryId' is absent)");
|
|
2761
|
-
return false;
|
|
2762
|
-
}
|
|
2763
|
-
if (cfg.positionsCompressed && !cfg.positionsDecodeMatrix && !cfg.positionsDecodeBoundary) {
|
|
2764
|
-
this.error("Param expected: 'positionsCompressed' should be accompanied by 'positionsDecodeMatrix'/'positionsDecodeBoundary' ('geometryId' is absent)");
|
|
2765
|
-
return false;
|
|
2766
|
-
}
|
|
2767
|
-
if (cfg.uvCompressed && !cfg.uvDecodeMatrix) {
|
|
2768
|
-
this.error("Param expected: 'uvCompressed' should be accompanied by `uvDecodeMatrix` ('geometryId' is absent)");
|
|
2769
|
-
return false;
|
|
2770
|
-
}
|
|
2771
|
-
if (!cfg.buckets && !cfg.indices && cfg.primitive !== "points") {
|
|
2772
|
-
this.error(`Param expected: indices (required for '${cfg.primitive}' primitive type)`);
|
|
2773
|
-
return false;
|
|
2774
|
-
}
|
|
2775
|
-
if ((cfg.matrix || cfg.position || cfg.rotation || cfg.scale) && (cfg.positionsCompressed || cfg.positionsDecodeBoundary)) {
|
|
2776
|
-
this.error("Unexpected params: 'matrix', 'rotation', 'scale', 'position' not allowed with 'positionsCompressed'");
|
|
2777
|
-
return false;
|
|
2778
|
-
}
|
|
2779
|
-
|
|
2780
|
-
const useDTX = (!!this._dtxEnabled && (cfg.primitive === "triangles"
|
|
2781
|
-
|| cfg.primitive === "solid"
|
|
2782
|
-
|| cfg.primitive === "surface"));
|
|
2783
|
-
|
|
2784
|
-
cfg.origin = cfg.origin ? math.addVec3(this._origin, cfg.origin, math.vec3()) : this._origin;
|
|
2785
|
-
|
|
2786
|
-
// MATRIX - optional for batching
|
|
2787
|
-
|
|
2788
|
-
if (cfg.matrix) {
|
|
2789
|
-
cfg.meshMatrix = cfg.matrix;
|
|
2790
|
-
} else if (cfg.scale || cfg.rotation || cfg.position) {
|
|
2791
|
-
const scale = cfg.scale || DEFAULT_SCALE;
|
|
2792
|
-
const position = cfg.position || DEFAULT_POSITION;
|
|
2793
|
-
const rotation = cfg.rotation || DEFAULT_ROTATION;
|
|
2794
|
-
math.eulerToQuaternion(rotation, "XYZ", DEFAULT_QUATERNION);
|
|
2795
|
-
cfg.meshMatrix = math.composeMat4(position, DEFAULT_QUATERNION, scale, math.mat4());
|
|
2796
|
-
}
|
|
2797
|
-
|
|
2798
|
-
if (cfg.positionsDecodeBoundary) {
|
|
2799
|
-
cfg.positionsDecodeMatrix = createPositionsDecodeMatrix(cfg.positionsDecodeBoundary, math.mat4());
|
|
2800
|
-
}
|
|
2801
|
-
|
|
2802
|
-
if (useDTX) {
|
|
2803
|
-
|
|
2804
|
-
// DTX
|
|
2805
|
-
|
|
2806
|
-
cfg.type = DTX;
|
|
2807
|
-
|
|
2808
|
-
// NPR
|
|
2809
|
-
|
|
2810
|
-
cfg.color = (cfg.color) ? new Uint8Array([Math.floor(cfg.color[0] * 255), Math.floor(cfg.color[1] * 255), Math.floor(cfg.color[2] * 255)]) : defaultCompressedColor;
|
|
2811
|
-
cfg.opacity = (cfg.opacity !== undefined && cfg.opacity !== null) ? Math.floor(cfg.opacity * 255) : 255;
|
|
2812
|
-
|
|
2813
|
-
// RTC
|
|
2814
|
-
|
|
2815
|
-
if (cfg.positions) {
|
|
2816
|
-
const rtcCenter = math.vec3();
|
|
2817
|
-
const rtcPositions = [];
|
|
2818
|
-
const rtcNeeded = worldToRTCPositions(cfg.positions, rtcPositions, rtcCenter);
|
|
2819
|
-
if (rtcNeeded) {
|
|
2820
|
-
cfg.positions = rtcPositions;
|
|
2821
|
-
cfg.origin = math.addVec3(cfg.origin, rtcCenter, rtcCenter);
|
|
2822
|
-
}
|
|
2823
|
-
}
|
|
2824
|
-
|
|
2825
|
-
// COMPRESSION
|
|
2826
|
-
|
|
2827
|
-
if (cfg.positions) {
|
|
2828
|
-
const aabb = math.collapseAABB3();
|
|
2829
|
-
cfg.positionsDecodeMatrix = math.mat4();
|
|
2830
|
-
math.expandAABB3Points3(aabb, cfg.positions);
|
|
2831
|
-
cfg.positionsCompressed = quantizePositions(cfg.positions, aabb, cfg.positionsDecodeMatrix);
|
|
2832
|
-
cfg.aabb = aabb;
|
|
2833
|
-
|
|
2834
|
-
} else if (cfg.positionsCompressed) {
|
|
2835
|
-
const aabb = math.collapseAABB3();
|
|
2836
|
-
math.expandAABB3Points3(aabb, cfg.positionsCompressed);
|
|
2837
|
-
geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);
|
|
2838
|
-
cfg.aabb = aabb;
|
|
2839
|
-
|
|
2840
|
-
}
|
|
2841
|
-
if (cfg.buckets) {
|
|
2842
|
-
const aabb = math.collapseAABB3();
|
|
2843
|
-
for (let i = 0, len = cfg.buckets.length; i < len; i++) {
|
|
2844
|
-
const bucket = cfg.buckets[i];
|
|
2845
|
-
if (bucket.positions) {
|
|
2846
|
-
math.expandAABB3Points3(aabb, bucket.positions);
|
|
2847
|
-
} else if (bucket.positionsCompressed) {
|
|
2848
|
-
math.expandAABB3Points3(aabb, bucket.positionsCompressed);
|
|
2849
|
-
}
|
|
2850
|
-
}
|
|
2851
|
-
if (cfg.positionsDecodeMatrix) {
|
|
2852
|
-
geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);
|
|
2853
|
-
}
|
|
2854
|
-
cfg.aabb = aabb;
|
|
2855
|
-
}
|
|
2856
|
-
|
|
2857
|
-
if (cfg.meshMatrix) {
|
|
2858
|
-
math.AABB3ToOBB3(cfg.aabb, tempOBB3);
|
|
2859
|
-
math.transformOBB3(cfg.meshMatrix, tempOBB3);
|
|
2860
|
-
math.OBB3ToAABB3(tempOBB3, cfg.aabb);
|
|
2861
|
-
}
|
|
2862
|
-
|
|
2863
|
-
// EDGES
|
|
2864
|
-
|
|
2865
|
-
if (!cfg.buckets && !cfg.edgeIndices && (cfg.primitive === "triangles" || cfg.primitive === "solid" || cfg.primitive === "surface")) {
|
|
2866
|
-
if (cfg.positions) { // Faster
|
|
2867
|
-
cfg.edgeIndices = buildEdgeIndices(cfg.positions, cfg.indices, null, 2.0);
|
|
2868
|
-
} else {
|
|
2869
|
-
cfg.edgeIndices = buildEdgeIndices(cfg.positionsCompressed, cfg.indices, cfg.positionsDecodeMatrix, 2.0);
|
|
2870
|
-
}
|
|
2871
|
-
}
|
|
2872
|
-
|
|
2873
|
-
// BUCKETING
|
|
2874
|
-
|
|
2875
|
-
if (!cfg.buckets) {
|
|
2876
|
-
cfg.buckets = createDTXBuckets(cfg, this._enableVertexWelding && this._enableIndexBucketing);
|
|
2877
|
-
}
|
|
2878
|
-
|
|
2879
|
-
} else {
|
|
2880
|
-
|
|
2881
|
-
// VBO
|
|
2882
|
-
|
|
2883
|
-
cfg.type = VBO_BATCHED;
|
|
2884
|
-
|
|
2885
|
-
// PBR
|
|
2886
|
-
|
|
2887
|
-
cfg.color = (cfg.color) ? new Uint8Array([Math.floor(cfg.color[0] * 255), Math.floor(cfg.color[1] * 255), Math.floor(cfg.color[2] * 255)]) : [255, 255, 255];
|
|
2888
|
-
cfg.opacity = (cfg.opacity !== undefined && cfg.opacity !== null) ? Math.floor(cfg.opacity * 255) : 255;
|
|
2889
|
-
cfg.metallic = (cfg.metallic !== undefined && cfg.metallic !== null) ? Math.floor(cfg.metallic * 255) : 0;
|
|
2890
|
-
cfg.roughness = (cfg.roughness !== undefined && cfg.roughness !== null) ? Math.floor(cfg.roughness * 255) : 255;
|
|
2891
|
-
|
|
2892
|
-
// RTC
|
|
2893
|
-
|
|
2894
|
-
if (cfg.positions) {
|
|
2895
|
-
const rtcPositions = [];
|
|
2896
|
-
const rtcNeeded = worldToRTCPositions(cfg.positions, rtcPositions, tempVec3a);
|
|
2897
|
-
if (rtcNeeded) {
|
|
2898
|
-
cfg.positions = rtcPositions;
|
|
2899
|
-
cfg.origin = math.addVec3(cfg.origin, tempVec3a, math.vec3());
|
|
2900
|
-
}
|
|
2901
|
-
}
|
|
2902
|
-
|
|
2903
|
-
if (cfg.positions) {
|
|
2904
|
-
const aabb = math.collapseAABB3();
|
|
2905
|
-
if (cfg.meshMatrix) {
|
|
2906
|
-
math.transformPositions3(cfg.meshMatrix, cfg.positions, cfg.positions);
|
|
2907
|
-
cfg.meshMatrix = null; // Positions now baked, don't need any more
|
|
2908
|
-
}
|
|
2909
|
-
math.expandAABB3Points3(aabb, cfg.positions);
|
|
2910
|
-
cfg.aabb = aabb;
|
|
2911
|
-
|
|
2912
|
-
} else {
|
|
2913
|
-
const aabb = math.collapseAABB3();
|
|
2914
|
-
math.expandAABB3Points3(aabb, cfg.positionsCompressed);
|
|
2915
|
-
geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);
|
|
2916
|
-
cfg.aabb = aabb;
|
|
2917
|
-
}
|
|
2918
|
-
|
|
2919
|
-
if (cfg.meshMatrix) {
|
|
2920
|
-
math.AABB3ToOBB3(cfg.aabb, tempOBB3);
|
|
2921
|
-
math.transformOBB3(cfg.meshMatrix, tempOBB3);
|
|
2922
|
-
math.OBB3ToAABB3(tempOBB3, cfg.aabb);
|
|
2923
|
-
}
|
|
2924
|
-
|
|
2925
|
-
// EDGES
|
|
2926
|
-
|
|
2927
|
-
if (!cfg.buckets && !cfg.edgeIndices && (cfg.primitive === "triangles" || cfg.primitive === "solid" || cfg.primitive === "surface")) {
|
|
2928
|
-
if (cfg.positions) {
|
|
2929
|
-
cfg.edgeIndices = buildEdgeIndices(cfg.positions, cfg.indices, null, 2.0);
|
|
2930
|
-
} else {
|
|
2931
|
-
cfg.edgeIndices = buildEdgeIndices(cfg.positionsCompressed, cfg.indices, cfg.positionsDecodeMatrix, 2.0);
|
|
2932
|
-
}
|
|
2933
|
-
}
|
|
2934
|
-
|
|
2935
|
-
// TEXTURE
|
|
2936
|
-
|
|
2937
|
-
// cfg.textureSetId = cfg.textureSetId || DEFAULT_TEXTURE_SET_ID;
|
|
2938
|
-
if (cfg.textureSetId) {
|
|
2939
|
-
cfg.textureSet = this._textureSets[cfg.textureSetId];
|
|
2940
|
-
if (!cfg.textureSet) {
|
|
2941
|
-
this.error(`[createMesh] Texture set not found: ${cfg.textureSetId} - ensure that you create it first with createTextureSet()`);
|
|
2942
|
-
return false;
|
|
2943
|
-
}
|
|
2944
|
-
}
|
|
2945
|
-
}
|
|
2946
|
-
|
|
2947
|
-
} else {
|
|
2948
|
-
|
|
2949
|
-
// INSTANCING
|
|
2950
|
-
|
|
2951
|
-
if (cfg.positions || cfg.positionsCompressed || cfg.indices || cfg.edgeIndices || cfg.normals || cfg.normalsCompressed || cfg.uv || cfg.uvCompressed || cfg.positionsDecodeMatrix) {
|
|
2952
|
-
this.error(`Mesh geometry parameters not expected when instancing a geometry (not expected: positions, positionsCompressed, indices, edgeIndices, normals, normalsCompressed, uv, uvCompressed, positionsDecodeMatrix)`);
|
|
2953
|
-
return false;
|
|
2954
|
-
}
|
|
2955
|
-
|
|
2956
|
-
cfg.geometry = this._geometries[cfg.geometryId];
|
|
2957
|
-
if (!cfg.geometry) {
|
|
2958
|
-
this.error(`[createMesh] Geometry not found: ${cfg.geometryId} - ensure that you create it first with createGeometry()`);
|
|
2959
|
-
return false;
|
|
2960
|
-
}
|
|
2961
|
-
|
|
2962
|
-
cfg.origin = cfg.origin ? math.addVec3(this._origin, cfg.origin, math.vec3()) : this._origin;
|
|
2963
|
-
cfg.positionsDecodeMatrix = cfg.geometry.positionsDecodeMatrix;
|
|
2964
|
-
|
|
2965
|
-
if (cfg.transformId) {
|
|
2966
|
-
|
|
2967
|
-
// TRANSFORM
|
|
2968
|
-
|
|
2969
|
-
cfg.transform = this._transforms[cfg.transformId];
|
|
2970
|
-
|
|
2971
|
-
if (!cfg.transform) {
|
|
2972
|
-
this.error(`[createMesh] Transform not found: ${cfg.transformId} - ensure that you create it first with createTransform()`);
|
|
2973
|
-
return false;
|
|
2974
|
-
}
|
|
2975
|
-
|
|
2976
|
-
cfg.aabb = cfg.geometry.aabb;
|
|
2977
|
-
|
|
2978
|
-
} else {
|
|
2979
|
-
|
|
2980
|
-
// MATRIX
|
|
2981
|
-
|
|
2982
|
-
if (cfg.matrix) {
|
|
2983
|
-
cfg.meshMatrix = cfg.matrix.slice();
|
|
2984
|
-
} else {
|
|
2985
|
-
const scale = cfg.scale || DEFAULT_SCALE;
|
|
2986
|
-
const position = cfg.position || DEFAULT_POSITION;
|
|
2987
|
-
const rotation = cfg.rotation || DEFAULT_ROTATION;
|
|
2988
|
-
math.eulerToQuaternion(rotation, "XYZ", DEFAULT_QUATERNION);
|
|
2989
|
-
cfg.meshMatrix = math.composeMat4(position, DEFAULT_QUATERNION, scale, math.mat4());
|
|
2990
|
-
}
|
|
2991
|
-
|
|
2992
|
-
math.AABB3ToOBB3(cfg.geometry.aabb, tempOBB3);
|
|
2993
|
-
math.transformOBB3(cfg.meshMatrix, tempOBB3);
|
|
2994
|
-
cfg.aabb = math.OBB3ToAABB3(tempOBB3, math.AABB3());
|
|
2995
|
-
}
|
|
2996
|
-
|
|
2997
|
-
const useDTX = (!!this._dtxEnabled
|
|
2998
|
-
&& (cfg.geometry.primitive === "triangles"
|
|
2999
|
-
|| cfg.geometry.primitive === "solid"
|
|
3000
|
-
|| cfg.geometry.primitive === "surface"));
|
|
3001
|
-
|
|
3002
|
-
if (useDTX) {
|
|
3003
|
-
|
|
3004
|
-
// DTX
|
|
3005
|
-
|
|
3006
|
-
cfg.type = DTX;
|
|
3007
|
-
|
|
3008
|
-
// NPR
|
|
3009
|
-
|
|
3010
|
-
cfg.color = (cfg.color) ? new Uint8Array([Math.floor(cfg.color[0] * 255), Math.floor(cfg.color[1] * 255), Math.floor(cfg.color[2] * 255)]) : defaultCompressedColor;
|
|
3011
|
-
cfg.opacity = (cfg.opacity !== undefined && cfg.opacity !== null) ? Math.floor(cfg.opacity * 255) : 255;
|
|
3012
|
-
|
|
3013
|
-
// BUCKETING - lazy generated, reused
|
|
3014
|
-
|
|
3015
|
-
let buckets = this._dtxBuckets[cfg.geometryId];
|
|
3016
|
-
if (!buckets) {
|
|
3017
|
-
buckets = createDTXBuckets(cfg.geometry, this._enableVertexWelding, this._enableIndexBucketing);
|
|
3018
|
-
this._dtxBuckets[cfg.geometryId] = buckets;
|
|
3019
|
-
}
|
|
3020
|
-
cfg.buckets = buckets;
|
|
3021
|
-
|
|
3022
|
-
} else {
|
|
3023
|
-
|
|
3024
|
-
// VBO
|
|
3025
|
-
|
|
3026
|
-
cfg.type = VBO_INSTANCED;
|
|
3027
|
-
|
|
3028
|
-
// PBR
|
|
3029
|
-
|
|
3030
|
-
cfg.color = (cfg.color) ? new Uint8Array([Math.floor(cfg.color[0] * 255), Math.floor(cfg.color[1] * 255), Math.floor(cfg.color[2] * 255)]) : defaultCompressedColor;
|
|
3031
|
-
cfg.opacity = (cfg.opacity !== undefined && cfg.opacity !== null) ? Math.floor(cfg.opacity * 255) : 255;
|
|
3032
|
-
cfg.metallic = (cfg.metallic !== undefined && cfg.metallic !== null) ? Math.floor(cfg.metallic * 255) : 0;
|
|
3033
|
-
cfg.roughness = (cfg.roughness !== undefined && cfg.roughness !== null) ? Math.floor(cfg.roughness * 255) : 255;
|
|
3034
|
-
|
|
3035
|
-
// TEXTURE
|
|
3036
|
-
|
|
3037
|
-
if (cfg.textureSetId) {
|
|
3038
|
-
cfg.textureSet = this._textureSets[cfg.textureSetId];
|
|
3039
|
-
// if (!cfg.textureSet) {
|
|
3040
|
-
// this.error(`[createMesh] Texture set not found: ${cfg.textureSetId} - ensure that you create it first with createTextureSet()`);
|
|
3041
|
-
// return false;
|
|
3042
|
-
// }
|
|
3043
|
-
}
|
|
3044
|
-
}
|
|
3045
|
-
}
|
|
3046
|
-
|
|
3047
|
-
cfg.numPrimitives = this._getNumPrimitives(cfg);
|
|
3048
|
-
|
|
3049
|
-
this._meshesCfgsBeforeMeshCreation[cfg.id] = cfg;
|
|
3050
|
-
|
|
3051
|
-
return true;
|
|
3052
|
-
}
|
|
3053
|
-
|
|
3054
|
-
_createMesh(cfg) {
|
|
3055
|
-
const mesh = new SceneModelMesh(this, cfg.id, cfg.color, cfg.opacity, cfg.transform, cfg.textureSet);
|
|
3056
|
-
mesh.pickId = this.scene._renderer.getPickID(mesh);
|
|
3057
|
-
const pickId = mesh.pickId;
|
|
3058
|
-
const a = pickId >> 24 & 0xFF;
|
|
3059
|
-
const b = pickId >> 16 & 0xFF;
|
|
3060
|
-
const g = pickId >> 8 & 0xFF;
|
|
3061
|
-
const r = pickId & 0xFF;
|
|
3062
|
-
cfg.pickColor = new Uint8Array([r, g, b, a]); // Quantized pick color
|
|
3063
|
-
cfg.solid = (cfg.primitive === "solid");
|
|
3064
|
-
mesh.origin = math.vec3(cfg.origin);
|
|
3065
|
-
switch (cfg.type) {
|
|
3066
|
-
case DTX:
|
|
3067
|
-
mesh.layer = this._getDTXLayer(cfg);
|
|
3068
|
-
mesh.aabb = cfg.aabb;
|
|
3069
|
-
break;
|
|
3070
|
-
case VBO_BATCHED:
|
|
3071
|
-
mesh.layer = this._getVBOBatchingLayer(cfg);
|
|
3072
|
-
mesh.aabb = cfg.aabb;
|
|
3073
|
-
break;
|
|
3074
|
-
case VBO_INSTANCED:
|
|
3075
|
-
mesh.layer = this._getVBOInstancingLayer(cfg);
|
|
3076
|
-
mesh.aabb = cfg.aabb;
|
|
3077
|
-
break;
|
|
3078
|
-
}
|
|
3079
|
-
if (cfg.transform) {
|
|
3080
|
-
cfg.meshMatrix = cfg.transform.worldMatrix;
|
|
3081
|
-
}
|
|
3082
|
-
mesh.portionId = mesh.layer.createPortion(mesh, cfg);
|
|
3083
|
-
return mesh;
|
|
3084
|
-
}
|
|
3085
|
-
|
|
3086
|
-
_getNumPrimitives(cfg) {
|
|
3087
|
-
let countIndices = 0;
|
|
3088
|
-
const primitive = cfg.geometry ? cfg.geometry.primitive : cfg.primitive;
|
|
3089
|
-
switch (primitive) {
|
|
3090
|
-
case "triangles":
|
|
3091
|
-
case "solid":
|
|
3092
|
-
case "surface":
|
|
3093
|
-
switch (cfg.type) {
|
|
3094
|
-
case DTX:
|
|
3095
|
-
for (let i = 0, len = cfg.buckets.length; i < len; i++) {
|
|
3096
|
-
countIndices += cfg.buckets[i].indices.length;
|
|
3097
|
-
}
|
|
3098
|
-
break;
|
|
3099
|
-
case VBO_BATCHED:
|
|
3100
|
-
countIndices += cfg.indices.length;
|
|
3101
|
-
break;
|
|
3102
|
-
case VBO_INSTANCED:
|
|
3103
|
-
countIndices += cfg.geometry.indices.length;
|
|
3104
|
-
break;
|
|
3105
|
-
}
|
|
3106
|
-
return Math.round(countIndices / 3);
|
|
3107
|
-
case "points":
|
|
3108
|
-
switch (cfg.type) {
|
|
3109
|
-
case DTX:
|
|
3110
|
-
for (let i = 0, len = cfg.buckets.length; i < len; i++) {
|
|
3111
|
-
countIndices += cfg.buckets[i].positionsCompressed.length;
|
|
3112
|
-
}
|
|
3113
|
-
break;
|
|
3114
|
-
case VBO_BATCHED:
|
|
3115
|
-
countIndices += cfg.positions ? cfg.positions.length : cfg.positionsCompressed.length;
|
|
3116
|
-
break;
|
|
3117
|
-
case VBO_INSTANCED:
|
|
3118
|
-
const geometry = cfg.geometry;
|
|
3119
|
-
countIndices += geometry.positions ? geometry.positions.length : geometry.positionsCompressed.length;
|
|
3120
|
-
break;
|
|
3121
|
-
}
|
|
3122
|
-
return Math.round(countIndices);
|
|
3123
|
-
case "lines":
|
|
3124
|
-
case "line-strip":
|
|
3125
|
-
switch (cfg.type) {
|
|
3126
|
-
case DTX:
|
|
3127
|
-
for (let i = 0, len = cfg.buckets.length; i < len; i++) {
|
|
3128
|
-
countIndices += cfg.buckets[i].indices.length;
|
|
3129
|
-
}
|
|
3130
|
-
break;
|
|
3131
|
-
case VBO_BATCHED:
|
|
3132
|
-
countIndices += cfg.indices.length;
|
|
3133
|
-
break;
|
|
3134
|
-
case VBO_INSTANCED:
|
|
3135
|
-
countIndices += cfg.geometry.indices.length;
|
|
3136
|
-
break;
|
|
3137
|
-
}
|
|
3138
|
-
return Math.round(countIndices / 2);
|
|
3139
|
-
}
|
|
3140
|
-
return 0;
|
|
3141
|
-
}
|
|
3142
|
-
|
|
3143
|
-
_getDTXLayer(cfg) {
|
|
3144
|
-
const origin = cfg.origin;
|
|
3145
|
-
const primitive = cfg.geometry ? cfg.geometry.primitive : cfg.primitive;
|
|
3146
|
-
const layerId = `.${primitive}.${Math.round(origin[0])}.${Math.round(origin[1])}.${Math.round(origin[2])}`;
|
|
3147
|
-
let dtxLayer = this._dtxLayers[layerId];
|
|
3148
|
-
if (dtxLayer) {
|
|
3149
|
-
if (!dtxLayer.canCreatePortion(cfg)) {
|
|
3150
|
-
dtxLayer.finalize();
|
|
3151
|
-
delete this._dtxLayers[layerId];
|
|
3152
|
-
dtxLayer = null;
|
|
3153
|
-
} else {
|
|
3154
|
-
return dtxLayer;
|
|
3155
|
-
}
|
|
3156
|
-
}
|
|
3157
|
-
switch (primitive) {
|
|
3158
|
-
case "triangles":
|
|
3159
|
-
case "solid":
|
|
3160
|
-
case "surface":
|
|
3161
|
-
dtxLayer = new DTXTrianglesLayer(this, {layerIndex: 0, origin}); // layerIndex is set in #finalize()
|
|
3162
|
-
break;
|
|
3163
|
-
case "lines":
|
|
3164
|
-
dtxLayer = new DTXLinesLayer(this, {layerIndex: 0, origin}); // layerIndex is set in #finalize()
|
|
3165
|
-
break;
|
|
3166
|
-
default:
|
|
3167
|
-
return;
|
|
3168
|
-
}
|
|
3169
|
-
this._dtxLayers[layerId] = dtxLayer;
|
|
3170
|
-
this.layerList.push(dtxLayer);
|
|
3171
|
-
return dtxLayer;
|
|
3172
|
-
}
|
|
3173
|
-
|
|
3174
|
-
_getVBOBatchingLayer(cfg) {
|
|
3175
|
-
const model = this;
|
|
3176
|
-
const origin = cfg.origin;
|
|
3177
|
-
const positionsDecodeHash = cfg.positionsDecodeMatrix || cfg.positionsDecodeBoundary ?
|
|
3178
|
-
this._createHashStringFromMatrix(cfg.positionsDecodeMatrix || cfg.positionsDecodeBoundary)
|
|
3179
|
-
: "-";
|
|
3180
|
-
const textureSetId = cfg.textureSetId || "-";
|
|
3181
|
-
const layerId = `${Math.round(origin[0])}.${Math.round(origin[1])}.${Math.round(origin[2])}.${cfg.primitive}.${positionsDecodeHash}.${textureSetId}`;
|
|
3182
|
-
let vboBatchingLayer = this._vboBatchingLayers[layerId];
|
|
3183
|
-
if (vboBatchingLayer) {
|
|
3184
|
-
return vboBatchingLayer;
|
|
3185
|
-
}
|
|
3186
|
-
let textureSet = cfg.textureSet;
|
|
3187
|
-
while (!vboBatchingLayer) {
|
|
3188
|
-
switch (cfg.primitive) {
|
|
3189
|
-
case "triangles":
|
|
3190
|
-
// console.info(`[SceneModel ${this.id}]: creating TrianglesBatchingLayer`);
|
|
3191
|
-
vboBatchingLayer = new VBOBatchingTrianglesLayer({
|
|
3192
|
-
model,
|
|
3193
|
-
textureSet,
|
|
3194
|
-
layerIndex: 0, // This is set in #finalize()
|
|
3195
|
-
scratchMemory: this._vboBatchingLayerScratchMemory,
|
|
3196
|
-
positionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined
|
|
3197
|
-
uvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined
|
|
3198
|
-
origin,
|
|
3199
|
-
maxGeometryBatchSize: this._maxGeometryBatchSize,
|
|
3200
|
-
solid: (cfg.primitive === "solid"),
|
|
3201
|
-
autoNormals: true
|
|
3202
|
-
});
|
|
3203
|
-
break;
|
|
3204
|
-
case "solid":
|
|
3205
|
-
// console.info(`[SceneModel ${this.id}]: creating TrianglesBatchingLayer`);
|
|
3206
|
-
vboBatchingLayer = new VBOBatchingTrianglesLayer({
|
|
3207
|
-
model,
|
|
3208
|
-
textureSet,
|
|
3209
|
-
layerIndex: 0, // This is set in #finalize()
|
|
3210
|
-
scratchMemory: this._vboBatchingLayerScratchMemory,
|
|
3211
|
-
positionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined
|
|
3212
|
-
uvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined
|
|
3213
|
-
origin,
|
|
3214
|
-
maxGeometryBatchSize: this._maxGeometryBatchSize,
|
|
3215
|
-
solid: (cfg.primitive === "solid"),
|
|
3216
|
-
autoNormals: true
|
|
3217
|
-
});
|
|
3218
|
-
break;
|
|
3219
|
-
case "surface":
|
|
3220
|
-
// console.info(`[SceneModel ${this.id}]: creating TrianglesBatchingLayer`);
|
|
3221
|
-
vboBatchingLayer = new VBOBatchingTrianglesLayer({
|
|
3222
|
-
model,
|
|
3223
|
-
textureSet,
|
|
3224
|
-
layerIndex: 0, // This is set in #finalize()
|
|
3225
|
-
scratchMemory: this._vboBatchingLayerScratchMemory,
|
|
3226
|
-
positionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined
|
|
3227
|
-
uvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined
|
|
3228
|
-
origin,
|
|
3229
|
-
maxGeometryBatchSize: this._maxGeometryBatchSize,
|
|
3230
|
-
solid: (cfg.primitive === "solid"),
|
|
3231
|
-
autoNormals: true
|
|
3232
|
-
});
|
|
3233
|
-
break;
|
|
3234
|
-
case "lines":
|
|
3235
|
-
// console.info(`[SceneModel ${this.id}]: creating VBOBatchingLinesLayer`);
|
|
3236
|
-
vboBatchingLayer = new VBOBatchingLinesLayer({
|
|
3237
|
-
model,
|
|
3238
|
-
layerIndex: 0, // This is set in #finalize()
|
|
3239
|
-
scratchMemory: this._vboBatchingLayerScratchMemory,
|
|
3240
|
-
positionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined
|
|
3241
|
-
uvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined
|
|
3242
|
-
origin,
|
|
3243
|
-
maxGeometryBatchSize: this._maxGeometryBatchSize
|
|
3244
|
-
});
|
|
3245
|
-
break;
|
|
3246
|
-
case "points":
|
|
3247
|
-
// console.info(`[SceneModel ${this.id}]: creating VBOBatchingPointsLayer`);
|
|
3248
|
-
vboBatchingLayer = new VBOBatchingPointsLayer({
|
|
3249
|
-
model,
|
|
3250
|
-
layerIndex: 0, // This is set in #finalize()
|
|
3251
|
-
scratchMemory: this._vboBatchingLayerScratchMemory,
|
|
3252
|
-
positionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined
|
|
3253
|
-
uvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined
|
|
3254
|
-
origin,
|
|
3255
|
-
maxGeometryBatchSize: this._maxGeometryBatchSize
|
|
3256
|
-
});
|
|
3257
|
-
break;
|
|
3258
|
-
}
|
|
3259
|
-
const lenPositions = cfg.positionsCompressed ? cfg.positionsCompressed.length : cfg.positions.length;
|
|
3260
|
-
const canCreatePortion = (cfg.primitive === "points")
|
|
3261
|
-
? vboBatchingLayer.canCreatePortion(lenPositions)
|
|
3262
|
-
: vboBatchingLayer.canCreatePortion(lenPositions, cfg.indices.length);
|
|
3263
|
-
if (!canCreatePortion) {
|
|
3264
|
-
vboBatchingLayer.finalize();
|
|
3265
|
-
delete this._vboBatchingLayers[layerId];
|
|
3266
|
-
vboBatchingLayer = null;
|
|
3267
|
-
}
|
|
3268
|
-
}
|
|
3269
|
-
this._vboBatchingLayers[layerId] = vboBatchingLayer;
|
|
3270
|
-
this.layerList.push(vboBatchingLayer);
|
|
3271
|
-
return vboBatchingLayer;
|
|
3272
|
-
}
|
|
3273
|
-
|
|
3274
|
-
_createHashStringFromMatrix(matrix) {
|
|
3275
|
-
const matrixString = matrix.join('');
|
|
3276
|
-
let hash = 0;
|
|
3277
|
-
for (let i = 0; i < matrixString.length; i++) {
|
|
3278
|
-
const char = matrixString.charCodeAt(i);
|
|
3279
|
-
hash = (hash << 5) - hash + char;
|
|
3280
|
-
hash |= 0; // Convert to 32-bit integer
|
|
3281
|
-
}
|
|
3282
|
-
const hashString = (hash >>> 0).toString(16);
|
|
3283
|
-
return hashString;
|
|
3284
|
-
}
|
|
3285
|
-
|
|
3286
|
-
_getVBOInstancingLayer(cfg) {
|
|
3287
|
-
const model = this;
|
|
3288
|
-
const origin = cfg.origin;
|
|
3289
|
-
const textureSetId = cfg.textureSetId || "-";
|
|
3290
|
-
const geometryId = cfg.geometryId;
|
|
3291
|
-
const layerId = `${Math.round(origin[0])}.${Math.round(origin[1])}.${Math.round(origin[2])}.${textureSetId}.${geometryId}`;
|
|
3292
|
-
let vboInstancingLayer = this._vboInstancingLayers[layerId];
|
|
3293
|
-
if (vboInstancingLayer) {
|
|
3294
|
-
return vboInstancingLayer;
|
|
3295
|
-
}
|
|
3296
|
-
let textureSet = cfg.textureSet;
|
|
3297
|
-
const geometry = cfg.geometry;
|
|
3298
|
-
while (!vboInstancingLayer) {
|
|
3299
|
-
switch (geometry.primitive) {
|
|
3300
|
-
case "triangles":
|
|
3301
|
-
// console.info(`[SceneModel ${this.id}]: creating TrianglesInstancingLayer`);
|
|
3302
|
-
vboInstancingLayer = new VBOInstancingTrianglesLayer({
|
|
3303
|
-
model,
|
|
3304
|
-
textureSet,
|
|
3305
|
-
geometry,
|
|
3306
|
-
origin,
|
|
3307
|
-
layerIndex: 0,
|
|
3308
|
-
solid: false
|
|
3309
|
-
});
|
|
3310
|
-
break;
|
|
3311
|
-
case "solid":
|
|
3312
|
-
// console.info(`[SceneModel ${this.id}]: creating TrianglesInstancingLayer`);
|
|
3313
|
-
vboInstancingLayer = new VBOInstancingTrianglesLayer({
|
|
3314
|
-
model,
|
|
3315
|
-
textureSet,
|
|
3316
|
-
geometry,
|
|
3317
|
-
origin,
|
|
3318
|
-
layerIndex: 0,
|
|
3319
|
-
solid: true
|
|
3320
|
-
});
|
|
3321
|
-
break;
|
|
3322
|
-
case "surface":
|
|
3323
|
-
// console.info(`[SceneModel ${this.id}]: creating TrianglesInstancingLayer`);
|
|
3324
|
-
vboInstancingLayer = new VBOInstancingTrianglesLayer({
|
|
3325
|
-
model,
|
|
3326
|
-
textureSet,
|
|
3327
|
-
geometry,
|
|
3328
|
-
origin,
|
|
3329
|
-
layerIndex: 0,
|
|
3330
|
-
solid: false
|
|
3331
|
-
});
|
|
3332
|
-
break;
|
|
3333
|
-
case "lines":
|
|
3334
|
-
// console.info(`[SceneModel ${this.id}]: creating VBOInstancingLinesLayer`);
|
|
3335
|
-
vboInstancingLayer = new VBOInstancingLinesLayer({
|
|
3336
|
-
model,
|
|
3337
|
-
textureSet,
|
|
3338
|
-
geometry,
|
|
3339
|
-
origin,
|
|
3340
|
-
layerIndex: 0
|
|
3341
|
-
});
|
|
3342
|
-
break;
|
|
3343
|
-
case "points":
|
|
3344
|
-
// console.info(`[SceneModel ${this.id}]: creating PointsInstancingLayer`);
|
|
3345
|
-
vboInstancingLayer = new VBOInstancingPointsLayer({
|
|
3346
|
-
model,
|
|
3347
|
-
textureSet,
|
|
3348
|
-
geometry,
|
|
3349
|
-
origin,
|
|
3350
|
-
layerIndex: 0
|
|
3351
|
-
});
|
|
3352
|
-
break;
|
|
3353
|
-
}
|
|
3354
|
-
// const lenPositions = geometry.positionsCompressed.length;
|
|
3355
|
-
// if (!vboInstancingLayer.canCreatePortion(lenPositions, geometry.indices.length)) { // FIXME: indices should be optional
|
|
3356
|
-
// vboInstancingLayer.finalize();
|
|
3357
|
-
// delete this._vboInstancingLayers[layerId];
|
|
3358
|
-
// vboInstancingLayer = null;
|
|
3359
|
-
// }
|
|
3360
|
-
}
|
|
3361
|
-
this._vboInstancingLayers[layerId] = vboInstancingLayer;
|
|
3362
|
-
this.layerList.push(vboInstancingLayer);
|
|
3363
|
-
return vboInstancingLayer;
|
|
3364
|
-
}
|
|
3365
|
-
|
|
3366
|
-
/**
|
|
3367
|
-
* Creates a {@link SceneModelEntity} within this SceneModel.
|
|
3368
|
-
*
|
|
3369
|
-
* * Gives the SceneModelEntity one or more {@link SceneModelMesh}es previously created with
|
|
3370
|
-
* {@link SceneModel#createMesh}. A SceneModelMesh can only belong to one SceneModelEntity, so you'll get an
|
|
3371
|
-
* error if you try to reuse a mesh among multiple SceneModelEntitys.
|
|
3372
|
-
* * The SceneModelEntity can have a {@link SceneModelTextureSet}, previously created with
|
|
3373
|
-
* {@link SceneModel#createTextureSet}. A SceneModelTextureSet can belong to multiple SceneModelEntitys.
|
|
3374
|
-
* * The SceneModelEntity can have a geometry, previously created with
|
|
3375
|
-
* {@link SceneModel#createTextureSet}. A geometry is a "virtual component" and can belong to multiple SceneModelEntitys.
|
|
3376
|
-
*
|
|
3377
|
-
* @param {Object} cfg SceneModelEntity configuration.
|
|
3378
|
-
* @param {String} cfg.id Optional ID for the new SceneModelEntity. Must not clash with any existing components within the {@link Scene}.
|
|
3379
|
-
* @param {String[]} cfg.meshIds IDs of one or more meshes created previously with {@link SceneModel@createMesh}.
|
|
3380
|
-
* @param {Boolean} [cfg.isObject] Set ````true```` if the {@link SceneModelEntity} represents an object, in which case it will be registered by {@link SceneModelEntity#id} in {@link Scene#objects} and can also have a corresponding {@link MetaObject} with matching {@link MetaObject#id}, registered by that ID in {@link MetaScene#metaObjects}.
|
|
3381
|
-
* @param {Boolean} [cfg.visible=true] Indicates if the SceneModelEntity is initially visible.
|
|
3382
|
-
* @param {Boolean} [cfg.culled=false] Indicates if the SceneModelEntity is initially culled from view.
|
|
3383
|
-
* @param {Boolean} [cfg.pickable=true] Indicates if the SceneModelEntity is initially pickable.
|
|
3384
|
-
* @param {Boolean} [cfg.clippable=true] Indicates if the SceneModelEntity is initially clippable.
|
|
3385
|
-
* @param {Boolean} [cfg.collidable=true] Indicates if the SceneModelEntity is initially included in boundary calculations.
|
|
3386
|
-
* @param {Boolean} [cfg.castsShadow=true] Indicates if the SceneModelEntity initially casts shadows.
|
|
3387
|
-
* @param {Boolean} [cfg.receivesShadow=true] Indicates if the SceneModelEntity initially receives shadows.
|
|
3388
|
-
* @param {Boolean} [cfg.xrayed=false] Indicates if the SceneModelEntity is initially xrayed. XRayed appearance is configured by {@link SceneModel#xrayMaterial}.
|
|
3389
|
-
* @param {Boolean} [cfg.highlighted=false] Indicates if the SceneModelEntity is initially highlighted. Highlighted appearance is configured by {@link SceneModel#highlightMaterial}.
|
|
3390
|
-
* @param {Boolean} [cfg.selected=false] Indicates if the SceneModelEntity is initially selected. Selected appearance is configured by {@link SceneModel#selectedMaterial}.
|
|
3391
|
-
* @param {Boolean} [cfg.edges=false] Indicates if the SceneModelEntity's edges are initially emphasized. Edges appearance is configured by {@link SceneModel#edgeMaterial}.
|
|
3392
|
-
* @returns {SceneModelEntity} The new SceneModelEntity.
|
|
3393
|
-
*/
|
|
3394
|
-
createEntity(cfg) {
|
|
3395
|
-
if (cfg.id === undefined) {
|
|
3396
|
-
cfg.id = math.createUUID();
|
|
3397
|
-
} else if (this.scene.components[cfg.id]) {
|
|
3398
|
-
this.error(`Scene already has a Component with this ID: ${cfg.id} - will assign random ID`);
|
|
3399
|
-
cfg.id = math.createUUID();
|
|
3400
|
-
}
|
|
3401
|
-
if (cfg.meshIds === undefined) {
|
|
3402
|
-
this.error("Config missing: meshIds");
|
|
3403
|
-
return;
|
|
3404
|
-
}
|
|
3405
|
-
let flags = 0;
|
|
3406
|
-
if (this._visible && cfg.visible !== false) {
|
|
3407
|
-
flags = flags | ENTITY_FLAGS.VISIBLE;
|
|
3408
|
-
}
|
|
3409
|
-
if (this._pickable && cfg.pickable !== false) {
|
|
3410
|
-
flags = flags | ENTITY_FLAGS.PICKABLE;
|
|
3411
|
-
}
|
|
3412
|
-
if (this._culled && cfg.culled !== false) {
|
|
3413
|
-
flags = flags | ENTITY_FLAGS.CULLED;
|
|
3414
|
-
}
|
|
3415
|
-
if (this._clippable && cfg.clippable !== false) {
|
|
3416
|
-
flags = flags | ENTITY_FLAGS.CLIPPABLE;
|
|
3417
|
-
}
|
|
3418
|
-
if (this._collidable && cfg.collidable !== false) {
|
|
3419
|
-
flags = flags | ENTITY_FLAGS.COLLIDABLE;
|
|
3420
|
-
}
|
|
3421
|
-
if (this._edges && cfg.edges !== false) {
|
|
3422
|
-
flags = flags | ENTITY_FLAGS.EDGES;
|
|
3423
|
-
}
|
|
3424
|
-
if (this._xrayed && cfg.xrayed !== false) {
|
|
3425
|
-
flags = flags | ENTITY_FLAGS.XRAYED;
|
|
3426
|
-
}
|
|
3427
|
-
if (this._highlighted && cfg.highlighted !== false) {
|
|
3428
|
-
flags = flags | ENTITY_FLAGS.HIGHLIGHTED;
|
|
3429
|
-
}
|
|
3430
|
-
if (this._selected && cfg.selected !== false) {
|
|
3431
|
-
flags = flags | ENTITY_FLAGS.SELECTED;
|
|
3432
|
-
}
|
|
3433
|
-
cfg.flags = flags;
|
|
3434
|
-
this._createEntity(cfg);
|
|
3435
|
-
}
|
|
3436
|
-
|
|
3437
|
-
_createEntity(cfg) {
|
|
3438
|
-
let meshes = [];
|
|
3439
|
-
for (let i = 0, len = cfg.meshIds.length; i < len; i++) {
|
|
3440
|
-
const meshId = cfg.meshIds[i];
|
|
3441
|
-
let mesh = this._meshes[meshId]; // Trying to get already created mesh
|
|
3442
|
-
if (!mesh) { // Checks if there is already created mesh for this meshId
|
|
3443
|
-
let meshCfg = this._meshesCfgsBeforeMeshCreation[meshId]; // Trying to get already created cfg
|
|
3444
|
-
if (!meshCfg) { // Checks if there is already created cfg for this meshId
|
|
3445
|
-
this.error(`Mesh with this ID not found: "${meshId}" - ignoring this mesh`); // There is no such cfg
|
|
3446
|
-
continue;
|
|
3447
|
-
}
|
|
3448
|
-
mesh = this._createMesh(meshCfg) // There is no such mesh yet, but there is already created cfg, so it creates this mesh
|
|
3449
|
-
this._meshes[cfg.id] = mesh; // Now it will also add this mesh to dictionary of created meshes
|
|
3450
|
-
}
|
|
3451
|
-
if (mesh.parent) {
|
|
3452
|
-
this.error(`Mesh with ID "${meshId}" already belongs to object with ID "${mesh.parent.id}" - ignoring this mesh`);
|
|
3453
|
-
continue;
|
|
3454
|
-
}
|
|
3455
|
-
meshes.push(mesh);
|
|
3456
|
-
}
|
|
3457
|
-
const lodCullable = true;
|
|
3458
|
-
const entity = new SceneModelEntity(
|
|
3459
|
-
this,
|
|
3460
|
-
cfg.isObject,
|
|
3461
|
-
cfg.id,
|
|
3462
|
-
meshes,
|
|
3463
|
-
cfg.flags,
|
|
3464
|
-
lodCullable); // Internally sets SceneModelEntity#parent to this SceneModel
|
|
3465
|
-
this._entityList.push(entity);
|
|
3466
|
-
this._entities[cfg.id] = entity;
|
|
3467
|
-
this.numEntities++;
|
|
3468
|
-
}
|
|
3469
|
-
|
|
3470
|
-
/**
|
|
3471
|
-
* Finalizes this SceneModel.
|
|
3472
|
-
*
|
|
3473
|
-
* Once finalized, you can't add anything more to this SceneModel.
|
|
3474
|
-
*/
|
|
3475
|
-
finalize() {
|
|
3476
|
-
if (this.destroyed) {
|
|
3477
|
-
return;
|
|
3478
|
-
}
|
|
3479
|
-
for (let i = 0, len = this.layerList.length; i < len; i++) {
|
|
3480
|
-
const layer = this.layerList[i];
|
|
3481
|
-
layer.finalize();
|
|
3482
|
-
}
|
|
3483
|
-
this._geometries = {};
|
|
3484
|
-
this._dtxBuckets = {};
|
|
3485
|
-
this._textures = {};
|
|
3486
|
-
this._textureSets = {};
|
|
3487
|
-
this._dtxLayers = {};
|
|
3488
|
-
this._vboInstancingLayers = {};
|
|
3489
|
-
this._vboBatchingLayers = {};
|
|
3490
|
-
for (let i = 0, len = this._entityList.length; i < len; i++) {
|
|
3491
|
-
const entity = this._entityList[i];
|
|
3492
|
-
entity._finalize();
|
|
3493
|
-
}
|
|
3494
|
-
for (let i = 0, len = this._entityList.length; i < len; i++) {
|
|
3495
|
-
const entity = this._entityList[i];
|
|
3496
|
-
entity._finalize2();
|
|
3497
|
-
}
|
|
3498
|
-
// Sort layers to reduce WebGL shader switching when rendering them
|
|
3499
|
-
this.layerList.sort((a, b) => {
|
|
3500
|
-
if (a.sortId < b.sortId) {
|
|
3501
|
-
return -1;
|
|
3502
|
-
}
|
|
3503
|
-
if (a.sortId > b.sortId) {
|
|
3504
|
-
return 1;
|
|
3505
|
-
}
|
|
3506
|
-
return 0;
|
|
3507
|
-
});
|
|
3508
|
-
for (let i = 0, len = this.layerList.length; i < len; i++) {
|
|
3509
|
-
const layer = this.layerList[i];
|
|
3510
|
-
layer.layerIndex = i;
|
|
3511
|
-
}
|
|
3512
|
-
this.glRedraw();
|
|
3513
|
-
this.scene._aabbDirty = true;
|
|
3514
|
-
this._viewMatrixDirty = true;
|
|
3515
|
-
this._matrixDirty = true;
|
|
3516
|
-
this._aabbDirty = true;
|
|
3517
|
-
|
|
3518
|
-
this._setWorldMatrixDirty();
|
|
3519
|
-
this._sceneModelDirty();
|
|
3520
|
-
|
|
3521
|
-
this.position = this._position;
|
|
3522
|
-
}
|
|
3523
|
-
|
|
3524
|
-
/** @private */
|
|
3525
|
-
stateSortCompare(drawable1, drawable2) {
|
|
3526
|
-
}
|
|
3527
|
-
|
|
3528
|
-
/** @private */
|
|
3529
|
-
rebuildRenderFlags() {
|
|
3530
|
-
this.renderFlags.reset();
|
|
3531
|
-
this._updateRenderFlagsVisibleLayers();
|
|
3532
|
-
if (this.renderFlags.numLayers > 0 && this.renderFlags.numVisibleLayers === 0) {
|
|
3533
|
-
this.renderFlags.culled = true;
|
|
3534
|
-
return;
|
|
3535
|
-
}
|
|
3536
|
-
this._updateRenderFlags();
|
|
3537
|
-
}
|
|
3538
|
-
|
|
3539
|
-
/**
|
|
3540
|
-
* @private
|
|
3541
|
-
*/
|
|
3542
|
-
_updateRenderFlagsVisibleLayers() {
|
|
3543
|
-
const renderFlags = this.renderFlags;
|
|
3544
|
-
renderFlags.numLayers = this.layerList.length;
|
|
3545
|
-
renderFlags.numVisibleLayers = 0;
|
|
3546
|
-
for (let layerIndex = 0, len = this.layerList.length; layerIndex < len; layerIndex++) {
|
|
3547
|
-
const layer = this.layerList[layerIndex];
|
|
3548
|
-
const layerVisible = this._getActiveSectionPlanesForLayer(layer);
|
|
3549
|
-
if (layerVisible) {
|
|
3550
|
-
renderFlags.visibleLayers[renderFlags.numVisibleLayers++] = layerIndex;
|
|
3551
|
-
}
|
|
3552
|
-
}
|
|
3553
|
-
}
|
|
3554
|
-
|
|
3555
|
-
_getActiveSectionPlanesForLayer(layer) {
|
|
3556
|
-
const renderFlags = this.renderFlags;
|
|
3557
|
-
const sectionPlanes = this.scene._sectionPlanesState.sectionPlanes;
|
|
3558
|
-
const numSectionPlanes = sectionPlanes.length;
|
|
3559
|
-
const baseIndex = layer.layerIndex * numSectionPlanes;
|
|
3560
|
-
if (numSectionPlanes > 0) {
|
|
3561
|
-
for (let i = 0; i < numSectionPlanes; i++) {
|
|
3562
|
-
const sectionPlane = sectionPlanes[i];
|
|
3563
|
-
if (!sectionPlane.active) {
|
|
3564
|
-
renderFlags.sectionPlanesActivePerLayer[baseIndex + i] = false;
|
|
3565
|
-
} else {
|
|
3566
|
-
renderFlags.sectionPlanesActivePerLayer[baseIndex + i] = true;
|
|
3567
|
-
renderFlags.sectioned = true;
|
|
3568
|
-
}
|
|
3569
|
-
}
|
|
3570
|
-
}
|
|
3571
|
-
return true;
|
|
3572
|
-
}
|
|
3573
|
-
|
|
3574
|
-
_updateRenderFlags() {
|
|
3575
|
-
if (this.numVisibleLayerPortions === 0) {
|
|
3576
|
-
return;
|
|
3577
|
-
}
|
|
3578
|
-
if (this.numCulledLayerPortions === this.numPortions) {
|
|
3579
|
-
return;
|
|
3580
|
-
}
|
|
3581
|
-
const renderFlags = this.renderFlags;
|
|
3582
|
-
renderFlags.colorOpaque = (this.numTransparentLayerPortions < this.numPortions);
|
|
3583
|
-
if (this.numTransparentLayerPortions > 0) {
|
|
3584
|
-
renderFlags.colorTransparent = true;
|
|
3585
|
-
}
|
|
3586
|
-
if (this.numXRayedLayerPortions > 0) {
|
|
3587
|
-
const xrayMaterial = this.scene.xrayMaterial._state;
|
|
3588
|
-
if (xrayMaterial.fill) {
|
|
3589
|
-
if (xrayMaterial.fillAlpha < 1.0) {
|
|
3590
|
-
renderFlags.xrayedSilhouetteTransparent = true;
|
|
3591
|
-
} else {
|
|
3592
|
-
renderFlags.xrayedSilhouetteOpaque = true;
|
|
3593
|
-
}
|
|
3594
|
-
}
|
|
3595
|
-
if (xrayMaterial.edges) {
|
|
3596
|
-
if (xrayMaterial.edgeAlpha < 1.0) {
|
|
3597
|
-
renderFlags.xrayedEdgesTransparent = true;
|
|
3598
|
-
} else {
|
|
3599
|
-
renderFlags.xrayedEdgesOpaque = true;
|
|
3600
|
-
}
|
|
3601
|
-
}
|
|
3602
|
-
}
|
|
3603
|
-
if (this.numEdgesLayerPortions > 0) {
|
|
3604
|
-
const edgeMaterial = this.scene.edgeMaterial._state;
|
|
3605
|
-
if (edgeMaterial.edges) {
|
|
3606
|
-
renderFlags.edgesOpaque = (this.numTransparentLayerPortions < this.numPortions);
|
|
3607
|
-
if (this.numTransparentLayerPortions > 0) {
|
|
3608
|
-
renderFlags.edgesTransparent = true;
|
|
3609
|
-
}
|
|
3610
|
-
}
|
|
3611
|
-
}
|
|
3612
|
-
if (this.numSelectedLayerPortions > 0) {
|
|
3613
|
-
const selectedMaterial = this.scene.selectedMaterial._state;
|
|
3614
|
-
if (selectedMaterial.fill) {
|
|
3615
|
-
if (selectedMaterial.fillAlpha < 1.0) {
|
|
3616
|
-
renderFlags.selectedSilhouetteTransparent = true;
|
|
3617
|
-
} else {
|
|
3618
|
-
renderFlags.selectedSilhouetteOpaque = true;
|
|
3619
|
-
}
|
|
3620
|
-
}
|
|
3621
|
-
if (selectedMaterial.edges) {
|
|
3622
|
-
if (selectedMaterial.edgeAlpha < 1.0) {
|
|
3623
|
-
renderFlags.selectedEdgesTransparent = true;
|
|
3624
|
-
} else {
|
|
3625
|
-
renderFlags.selectedEdgesOpaque = true;
|
|
3626
|
-
}
|
|
3627
|
-
}
|
|
3628
|
-
}
|
|
3629
|
-
if (this.numHighlightedLayerPortions > 0) {
|
|
3630
|
-
const highlightMaterial = this.scene.highlightMaterial._state;
|
|
3631
|
-
if (highlightMaterial.fill) {
|
|
3632
|
-
if (highlightMaterial.fillAlpha < 1.0) {
|
|
3633
|
-
renderFlags.highlightedSilhouetteTransparent = true;
|
|
3634
|
-
} else {
|
|
3635
|
-
renderFlags.highlightedSilhouetteOpaque = true;
|
|
3636
|
-
}
|
|
3637
|
-
}
|
|
3638
|
-
if (highlightMaterial.edges) {
|
|
3639
|
-
if (highlightMaterial.edgeAlpha < 1.0) {
|
|
3640
|
-
renderFlags.highlightedEdgesTransparent = true;
|
|
3641
|
-
} else {
|
|
3642
|
-
renderFlags.highlightedEdgesOpaque = true;
|
|
3643
|
-
}
|
|
3644
|
-
}
|
|
3645
|
-
}
|
|
3646
|
-
}
|
|
3647
|
-
|
|
3648
|
-
// -------------- RENDERING ---------------------------------------------------------------------------------------
|
|
3649
|
-
|
|
3650
|
-
/** @private */
|
|
3651
|
-
drawColorOpaque(frameCtx) {
|
|
3652
|
-
const renderFlags = this.renderFlags;
|
|
3653
|
-
for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
|
|
3654
|
-
const layerIndex = renderFlags.visibleLayers[i];
|
|
3655
|
-
this.layerList[layerIndex].drawColorOpaque(renderFlags, frameCtx);
|
|
3656
|
-
}
|
|
3657
|
-
}
|
|
3658
|
-
|
|
3659
|
-
/** @private */
|
|
3660
|
-
drawColorTransparent(frameCtx) {
|
|
3661
|
-
const renderFlags = this.renderFlags;
|
|
3662
|
-
for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
|
|
3663
|
-
const layerIndex = renderFlags.visibleLayers[i];
|
|
3664
|
-
this.layerList[layerIndex].drawColorTransparent(renderFlags, frameCtx);
|
|
3665
|
-
}
|
|
3666
|
-
}
|
|
3667
|
-
|
|
3668
|
-
/** @private */
|
|
3669
|
-
drawDepth(frameCtx) { // Dedicated to SAO because it skips transparent objects
|
|
3670
|
-
const renderFlags = this.renderFlags;
|
|
3671
|
-
for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
|
|
3672
|
-
const layerIndex = renderFlags.visibleLayers[i];
|
|
3673
|
-
this.layerList[layerIndex].drawDepth(renderFlags, frameCtx);
|
|
3674
|
-
}
|
|
3675
|
-
}
|
|
3676
|
-
|
|
3677
|
-
/** @private */
|
|
3678
|
-
drawNormals(frameCtx) { // Dedicated to SAO because it skips transparent objects
|
|
3679
|
-
const renderFlags = this.renderFlags;
|
|
3680
|
-
for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
|
|
3681
|
-
const layerIndex = renderFlags.visibleLayers[i];
|
|
3682
|
-
this.layerList[layerIndex].drawNormals(renderFlags, frameCtx);
|
|
3683
|
-
}
|
|
3684
|
-
}
|
|
3685
|
-
|
|
3686
|
-
/** @private */
|
|
3687
|
-
drawSilhouetteXRayed(frameCtx) {
|
|
3688
|
-
const renderFlags = this.renderFlags;
|
|
3689
|
-
for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
|
|
3690
|
-
const layerIndex = renderFlags.visibleLayers[i];
|
|
3691
|
-
this.layerList[layerIndex].drawSilhouetteXRayed(renderFlags, frameCtx);
|
|
3692
|
-
}
|
|
3693
|
-
}
|
|
3694
|
-
|
|
3695
|
-
/** @private */
|
|
3696
|
-
drawSilhouetteHighlighted(frameCtx) {
|
|
3697
|
-
const renderFlags = this.renderFlags;
|
|
3698
|
-
for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
|
|
3699
|
-
const layerIndex = renderFlags.visibleLayers[i];
|
|
3700
|
-
this.layerList[layerIndex].drawSilhouetteHighlighted(renderFlags, frameCtx);
|
|
3701
|
-
}
|
|
3702
|
-
}
|
|
3703
|
-
|
|
3704
|
-
/** @private */
|
|
3705
|
-
drawSilhouetteSelected(frameCtx) {
|
|
3706
|
-
const renderFlags = this.renderFlags;
|
|
3707
|
-
for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
|
|
3708
|
-
const layerIndex = renderFlags.visibleLayers[i];
|
|
3709
|
-
this.layerList[layerIndex].drawSilhouetteSelected(renderFlags, frameCtx);
|
|
3710
|
-
}
|
|
3711
|
-
}
|
|
3712
|
-
|
|
3713
|
-
/** @private */
|
|
3714
|
-
drawEdgesColorOpaque(frameCtx) {
|
|
3715
|
-
const renderFlags = this.renderFlags;
|
|
3716
|
-
for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
|
|
3717
|
-
const layerIndex = renderFlags.visibleLayers[i];
|
|
3718
|
-
this.layerList[layerIndex].drawEdgesColorOpaque(renderFlags, frameCtx);
|
|
3719
|
-
}
|
|
3720
|
-
}
|
|
3721
|
-
|
|
3722
|
-
/** @private */
|
|
3723
|
-
drawEdgesColorTransparent(frameCtx) {
|
|
3724
|
-
const renderFlags = this.renderFlags;
|
|
3725
|
-
for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
|
|
3726
|
-
const layerIndex = renderFlags.visibleLayers[i];
|
|
3727
|
-
this.layerList[layerIndex].drawEdgesColorTransparent(renderFlags, frameCtx);
|
|
3728
|
-
}
|
|
3729
|
-
}
|
|
3730
|
-
|
|
3731
|
-
/** @private */
|
|
3732
|
-
drawEdgesXRayed(frameCtx) {
|
|
3733
|
-
const renderFlags = this.renderFlags;
|
|
3734
|
-
for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
|
|
3735
|
-
const layerIndex = renderFlags.visibleLayers[i];
|
|
3736
|
-
this.layerList[layerIndex].drawEdgesXRayed(renderFlags, frameCtx);
|
|
3737
|
-
}
|
|
3738
|
-
}
|
|
3739
|
-
|
|
3740
|
-
/** @private */
|
|
3741
|
-
drawEdgesHighlighted(frameCtx) {
|
|
3742
|
-
const renderFlags = this.renderFlags;
|
|
3743
|
-
for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
|
|
3744
|
-
const layerIndex = renderFlags.visibleLayers[i];
|
|
3745
|
-
this.layerList[layerIndex].drawEdgesHighlighted(renderFlags, frameCtx);
|
|
3746
|
-
}
|
|
3747
|
-
}
|
|
3748
|
-
|
|
3749
|
-
/** @private */
|
|
3750
|
-
drawEdgesSelected(frameCtx) {
|
|
3751
|
-
const renderFlags = this.renderFlags;
|
|
3752
|
-
for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
|
|
3753
|
-
const layerIndex = renderFlags.visibleLayers[i];
|
|
3754
|
-
this.layerList[layerIndex].drawEdgesSelected(renderFlags, frameCtx);
|
|
3755
|
-
}
|
|
3756
|
-
}
|
|
3757
|
-
|
|
3758
|
-
/**
|
|
3759
|
-
* @private
|
|
3760
|
-
*/
|
|
3761
|
-
drawOcclusion(frameCtx) {
|
|
3762
|
-
if (this.numVisibleLayerPortions === 0) {
|
|
3763
|
-
return;
|
|
3764
|
-
}
|
|
3765
|
-
const renderFlags = this.renderFlags;
|
|
3766
|
-
for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
|
|
3767
|
-
const layerIndex = renderFlags.visibleLayers[i];
|
|
3768
|
-
this.layerList[layerIndex].drawOcclusion(renderFlags, frameCtx);
|
|
3769
|
-
}
|
|
3770
|
-
}
|
|
3771
|
-
|
|
3772
|
-
/**
|
|
3773
|
-
* @private
|
|
3774
|
-
*/
|
|
3775
|
-
drawShadow(frameCtx) {
|
|
3776
|
-
if (this.numVisibleLayerPortions === 0) {
|
|
3777
|
-
return;
|
|
3778
|
-
}
|
|
3779
|
-
const renderFlags = this.renderFlags;
|
|
3780
|
-
for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
|
|
3781
|
-
const layerIndex = renderFlags.visibleLayers[i];
|
|
3782
|
-
this.layerList[layerIndex].drawShadow(renderFlags, frameCtx);
|
|
3783
|
-
}
|
|
3784
|
-
}
|
|
3785
|
-
|
|
3786
|
-
/** @private */
|
|
3787
|
-
setPickMatrices(pickViewMatrix, pickProjMatrix) {
|
|
3788
|
-
if (this._numVisibleLayerPortions === 0) {
|
|
3789
|
-
return;
|
|
3790
|
-
}
|
|
3791
|
-
const renderFlags = this.renderFlags;
|
|
3792
|
-
for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
|
|
3793
|
-
const layerIndex = renderFlags.visibleLayers[i];
|
|
3794
|
-
const layer = this.layerList[layerIndex];
|
|
3795
|
-
if (layer.setPickMatrices) {
|
|
3796
|
-
layer.setPickMatrices(pickViewMatrix, pickProjMatrix);
|
|
3797
|
-
}
|
|
3798
|
-
}
|
|
3799
|
-
}
|
|
3800
|
-
|
|
3801
|
-
/** @private */
|
|
3802
|
-
drawPickMesh(frameCtx) {
|
|
3803
|
-
if (this.numVisibleLayerPortions === 0) {
|
|
3804
|
-
return;
|
|
3805
|
-
}
|
|
3806
|
-
const renderFlags = this.renderFlags;
|
|
3807
|
-
for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
|
|
3808
|
-
const layerIndex = renderFlags.visibleLayers[i];
|
|
3809
|
-
this.layerList[layerIndex].drawPickMesh(renderFlags, frameCtx);
|
|
3810
|
-
}
|
|
3811
|
-
}
|
|
3812
|
-
|
|
3813
|
-
/**
|
|
3814
|
-
* Called by SceneModelMesh.drawPickDepths()
|
|
3815
|
-
* @private
|
|
3816
|
-
*/
|
|
3817
|
-
drawPickDepths(frameCtx) {
|
|
3818
|
-
if (this.numVisibleLayerPortions === 0) {
|
|
3819
|
-
return;
|
|
3820
|
-
}
|
|
3821
|
-
const renderFlags = this.renderFlags;
|
|
3822
|
-
for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
|
|
3823
|
-
const layerIndex = renderFlags.visibleLayers[i];
|
|
3824
|
-
this.layerList[layerIndex].drawPickDepths(renderFlags, frameCtx);
|
|
3825
|
-
}
|
|
3826
|
-
}
|
|
3827
|
-
|
|
3828
|
-
/**
|
|
3829
|
-
* Called by SceneModelMesh.drawPickNormals()
|
|
3830
|
-
* @private
|
|
3831
|
-
*/
|
|
3832
|
-
drawPickNormals(frameCtx) {
|
|
3833
|
-
if (this.numVisibleLayerPortions === 0) {
|
|
3834
|
-
return;
|
|
3835
|
-
}
|
|
3836
|
-
const renderFlags = this.renderFlags;
|
|
3837
|
-
for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
|
|
3838
|
-
const layerIndex = renderFlags.visibleLayers[i];
|
|
3839
|
-
this.layerList[layerIndex].drawPickNormals(renderFlags, frameCtx);
|
|
3840
|
-
}
|
|
3841
|
-
}
|
|
3842
|
-
|
|
3843
|
-
/**
|
|
3844
|
-
* @private
|
|
3845
|
-
*/
|
|
3846
|
-
drawSnapInit(frameCtx) {
|
|
3847
|
-
if (this.numVisibleLayerPortions === 0) {
|
|
3848
|
-
return;
|
|
3849
|
-
}
|
|
3850
|
-
const renderFlags = this.renderFlags;
|
|
3851
|
-
for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
|
|
3852
|
-
const layerIndex = renderFlags.visibleLayers[i];
|
|
3853
|
-
const layer = this.layerList[layerIndex];
|
|
3854
|
-
if (layer.drawSnapInit) {
|
|
3855
|
-
frameCtx.snapPickOrigin = [0, 0, 0];
|
|
3856
|
-
frameCtx.snapPickCoordinateScale = [1, 1, 1];
|
|
3857
|
-
frameCtx.snapPickLayerNumber++;
|
|
3858
|
-
layer.drawSnapInit(renderFlags, frameCtx);
|
|
3859
|
-
frameCtx.snapPickLayerParams[frameCtx.snapPickLayerNumber] = {
|
|
3860
|
-
origin: frameCtx.snapPickOrigin.slice(),
|
|
3861
|
-
coordinateScale: frameCtx.snapPickCoordinateScale.slice(),
|
|
3862
|
-
};
|
|
3863
|
-
}
|
|
3864
|
-
}
|
|
3865
|
-
}
|
|
3866
|
-
|
|
3867
|
-
/**
|
|
3868
|
-
* @private
|
|
3869
|
-
*/
|
|
3870
|
-
drawSnap(frameCtx) {
|
|
3871
|
-
if (this.numVisibleLayerPortions === 0) {
|
|
3872
|
-
return;
|
|
3873
|
-
}
|
|
3874
|
-
const renderFlags = this.renderFlags;
|
|
3875
|
-
for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
|
|
3876
|
-
const layerIndex = renderFlags.visibleLayers[i];
|
|
3877
|
-
const layer = this.layerList[layerIndex];
|
|
3878
|
-
if (layer.drawSnap) {
|
|
3879
|
-
frameCtx.snapPickOrigin = [0, 0, 0];
|
|
3880
|
-
frameCtx.snapPickCoordinateScale = [1, 1, 1];
|
|
3881
|
-
frameCtx.snapPickLayerNumber++;
|
|
3882
|
-
layer.drawSnap(renderFlags, frameCtx);
|
|
3883
|
-
frameCtx.snapPickLayerParams[frameCtx.snapPickLayerNumber] = {
|
|
3884
|
-
origin: frameCtx.snapPickOrigin.slice(),
|
|
3885
|
-
coordinateScale: frameCtx.snapPickCoordinateScale.slice(),
|
|
3886
|
-
};
|
|
3887
|
-
}
|
|
3888
|
-
}
|
|
3889
|
-
}
|
|
3890
|
-
|
|
3891
|
-
/**
|
|
3892
|
-
* Destroys this SceneModel.
|
|
3893
|
-
*/
|
|
3894
|
-
destroy() {
|
|
3895
|
-
for (let layerId in this._vboBatchingLayers) {
|
|
3896
|
-
if (this._vboBatchingLayers.hasOwnProperty(layerId)) {
|
|
3897
|
-
this._vboBatchingLayers[layerId].destroy();
|
|
3898
|
-
}
|
|
3899
|
-
}
|
|
3900
|
-
this._vboBatchingLayers = {};
|
|
3901
|
-
for (let layerId in this._vboInstancingLayers) {
|
|
3902
|
-
if (this._vboInstancingLayers.hasOwnProperty(layerId)) {
|
|
3903
|
-
this._vboInstancingLayers[layerId].destroy();
|
|
3904
|
-
}
|
|
3905
|
-
}
|
|
3906
|
-
this._vboInstancingLayers = {};
|
|
3907
|
-
this.scene.camera.off(this._onCameraViewMatrix);
|
|
3908
|
-
this.scene.off(this._onTick);
|
|
3909
|
-
for (let i = 0, len = this.layerList.length; i < len; i++) {
|
|
3910
|
-
this.layerList[i].destroy();
|
|
3911
|
-
}
|
|
3912
|
-
this.layerList = [];
|
|
3913
|
-
for (let i = 0, len = this._entityList.length; i < len; i++) {
|
|
3914
|
-
this._entityList[i]._destroy();
|
|
3915
|
-
}
|
|
3916
|
-
// Object.entries(this._geometries).forEach(([id, geometry]) => {
|
|
3917
|
-
// geometry.destroy();
|
|
3918
|
-
// });
|
|
3919
|
-
this._geometries = {};
|
|
3920
|
-
this._dtxBuckets = {};
|
|
3921
|
-
this._textures = {};
|
|
3922
|
-
this._textureSets = {};
|
|
3923
|
-
this._meshes = {};
|
|
3924
|
-
this._entities = {};
|
|
3925
|
-
this.scene._aabbDirty = true;
|
|
3926
|
-
if (this._isModel) {
|
|
3927
|
-
this.scene._deregisterModel(this);
|
|
3928
|
-
}
|
|
3929
|
-
putScratchMemory();
|
|
3930
|
-
super.destroy();
|
|
3931
|
-
}
|
|
3932
|
-
}
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
/**
|
|
3936
|
-
* This function applies two steps to the provided mesh geometry data:
|
|
3937
|
-
*
|
|
3938
|
-
* - 1st, it reduces its `.positions` to unique positions, thus removing duplicate vertices. It will adjust the `.indices` and `.edgeIndices` array accordingly to the unique `.positions`.
|
|
3939
|
-
*
|
|
3940
|
-
* - 2nd, it tries to do an optimization called `index rebucketting`
|
|
3941
|
-
*
|
|
3942
|
-
* _Rebucketting minimizes the amount of RAM usage for a given mesh geometry by trying do demote its needed index bitness._
|
|
3943
|
-
*
|
|
3944
|
-
* - _for 32 bit indices, will try to demote them to 16 bit indices_
|
|
3945
|
-
* - _for 16 bit indices, will try to demote them to 8 bits indices_
|
|
3946
|
-
* - _8 bits indices are kept as-is_
|
|
3947
|
-
*
|
|
3948
|
-
* The fact that 32/16/8 bits are needed for indices, depends on the number of maximumm indexable vertices within the mesh geometry: this is, the number of vertices in the mesh geometry.
|
|
3949
|
-
*
|
|
3950
|
-
* The function returns the same provided input `geometry`, enrichened with the additional key `.preparedBukets`.
|
|
3951
|
-
*
|
|
3952
|
-
* @param {object} geometry The mesh information containing `.positions`, `.indices`, `.edgeIndices` arrays.
|
|
3953
|
-
*
|
|
3954
|
-
* @param enableVertexWelding
|
|
3955
|
-
* @param enableIndexBucketing
|
|
3956
|
-
* @returns {object} The mesh information enrichened with `.buckets` key.
|
|
3957
|
-
*/
|
|
3958
|
-
function createDTXBuckets(geometry, enableVertexWelding, enableIndexBucketing) {
|
|
3959
|
-
let uniquePositionsCompressed, uniqueIndices, uniqueEdgeIndices;
|
|
3960
|
-
if (enableVertexWelding || enableIndexBucketing) { // Expensive - careful!
|
|
3961
|
-
[
|
|
3962
|
-
uniquePositionsCompressed,
|
|
3963
|
-
uniqueIndices,
|
|
3964
|
-
uniqueEdgeIndices,
|
|
3965
|
-
] = uniquifyPositions({
|
|
3966
|
-
positionsCompressed: geometry.positionsCompressed,
|
|
3967
|
-
indices: geometry.indices,
|
|
3968
|
-
edgeIndices: geometry.edgeIndices
|
|
3969
|
-
});
|
|
3970
|
-
} else {
|
|
3971
|
-
uniquePositionsCompressed = geometry.positionsCompressed;
|
|
3972
|
-
uniqueIndices = geometry.indices;
|
|
3973
|
-
uniqueEdgeIndices = geometry.edgeIndices;
|
|
3974
|
-
}
|
|
3975
|
-
let buckets;
|
|
3976
|
-
if (enableIndexBucketing) {
|
|
3977
|
-
let numUniquePositions = uniquePositionsCompressed.length / 3;
|
|
3978
|
-
buckets = rebucketPositions({
|
|
3979
|
-
positionsCompressed: uniquePositionsCompressed,
|
|
3980
|
-
indices: uniqueIndices,
|
|
3981
|
-
edgeIndices: uniqueEdgeIndices,
|
|
3982
|
-
},
|
|
3983
|
-
(numUniquePositions > (1 << 16)) ? 16 : 8,
|
|
3984
|
-
// true
|
|
3985
|
-
);
|
|
3986
|
-
} else {
|
|
3987
|
-
buckets = [{
|
|
3988
|
-
positionsCompressed: uniquePositionsCompressed,
|
|
3989
|
-
indices: uniqueIndices,
|
|
3990
|
-
edgeIndices: uniqueEdgeIndices,
|
|
3991
|
-
}];
|
|
3992
|
-
}
|
|
3993
|
-
return buckets;
|
|
3994
|
-
}
|
|
3995
|
-
|
|
3996
|
-
function
|
|
3997
|
-
|
|
3998
|
-
createGeometryOBB(geometry) {
|
|
3999
|
-
geometry.obb = math.OBB3();
|
|
4000
|
-
if (geometry.positionsCompressed && geometry.positionsCompressed.length > 0) {
|
|
4001
|
-
const localAABB = math.collapseAABB3();
|
|
4002
|
-
math.expandAABB3Points3(localAABB, geometry.positionsCompressed);
|
|
4003
|
-
geometryCompressionUtils.decompressAABB(localAABB, geometry.positionsDecodeMatrix);
|
|
4004
|
-
math.AABB3ToOBB3(localAABB, geometry.obb);
|
|
4005
|
-
} else if (geometry.positions && geometry.positions.length > 0) {
|
|
4006
|
-
const localAABB = math.collapseAABB3();
|
|
4007
|
-
math.expandAABB3Points3(localAABB, geometry.positions);
|
|
4008
|
-
math.AABB3ToOBB3(localAABB, geometry.obb);
|
|
4009
|
-
} else if (geometry.buckets) {
|
|
4010
|
-
const localAABB = math.collapseAABB3();
|
|
4011
|
-
for (let i = 0, len = geometry.buckets.length; i < len; i++) {
|
|
4012
|
-
const bucket = geometry.buckets[i];
|
|
4013
|
-
math.expandAABB3Points3(localAABB, bucket.positionsCompressed);
|
|
4014
|
-
}
|
|
4015
|
-
geometryCompressionUtils.decompressAABB(localAABB, geometry.positionsDecodeMatrix);
|
|
4016
|
-
math.AABB3ToOBB3(localAABB, geometry.obb);
|
|
4017
|
-
}
|
|
4018
|
-
}
|