UNPKG

@babylonjs/core

Version:

Getting started? Play directly with the Babylon.js API using our [playground](https://playground.babylonjs.com/). It also contains a lot of samples to learn how to use it.

1,257 lines (1,256 loc) 195 kB
import { Tools } from "./Misc/tools.js"; import { PrecisionDate } from "./Misc/precisionDate.js"; import { Observable } from "./Misc/observable.js"; import { SmartArrayNoDuplicate, SmartArray } from "./Misc/smartArray.js"; import { StringDictionary } from "./Misc/stringDictionary.js"; import { Tags } from "./Misc/tags.js"; import { Vector3, Matrix, TmpVectors } from "./Maths/math.vector.js"; import { ImageProcessingConfiguration } from "./Materials/imageProcessingConfiguration.js"; import { UniformBuffer } from "./Materials/uniformBuffer.js"; import { PickingInfo } from "./Collisions/pickingInfo.js"; import { ActionEvent } from "./Actions/actionEvent.js"; import { PostProcessManager } from "./PostProcesses/postProcessManager.js"; import { RenderingManager } from "./Rendering/renderingManager.js"; import { Stage } from "./sceneComponent.js"; import { IsWindowObjectExist } from "./Misc/domManagement.js"; import { EngineStore } from "./Engines/engineStore.js"; import { _WarnImport } from "./Misc/devTools.js"; import { InputManager } from "./Inputs/scene.inputManager.js"; import { PerfCounter } from "./Misc/perfCounter.js"; import { Color4, Color3 } from "./Maths/math.color.js"; import { Frustum } from "./Maths/math.frustum.js"; import { UniqueIdGenerator } from "./Misc/uniqueIdGenerator.js"; import { ReadFile, RequestFile, LoadFile } from "./Misc/fileTools.js"; import { LightConstants } from "./Lights/lightConstants.js"; import { _ObserveArray } from "./Misc/arrayTools.js"; import { PointerPickingConfiguration } from "./Inputs/pointerPickingConfiguration.js"; import { Logger } from "./Misc/logger.js"; import { RegisterClass } from "./Misc/typeStore.js"; /** * Define how the scene should favor performance over ease of use */ export var ScenePerformancePriority; (function (ScenePerformancePriority) { /** Default mode. No change. Performance will be treated as less important than backward compatibility */ ScenePerformancePriority[ScenePerformancePriority["BackwardCompatible"] = 0] = "BackwardCompatible"; /** Some performance options will be turned on trying to strike a balance between perf and ease of use */ ScenePerformancePriority[ScenePerformancePriority["Intermediate"] = 1] = "Intermediate"; /** Performance will be top priority */ ScenePerformancePriority[ScenePerformancePriority["Aggressive"] = 2] = "Aggressive"; })(ScenePerformancePriority || (ScenePerformancePriority = {})); /** * Represents a scene to be rendered by the engine. * @see https://doc.babylonjs.com/features/featuresDeepDive/scene */ export class Scene { // eslint-disable-next-line jsdoc/require-returns-check /** * Factory used to create the default material. * @param scene The scene to create the material for * @returns The default material */ static DefaultMaterialFactory(scene) { throw _WarnImport("StandardMaterial"); } // eslint-disable-next-line jsdoc/require-returns-check /** * Factory used to create the a collision coordinator. * @returns The collision coordinator */ static CollisionCoordinatorFactory() { throw _WarnImport("DefaultCollisionCoordinator"); } /** * Defines the color used to clear the render buffer (Default is (0.2, 0.2, 0.3, 1.0)) */ get clearColor() { return this._clearColor; } set clearColor(value) { if (value !== this._clearColor) { this._clearColor = value; this.onClearColorChangedObservable.notifyObservers(this._clearColor); } } /** * Default image processing configuration used either in the rendering * Forward main pass or through the imageProcessingPostProcess if present. * As in the majority of the scene they are the same (exception for multi camera), * this is easier to reference from here than from all the materials and post process. * * No setter as we it is a shared configuration, you can set the values instead. */ get imageProcessingConfiguration() { return this._imageProcessingConfiguration; } /** * Gets or sets a value indicating how to treat performance relatively to ease of use and backward compatibility */ get performancePriority() { return this._performancePriority; } set performancePriority(value) { if (value === this._performancePriority) { return; } this._performancePriority = value; switch (value) { case 0 /* ScenePerformancePriority.BackwardCompatible */: this.skipFrustumClipping = false; this._renderingManager.maintainStateBetweenFrames = false; this.skipPointerMovePicking = false; this.autoClear = true; break; case 1 /* ScenePerformancePriority.Intermediate */: this.skipFrustumClipping = false; this._renderingManager.maintainStateBetweenFrames = false; this.skipPointerMovePicking = true; this.autoClear = false; break; case 2 /* ScenePerformancePriority.Aggressive */: this.skipFrustumClipping = true; this._renderingManager.maintainStateBetweenFrames = true; this.skipPointerMovePicking = true; this.autoClear = false; break; } this.onScenePerformancePriorityChangedObservable.notifyObservers(value); } /** * Gets or sets a boolean indicating if all rendering must be done in wireframe */ set forceWireframe(value) { if (this._forceWireframe === value) { return; } this._forceWireframe = value; this.markAllMaterialsAsDirty(16); } get forceWireframe() { return this._forceWireframe; } /** * Gets or sets a boolean indicating if we should skip the frustum clipping part of the active meshes selection */ set skipFrustumClipping(value) { if (this._skipFrustumClipping === value) { return; } this._skipFrustumClipping = value; } get skipFrustumClipping() { return this._skipFrustumClipping; } /** * Gets or sets a boolean indicating if all rendering must be done in point cloud */ set forcePointsCloud(value) { if (this._forcePointsCloud === value) { return; } this._forcePointsCloud = value; this.markAllMaterialsAsDirty(16); } get forcePointsCloud() { return this._forcePointsCloud; } /** * Texture used in all pbr material as the reflection texture. * As in the majority of the scene they are the same (exception for multi room and so on), * this is easier to reference from here than from all the materials. */ get environmentTexture() { return this._environmentTexture; } /** * Texture used in all pbr material as the reflection texture. * As in the majority of the scene they are the same (exception for multi room and so on), * this is easier to set here than in all the materials. */ set environmentTexture(value) { if (this._environmentTexture === value) { return; } this._environmentTexture = value; this.onEnvironmentTextureChangedObservable.notifyObservers(value); this.markAllMaterialsAsDirty(1); } /** * @returns all meshes, lights, cameras, transformNodes and bones */ getNodes() { let nodes = []; nodes = nodes.concat(this.meshes); nodes = nodes.concat(this.lights); nodes = nodes.concat(this.cameras); nodes = nodes.concat(this.transformNodes); // dummies for (const skeleton of this.skeletons) { nodes = nodes.concat(skeleton.bones); } return nodes; } /** * Gets or sets the animation properties override */ get animationPropertiesOverride() { return this._animationPropertiesOverride; } set animationPropertiesOverride(value) { this._animationPropertiesOverride = value; } /** Sets a function to be executed when this scene is disposed. */ set onDispose(callback) { if (this._onDisposeObserver) { this.onDisposeObservable.remove(this._onDisposeObserver); } this._onDisposeObserver = this.onDisposeObservable.add(callback); } /** Sets a function to be executed before rendering this scene */ set beforeRender(callback) { if (this._onBeforeRenderObserver) { this.onBeforeRenderObservable.remove(this._onBeforeRenderObserver); } if (callback) { this._onBeforeRenderObserver = this.onBeforeRenderObservable.add(callback); } } /** Sets a function to be executed after rendering this scene */ set afterRender(callback) { if (this._onAfterRenderObserver) { this.onAfterRenderObservable.remove(this._onAfterRenderObserver); } if (callback) { this._onAfterRenderObserver = this.onAfterRenderObservable.add(callback); } } /** Sets a function to be executed before rendering a camera*/ set beforeCameraRender(callback) { if (this._onBeforeCameraRenderObserver) { this.onBeforeCameraRenderObservable.remove(this._onBeforeCameraRenderObserver); } this._onBeforeCameraRenderObserver = this.onBeforeCameraRenderObservable.add(callback); } /** Sets a function to be executed after rendering a camera*/ set afterCameraRender(callback) { if (this._onAfterCameraRenderObserver) { this.onAfterCameraRenderObservable.remove(this._onAfterCameraRenderObserver); } this._onAfterCameraRenderObserver = this.onAfterCameraRenderObservable.add(callback); } /** * Gets or sets a predicate used to select candidate meshes for a pointer down event */ get pointerDownPredicate() { return this._pointerPickingConfiguration.pointerDownPredicate; } set pointerDownPredicate(value) { this._pointerPickingConfiguration.pointerDownPredicate = value; } /** * Gets or sets a predicate used to select candidate meshes for a pointer up event */ get pointerUpPredicate() { return this._pointerPickingConfiguration.pointerUpPredicate; } set pointerUpPredicate(value) { this._pointerPickingConfiguration.pointerUpPredicate = value; } /** * Gets or sets a predicate used to select candidate meshes for a pointer move event */ get pointerMovePredicate() { return this._pointerPickingConfiguration.pointerMovePredicate; } set pointerMovePredicate(value) { this._pointerPickingConfiguration.pointerMovePredicate = value; } /** * Gets or sets a predicate used to select candidate meshes for a pointer down event */ get pointerDownFastCheck() { return this._pointerPickingConfiguration.pointerDownFastCheck; } set pointerDownFastCheck(value) { this._pointerPickingConfiguration.pointerDownFastCheck = value; } /** * Gets or sets a predicate used to select candidate meshes for a pointer up event */ get pointerUpFastCheck() { return this._pointerPickingConfiguration.pointerUpFastCheck; } set pointerUpFastCheck(value) { this._pointerPickingConfiguration.pointerUpFastCheck = value; } /** * Gets or sets a predicate used to select candidate meshes for a pointer move event */ get pointerMoveFastCheck() { return this._pointerPickingConfiguration.pointerMoveFastCheck; } set pointerMoveFastCheck(value) { this._pointerPickingConfiguration.pointerMoveFastCheck = value; } /** * Gets or sets a boolean indicating if the user want to entirely skip the picking phase when a pointer move event occurs. */ get skipPointerMovePicking() { return this._pointerPickingConfiguration.skipPointerMovePicking; } set skipPointerMovePicking(value) { this._pointerPickingConfiguration.skipPointerMovePicking = value; } /** * Gets or sets a boolean indicating if the user want to entirely skip the picking phase when a pointer down event occurs. */ get skipPointerDownPicking() { return this._pointerPickingConfiguration.skipPointerDownPicking; } set skipPointerDownPicking(value) { this._pointerPickingConfiguration.skipPointerDownPicking = value; } /** * Gets or sets a boolean indicating if the user want to entirely skip the picking phase when a pointer up event occurs. Off by default. */ get skipPointerUpPicking() { return this._pointerPickingConfiguration.skipPointerUpPicking; } set skipPointerUpPicking(value) { this._pointerPickingConfiguration.skipPointerUpPicking = value; } /** * Gets the pointer coordinates without any translation (ie. straight out of the pointer event) */ get unTranslatedPointer() { return this._inputManager.unTranslatedPointer; } /** * Gets or sets the distance in pixel that you have to move to prevent some events. Default is 10 pixels */ static get DragMovementThreshold() { return InputManager.DragMovementThreshold; } static set DragMovementThreshold(value) { InputManager.DragMovementThreshold = value; } /** * Time in milliseconds to wait to raise long press events if button is still pressed. Default is 500 ms */ static get LongPressDelay() { return InputManager.LongPressDelay; } static set LongPressDelay(value) { InputManager.LongPressDelay = value; } /** * Time in milliseconds to wait to raise long press events if button is still pressed. Default is 300 ms */ static get DoubleClickDelay() { return InputManager.DoubleClickDelay; } static set DoubleClickDelay(value) { InputManager.DoubleClickDelay = value; } /** If you need to check double click without raising a single click at first click, enable this flag */ static get ExclusiveDoubleClickMode() { return InputManager.ExclusiveDoubleClickMode; } static set ExclusiveDoubleClickMode(value) { InputManager.ExclusiveDoubleClickMode = value; } /** * Bind the current view position to an effect. * @param effect The effect to be bound * @param variableName name of the shader variable that will hold the eye position * @param isVector3 true to indicates that variableName is a Vector3 and not a Vector4 * @returns the computed eye position */ bindEyePosition(effect, variableName = "vEyePosition", isVector3 = false) { const eyePosition = this._forcedViewPosition ? this._forcedViewPosition : this._mirroredCameraPosition ? this._mirroredCameraPosition : (this.activeCamera?.globalPosition ?? Vector3.ZeroReadOnly); const invertNormal = this.useRightHandedSystem === (this._mirroredCameraPosition != null); TmpVectors.Vector4[0].set(eyePosition.x, eyePosition.y, eyePosition.z, invertNormal ? -1 : 1); if (effect) { if (isVector3) { effect.setFloat3(variableName, TmpVectors.Vector4[0].x, TmpVectors.Vector4[0].y, TmpVectors.Vector4[0].z); } else { effect.setVector4(variableName, TmpVectors.Vector4[0]); } } return TmpVectors.Vector4[0]; } /** * Update the scene ubo before it can be used in rendering processing * @returns the scene UniformBuffer */ finalizeSceneUbo() { const ubo = this.getSceneUniformBuffer(); const eyePosition = this.bindEyePosition(null); ubo.updateFloat4("vEyePosition", eyePosition.x, eyePosition.y, eyePosition.z, eyePosition.w); ubo.update(); return ubo; } /** * Gets or sets a boolean indicating if the scene must use right-handed coordinates system */ set useRightHandedSystem(value) { if (this._useRightHandedSystem === value) { return; } this._useRightHandedSystem = value; this.markAllMaterialsAsDirty(16); } get useRightHandedSystem() { return this._useRightHandedSystem; } /** * Sets the step Id used by deterministic lock step * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#deterministic-lockstep * @param newStepId defines the step Id */ setStepId(newStepId) { this._currentStepId = newStepId; } /** * Gets the step Id used by deterministic lock step * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#deterministic-lockstep * @returns the step Id */ getStepId() { return this._currentStepId; } /** * Gets the internal step used by deterministic lock step * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/advanced_animations#deterministic-lockstep * @returns the internal step */ getInternalStep() { return this._currentInternalStep; } /** * Gets or sets a boolean indicating if fog is enabled on this scene * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/environment_introduction#fog * (Default is true) */ set fogEnabled(value) { if (this._fogEnabled === value) { return; } this._fogEnabled = value; this.markAllMaterialsAsDirty(16); } get fogEnabled() { return this._fogEnabled; } /** * Gets or sets the fog mode to use * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/environment_introduction#fog * | mode | value | * | --- | --- | * | FOGMODE_NONE | 0 | * | FOGMODE_EXP | 1 | * | FOGMODE_EXP2 | 2 | * | FOGMODE_LINEAR | 3 | */ set fogMode(value) { if (this._fogMode === value) { return; } this._fogMode = value; this.markAllMaterialsAsDirty(16); } get fogMode() { return this._fogMode; } /** * Flag indicating that the frame buffer binding is handled by another component */ get prePass() { return !!this.prePassRenderer && this.prePassRenderer.defaultRT.enabled; } /** * Gets or sets a boolean indicating if shadows are enabled on this scene */ set shadowsEnabled(value) { if (this._shadowsEnabled === value) { return; } this._shadowsEnabled = value; this.markAllMaterialsAsDirty(2); } get shadowsEnabled() { return this._shadowsEnabled; } /** * Gets or sets a boolean indicating if lights are enabled on this scene */ set lightsEnabled(value) { if (this._lightsEnabled === value) { return; } this._lightsEnabled = value; this.markAllMaterialsAsDirty(2); } get lightsEnabled() { return this._lightsEnabled; } /** All of the active cameras added to this scene. */ get activeCameras() { return this._activeCameras; } set activeCameras(cameras) { if (this._unObserveActiveCameras) { this._unObserveActiveCameras(); this._unObserveActiveCameras = null; } if (cameras) { this._unObserveActiveCameras = _ObserveArray(cameras, () => { this.onActiveCamerasChanged.notifyObservers(this); }); } this._activeCameras = cameras; } /** Gets or sets the current active camera */ get activeCamera() { return this._activeCamera; } set activeCamera(value) { if (value === this._activeCamera) { return; } this._activeCamera = value; this.onActiveCameraChanged.notifyObservers(this); } /** @internal */ get _hasDefaultMaterial() { return Scene.DefaultMaterialFactory !== Scene._OriginalDefaultMaterialFactory; } /** The default material used on meshes when no material is affected */ get defaultMaterial() { if (!this._defaultMaterial) { this._defaultMaterial = Scene.DefaultMaterialFactory(this); } return this._defaultMaterial; } /** The default material used on meshes when no material is affected */ set defaultMaterial(value) { this._defaultMaterial = value; } /** * Gets or sets a boolean indicating if textures are enabled on this scene */ set texturesEnabled(value) { if (this._texturesEnabled === value) { return; } this._texturesEnabled = value; this.markAllMaterialsAsDirty(1); } get texturesEnabled() { return this._texturesEnabled; } /** * Gets or sets the frame graph used to render the scene. If set, the scene will use the frame graph to render the scene instead of the default render loop. */ get frameGraph() { return this._frameGraph; } set frameGraph(value) { if (this._frameGraph) { this._frameGraph = value; if (!value) { this.customRenderFunction = this._currentCustomRenderFunction; } return; } this._frameGraph = value; if (value) { this._currentCustomRenderFunction = this.customRenderFunction; this.customRenderFunction = this._renderWithFrameGraph; } } /** * Gets or sets a boolean indicating if skeletons are enabled on this scene */ set skeletonsEnabled(value) { if (this._skeletonsEnabled === value) { return; } this._skeletonsEnabled = value; this.markAllMaterialsAsDirty(8); } get skeletonsEnabled() { return this._skeletonsEnabled; } /** @internal */ get collisionCoordinator() { if (!this._collisionCoordinator) { this._collisionCoordinator = Scene.CollisionCoordinatorFactory(); this._collisionCoordinator.init(this); } return this._collisionCoordinator; } /** * Gets the scene's rendering manager */ get renderingManager() { return this._renderingManager; } /** * Gets the list of frustum planes (built from the active camera) */ get frustumPlanes() { return this._frustumPlanes; } /** * Registers the transient components if needed. */ _registerTransientComponents() { // Register components that have been associated lately to the scene. if (this._transientComponents.length > 0) { for (const component of this._transientComponents) { component.register(); } this._transientComponents.length = 0; } } /** * @internal * Add a component to the scene. * Note that the ccomponent could be registered on th next frame if this is called after * the register component stage. * @param component Defines the component to add to the scene */ _addComponent(component) { this._components.push(component); this._transientComponents.push(component); const serializableComponent = component; if (serializableComponent.addFromContainer && serializableComponent.serialize) { this._serializableComponents.push(serializableComponent); } } /** * @internal * Gets a component from the scene. * @param name defines the name of the component to retrieve * @returns the component or null if not present */ _getComponent(name) { for (const component of this._components) { if (component.name === name) { return component; } } return null; } /** * Creates a new Scene * @param engine defines the engine to use to render this scene * @param options defines the scene options */ constructor(engine, options) { /** @internal */ this._inputManager = new InputManager(this); /** Define this parameter if you are using multiple cameras and you want to specify which one should be used for pointer position */ this.cameraToUseForPointers = null; /** @internal */ this._isScene = true; /** @internal */ this._blockEntityCollection = false; /** * Gets or sets a boolean that indicates if the scene must clear the render buffer before rendering a frame */ this.autoClear = true; /** * Gets or sets a boolean that indicates if the scene must clear the depth and stencil buffers before rendering a frame */ this.autoClearDepthAndStencil = true; this._clearColor = new Color4(0.2, 0.2, 0.3, 1.0); /** * Observable triggered when the performance priority is changed */ this.onClearColorChangedObservable = new Observable(); /** * Defines the color used to simulate the ambient color (Default is (0, 0, 0)) */ this.ambientColor = new Color3(0, 0, 0); /** * Intensity of the environment (i.e. all indirect lighting) in all pbr material. * This dims or reinforces the indirect lighting overall (reflection and diffuse). * As in the majority of the scene they are the same (exception for multi room and so on), * this is easier to reference from here than from all the materials. * Note that this is more of a debugging parameter and is not physically accurate. * If you want to modify the intensity of the IBL texture, you should update iblIntensity instead. */ this.environmentIntensity = 1; /** * Overall intensity of the IBL texture. * This value is multiplied with the reflectionTexture.level value to calculate the final IBL intensity. */ this.iblIntensity = 1; this._performancePriority = 0 /* ScenePerformancePriority.BackwardCompatible */; /** * Observable triggered when the performance priority is changed */ this.onScenePerformancePriorityChangedObservable = new Observable(); this._forceWireframe = false; this._skipFrustumClipping = false; this._forcePointsCloud = false; /** * Gets the list of root nodes (ie. nodes with no parent) */ this.rootNodes = []; /** All of the cameras added to this scene * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras */ this.cameras = []; /** * All of the lights added to this scene * @see https://doc.babylonjs.com/features/featuresDeepDive/lights/lights_introduction */ this.lights = []; /** * All of the (abstract) meshes added to this scene */ this.meshes = []; /** * The list of skeletons added to the scene * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/bonesSkeletons */ this.skeletons = []; /** * All of the particle systems added to this scene * @see https://doc.babylonjs.com/features/featuresDeepDive/particles/particle_system/particle_system_intro */ this.particleSystems = []; /** * Gets a list of Animations associated with the scene */ this.animations = []; /** * All of the animation groups added to this scene * @see https://doc.babylonjs.com/features/featuresDeepDive/animation/groupAnimations */ this.animationGroups = []; /** * All of the multi-materials added to this scene * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/multiMaterials */ this.multiMaterials = []; /** * All of the materials added to this scene * In the context of a Scene, it is not supposed to be modified manually. * Any addition or removal should be done using the addMaterial and removeMaterial Scene methods. * Note also that the order of the Material within the array is not significant and might change. * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/materials_introduction */ this.materials = []; /** * The list of morph target managers added to the scene * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/dynamicMeshMorph */ this.morphTargetManagers = []; /** * The list of geometries used in the scene. */ this.geometries = []; /** * All of the transform nodes added to this scene * In the context of a Scene, it is not supposed to be modified manually. * Any addition or removal should be done using the addTransformNode and removeTransformNode Scene methods. * Note also that the order of the TransformNode within the array is not significant and might change. * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/transforms/parent_pivot/transform_node */ this.transformNodes = []; /** * ActionManagers available on the scene. * @deprecated */ this.actionManagers = []; /** * Textures to keep. */ this.textures = []; /** @internal */ this._environmentTexture = null; /** * The list of postprocesses added to the scene */ this.postProcesses = []; /** * The list of effect layers (highlights/glow) added to the scene * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/highlightLayer * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/glowLayer */ this.effectLayers = []; /** * The list of sounds used in the scene. */ this.sounds = null; /** * The list of layers (background and foreground) of the scene */ this.layers = []; /** * The list of lens flare system added to the scene * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/lenseFlare */ this.lensFlareSystems = []; /** * The list of procedural textures added to the scene * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/proceduralTextures */ this.proceduralTextures = []; /** * Gets or sets a boolean indicating if animations are enabled */ this.animationsEnabled = true; this._animationPropertiesOverride = null; /** * Gets or sets a boolean indicating if a constant deltatime has to be used * This is mostly useful for testing purposes when you do not want the animations to scale with the framerate */ this.useConstantAnimationDeltaTime = false; /** * Gets or sets a boolean indicating if the scene must keep the meshUnderPointer property updated * Please note that it requires to run a ray cast through the scene on every frame */ this.constantlyUpdateMeshUnderPointer = false; /** * Defines the HTML cursor to use when hovering over interactive elements */ this.hoverCursor = "pointer"; /** * Defines the HTML default cursor to use (empty by default) */ this.defaultCursor = ""; /** * Defines whether cursors are handled by the scene. */ this.doNotHandleCursors = false; /** * This is used to call preventDefault() on pointer down * in order to block unwanted artifacts like system double clicks */ this.preventDefaultOnPointerDown = true; /** * This is used to call preventDefault() on pointer up * in order to block unwanted artifacts like system double clicks */ this.preventDefaultOnPointerUp = true; // Metadata /** * Gets or sets user defined metadata */ this.metadata = null; /** * For internal use only. Please do not use. */ this.reservedDataStore = null; /** * Use this array to add regular expressions used to disable offline support for specific urls */ this.disableOfflineSupportExceptionRules = []; /** * An event triggered when the scene is disposed. */ this.onDisposeObservable = new Observable(); this._onDisposeObserver = null; /** * An event triggered before rendering the scene (right after animations and physics) */ this.onBeforeRenderObservable = new Observable(); this._onBeforeRenderObserver = null; /** * An event triggered after rendering the scene */ this.onAfterRenderObservable = new Observable(); /** * An event triggered after rendering the scene for an active camera (When scene.render is called this will be called after each camera) * This is triggered for each "sub" camera in a Camera Rig unlike onAfterCameraRenderObservable */ this.onAfterRenderCameraObservable = new Observable(); this._onAfterRenderObserver = null; /** * An event triggered before animating the scene */ this.onBeforeAnimationsObservable = new Observable(); /** * An event triggered after animations processing */ this.onAfterAnimationsObservable = new Observable(); /** * An event triggered before draw calls are ready to be sent */ this.onBeforeDrawPhaseObservable = new Observable(); /** * An event triggered after draw calls have been sent */ this.onAfterDrawPhaseObservable = new Observable(); /** * An event triggered when the scene is ready */ this.onReadyObservable = new Observable(); /** * An event triggered before rendering a camera */ this.onBeforeCameraRenderObservable = new Observable(); this._onBeforeCameraRenderObserver = null; /** * An event triggered after rendering a camera * This is triggered for the full rig Camera only unlike onAfterRenderCameraObservable */ this.onAfterCameraRenderObservable = new Observable(); this._onAfterCameraRenderObserver = null; /** * An event triggered when active meshes evaluation is about to start */ this.onBeforeActiveMeshesEvaluationObservable = new Observable(); /** * An event triggered when active meshes evaluation is done */ this.onAfterActiveMeshesEvaluationObservable = new Observable(); /** * An event triggered when particles rendering is about to start * Note: This event can be trigger more than once per frame (because particles can be rendered by render target textures as well) */ this.onBeforeParticlesRenderingObservable = new Observable(); /** * An event triggered when particles rendering is done * Note: This event can be trigger more than once per frame (because particles can be rendered by render target textures as well) */ this.onAfterParticlesRenderingObservable = new Observable(); /** * An event triggered when SceneLoader.Append or SceneLoader.Load or SceneLoader.ImportMesh were successfully executed */ this.onDataLoadedObservable = new Observable(); /** * An event triggered when a camera is created */ this.onNewCameraAddedObservable = new Observable(); /** * An event triggered when a camera is removed */ this.onCameraRemovedObservable = new Observable(); /** * An event triggered when a light is created */ this.onNewLightAddedObservable = new Observable(); /** * An event triggered when a light is removed */ this.onLightRemovedObservable = new Observable(); /** * An event triggered when a geometry is created */ this.onNewGeometryAddedObservable = new Observable(); /** * An event triggered when a geometry is removed */ this.onGeometryRemovedObservable = new Observable(); /** * An event triggered when a transform node is created */ this.onNewTransformNodeAddedObservable = new Observable(); /** * An event triggered when a transform node is removed */ this.onTransformNodeRemovedObservable = new Observable(); /** * An event triggered when a mesh is created */ this.onNewMeshAddedObservable = new Observable(); /** * An event triggered when a mesh is removed */ this.onMeshRemovedObservable = new Observable(); /** * An event triggered when a skeleton is created */ this.onNewSkeletonAddedObservable = new Observable(); /** * An event triggered when a skeleton is removed */ this.onSkeletonRemovedObservable = new Observable(); /** * An event triggered when a material is created */ this.onNewMaterialAddedObservable = new Observable(); /** * An event triggered when a multi material is created */ this.onNewMultiMaterialAddedObservable = new Observable(); /** * An event triggered when a material is removed */ this.onMaterialRemovedObservable = new Observable(); /** * An event triggered when a multi material is removed */ this.onMultiMaterialRemovedObservable = new Observable(); /** * An event triggered when a texture is created */ this.onNewTextureAddedObservable = new Observable(); /** * An event triggered when a texture is removed */ this.onTextureRemovedObservable = new Observable(); /** * An event triggered when render targets are about to be rendered * Can happen multiple times per frame. */ this.onBeforeRenderTargetsRenderObservable = new Observable(); /** * An event triggered when render targets were rendered. * Can happen multiple times per frame. */ this.onAfterRenderTargetsRenderObservable = new Observable(); /** * An event triggered before calculating deterministic simulation step */ this.onBeforeStepObservable = new Observable(); /** * An event triggered after calculating deterministic simulation step */ this.onAfterStepObservable = new Observable(); /** * An event triggered when the activeCamera property is updated */ this.onActiveCameraChanged = new Observable(); /** * An event triggered when the activeCameras property is updated */ this.onActiveCamerasChanged = new Observable(); /** * This Observable will be triggered before rendering each renderingGroup of each rendered camera. * The RenderingGroupInfo class contains all the information about the context in which the observable is called * If you wish to register an Observer only for a given set of renderingGroup, use the mask with a combination of the renderingGroup index elevated to the power of two (1 for renderingGroup 0, 2 for renderingrOup1, 4 for 2 and 8 for 3) */ this.onBeforeRenderingGroupObservable = new Observable(); /** * This Observable will be triggered after rendering each renderingGroup of each rendered camera. * The RenderingGroupInfo class contains all the information about the context in which the observable is called * If you wish to register an Observer only for a given set of renderingGroup, use the mask with a combination of the renderingGroup index elevated to the power of two (1 for renderingGroup 0, 2 for renderingrOup1, 4 for 2 and 8 for 3) */ this.onAfterRenderingGroupObservable = new Observable(); /** * This Observable will when a mesh has been imported into the scene. */ this.onMeshImportedObservable = new Observable(); /** * This Observable will when an animation file has been imported into the scene. */ this.onAnimationFileImportedObservable = new Observable(); /** * An event triggered when the environmentTexture is changed. */ this.onEnvironmentTextureChangedObservable = new Observable(); /** * An event triggered when the state of mesh under pointer, for a specific pointerId, changes. */ this.onMeshUnderPointerUpdatedObservable = new Observable(); // Animations /** @internal */ this._registeredForLateAnimationBindings = new SmartArrayNoDuplicate(256); // Pointers this._pointerPickingConfiguration = new PointerPickingConfiguration(); /** * This observable event is triggered when any ponter event is triggered. It is registered during Scene.attachControl() and it is called BEFORE the 3D engine process anything (mesh/sprite picking for instance). * You have the possibility to skip the process and the call to onPointerObservable by setting PointerInfoPre.skipOnPointerObservable to true */ this.onPrePointerObservable = new Observable(); /** * Observable event triggered each time an input event is received from the rendering canvas */ this.onPointerObservable = new Observable(); // Keyboard /** * This observable event is triggered when any keyboard event si raised and registered during Scene.attachControl() * You have the possibility to skip the process and the call to onKeyboardObservable by setting KeyboardInfoPre.skipOnPointerObservable to true */ this.onPreKeyboardObservable = new Observable(); /** * Observable event triggered each time an keyboard event is received from the hosting window */ this.onKeyboardObservable = new Observable(); // Coordinates system this._useRightHandedSystem = false; // Deterministic lockstep this._timeAccumulator = 0; this._currentStepId = 0; this._currentInternalStep = 0; // Fog this._fogEnabled = true; this._fogMode = Scene.FOGMODE_NONE; /** * Gets or sets the fog color to use * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/environment_introduction#fog * (Default is Color3(0.2, 0.2, 0.3)) */ this.fogColor = new Color3(0.2, 0.2, 0.3); /** * Gets or sets the fog density to use * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/environment_introduction#fog * (Default is 0.1) */ this.fogDensity = 0.1; /** * Gets or sets the fog start distance to use * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/environment_introduction#fog * (Default is 0) */ this.fogStart = 0; /** * Gets or sets the fog end distance to use * @see https://doc.babylonjs.com/features/featuresDeepDive/environment/environment_introduction#fog * (Default is 1000) */ this.fogEnd = 1000.0; /** * Flag indicating if we need to store previous matrices when rendering */ this.needsPreviousWorldMatrices = false; // Lights this._shadowsEnabled = true; this._lightsEnabled = true; this._unObserveActiveCameras = null; // Textures this._texturesEnabled = true; this._frameGraph = null; /** * List of frame graphs associated with the scene */ this.frameGraphs = []; // Physics /** * Gets or sets a boolean indicating if physic engines are enabled on this scene */ this.physicsEnabled = true; // Particles /** * Gets or sets a boolean indicating if particles are enabled on this scene */ this.particlesEnabled = true; // Sprites /** * Gets or sets a boolean indicating if sprites are enabled on this scene */ this.spritesEnabled = true; // Skeletons this._skeletonsEnabled = true; // Lens flares /** * Gets or sets a boolean indicating if lens flares are enabled on this scene */ this.lensFlaresEnabled = true; // Collisions /** * Gets or sets a boolean indicating if collisions are enabled on this scene * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_collisions */ this.collisionsEnabled = true; /** * Defines the gravity applied to this scene (used only for collisions) * @see https://doc.babylonjs.com/features/featuresDeepDive/cameras/camera_collisions */ this.gravity = new Vector3(0, -9.807, 0); // Postprocesses /** * Gets or sets a boolean indicating if postprocesses are enabled on this scene */ this.postProcessesEnabled = true; // Customs render targets /** * Gets or sets a boolean indicating if render targets are enabled on this scene */ this.renderTargetsEnabled = true; /** * Gets or sets a boolean indicating if next render targets must be dumped as image for debugging purposes * We recommend not using it and instead rely on Spector.js: http://spector.babylonjs.com */ this.dumpNextRenderTargets = false; /** * The list of user defined render targets added to the scene */ this.customRenderTargets = []; /** * Gets the list of meshes imported to the scene through SceneLoader */ this.importedMeshesFiles = []; // Probes /** * Gets or sets a boolean indicating if probes are enabled on this scene */ this.probesEnabled = true; this._meshesForIntersections = new SmartArrayNoDuplicate(256); // Procedural textures /** * Gets or sets a boolean indicating if procedural textures are enabled on this scene */ this.proceduralTexturesEnabled = true; // Performance counters this._totalVertices = new PerfCounter(); /** @internal */ this._activeIndices = new PerfCounter(); /** @internal */ this._activeParticles = new PerfCounter(); /** @internal */ this._activeBones = new PerfCounter(); /** @internal */ this._animationTime = 0; /** * Gets or sets a general scale for animation speed * @see https://www.babylonjs-playground.com/#IBU2W7#3 */ this.animationTimeScale = 1; this._renderId = 0; this._frameId = 0; this._executeWhenReadyTimeoutId = null; this._intermediateRendering = false; this._defaultFrameBufferCleared = false; this._viewUpdateFlag = -1; this._projectionUpdateFlag = -1; /** @internal */ this._toBeDisposed = new Array(256); this._activeRequests = new Array(); /** @internal */ this._pendingData = new Array(); this._isDisposed = false; /** * Gets or sets a boolean indicating that all submeshes of active meshes must be rendered * Use this boolean to avoid computing frustum clipping on submeshes (This could help when you are CPU bound) */ this.dispatchAllSubMeshesOfActiveMeshes = false; this._activeMeshes = new SmartArray(256); this._processedMaterials = new SmartArray(256); this._renderTargets = new SmartArrayNoDuplicate(256); this._materialsRenderTargets = new SmartArrayNoDuplicate(256); /** @internal */ this._activeParticleSystems = new SmartArray(256); this._activeSkeletons = new SmartArrayNoDuplicate(32); this._softwareSkinnedMeshes = new SmartArrayNoDuplicate(32); /** @internal */ this._activeAnimatables = new Array(); this._transformMatrix = Matrix.Zero(); /** * Gets or sets a boolean indicating if lights must be sorted by priority (off by default) * This is useful if there are more lights that the maximum simulteanous authorized */ this.requireLightSorting = false; /** * @internal * Backing store of defined scene components. */ this._components = []; /** * @internal * Backing store of defined scene components. */ this._serializableComponents = []; /** * List of components to reg