Explorar o código

Merge branch 'master' of https://github.com/BabylonJS/Babylon.js into shadowdepthmat

Popov72 %!s(int64=5) %!d(string=hai) anos
pai
achega
8a8d348d65
Modificáronse 46 ficheiros con 1666 adicións e 879 borrados
  1. 196 94
      dist/preview release/babylon.d.ts
  2. 2 2
      dist/preview release/babylon.js
  3. 412 191
      dist/preview release/babylon.module.d.ts
  4. 202 96
      dist/preview release/documentation.d.ts
  5. 1 1
      dist/preview release/glTF2Interface/package.json
  6. 2 2
      dist/preview release/gui/package.json
  7. 7 7
      dist/preview release/inspector/package.json
  8. 3 3
      dist/preview release/loaders/package.json
  9. 2 2
      dist/preview release/materialsLibrary/babylon.customMaterial.min.js
  10. 6 2
      dist/preview release/materialsLibrary/babylonjs.materials.d.ts
  11. 1 1
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  12. 14 6
      dist/preview release/materialsLibrary/babylonjs.materials.module.d.ts
  13. 2 2
      dist/preview release/materialsLibrary/package.json
  14. 19 14
      dist/preview release/nodeEditor/babylon.nodeEditor.d.ts
  15. 4 4
      dist/preview release/nodeEditor/babylon.nodeEditor.js
  16. 42 29
      dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts
  17. 2 2
      dist/preview release/nodeEditor/package.json
  18. 1 1
      dist/preview release/package.json
  19. 1 1
      dist/preview release/packagesSizeBaseLine.json
  20. 2 2
      dist/preview release/postProcessesLibrary/package.json
  21. 2 2
      dist/preview release/proceduralTexturesLibrary/package.json
  22. 3 3
      dist/preview release/serializers/package.json
  23. 412 191
      dist/preview release/viewer/babylon.module.d.ts
  24. 10 5
      dist/preview release/what's new.md
  25. 4 4
      materialsLibrary/src/custom/customMaterial.ts
  26. 3 3
      materialsLibrary/src/custom/pbrCustomMaterial.ts
  27. 9 8
      nodeEditor/src/components/propertyTab/propertyTabComponent.tsx
  28. 13 15
      nodeEditor/src/diagram/frameNodePort.ts
  29. 28 4
      nodeEditor/src/diagram/graphCanvas.tsx
  30. 83 69
      nodeEditor/src/diagram/graphFrame.ts
  31. 2 2
      nodeEditor/src/diagram/graphNode.ts
  32. 2 2
      nodeEditor/src/diagram/nodeLink.ts
  33. 2 1
      nodeEditor/src/diagram/nodePort.ts
  34. 45 26
      nodeEditor/src/diagram/properties/frameNodePortPropertyComponent.tsx
  35. 2 1
      nodeEditor/src/globalState.ts
  36. 2 2
      package.json
  37. 2 0
      src/Culling/ray.ts
  38. 46 16
      src/Engines/Extensions/engine.rawTexture.ts
  39. 0 30
      src/Engines/engine.ts
  40. 2 2
      src/Engines/thinEngine.ts
  41. 58 24
      src/Materials/Textures/colorGradingTexture.ts
  42. 2 0
      src/Meshes/transformNode.ts
  43. 1 1
      src/Physics/Plugins/cannonJSPlugin.ts
  44. 3 1
      src/Physics/Plugins/oimoJSPlugin.ts
  45. 6 2
      src/PostProcesses/imageProcessingPostProcess.ts
  46. 3 3
      src/XR/webXRExperienceHelper.ts

+ 196 - 94
dist/preview release/babylon.d.ts

@@ -9344,6 +9344,13 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /** @hidden */
+    export var shadowMapFragmentDeclaration: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /** @hidden */
     export var clipPlaneFragmentDeclaration: {
         name: string;
         shader: string;
@@ -9358,6 +9365,13 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /** @hidden */
+    export var shadowMapFragment: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /** @hidden */
     export var shadowMapPixelShader: {
         name: string;
         shader: string;
@@ -9400,6 +9414,13 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /** @hidden */
+    export var shadowMapVertexDeclaration: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /** @hidden */
     export var clipPlaneVertexDeclaration: {
         name: string;
         shader: string;
@@ -9428,6 +9449,20 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /** @hidden */
+    export var shadowMapVertexNormalBias: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /** @hidden */
+    export var shadowMapVertexMetric: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /** @hidden */
     export var clipPlaneVertex: {
         name: string;
         shader: string;
@@ -9475,6 +9510,7 @@ declare module BABYLON {
         length?: number);
         /**
          * Checks if the ray intersects a box
+         * This does not account for the ray lenght by design to improve perfs.
          * @param minimum bound of the box
          * @param maximum bound of the box
          * @param intersectionTreshold extra extend to be added to the box in all direction
@@ -9483,6 +9519,7 @@ declare module BABYLON {
         intersectsBoxMinMax(minimum: DeepImmutable<Vector3>, maximum: DeepImmutable<Vector3>, intersectionTreshold?: number): boolean;
         /**
          * Checks if the ray intersects a box
+         * This does not account for the ray lenght by design to improve perfs.
          * @param box the bounding box to check
          * @param intersectionTreshold extra extend to be added to the BoundingBox in all direction
          * @returns if the box was hit
@@ -10469,7 +10506,7 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
-        interface Engine {
+        interface ThinEngine {
             /**
              * Creates a raw texture
              * @param data defines the data to store in the texture
@@ -15476,6 +15513,7 @@ declare module BABYLON {
         private _cachedWorldViewProjectionMatrix;
         private _renderId;
         private _multiview;
+        private _cachedDefines;
         /**
          * Instantiate a new shader material.
          * The ShaderMaterial object has the necessary methods to pass data from your scene to the Vertex and Fragment Shaders and returns a material that can be applied to any mesh.
@@ -15675,14 +15713,23 @@ declare module BABYLON {
         /**
          * Binds the world matrix to the material
          * @param world defines the world transformation matrix
+         * @param effectOverride - If provided, use this effect instead of internal effect
          */
-        bindOnlyWorldMatrix(world: Matrix): void;
+        bindOnlyWorldMatrix(world: Matrix, effectOverride?: Nullable<Effect>): void;
+        /**
+         * Binds the submesh to this material by preparing the effect and shader to draw
+         * @param world defines the world transformation matrix
+         * @param mesh defines the mesh containing the submesh
+         * @param subMesh defines the submesh to bind the material to
+         */
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         /**
          * Binds the material to the mesh
          * @param world defines the world transformation matrix
          * @param mesh defines the mesh to bind the material to
+         * @param effectOverride - If provided, use this effect instead of internal effect
          */
-        bind(world: Matrix, mesh?: Mesh): void;
+        bind(world: Matrix, mesh?: Mesh, effectOverride?: Nullable<Effect>): void;
         protected _afterBind(mesh?: Mesh): void;
         /**
          * Gets the active textures from the material
@@ -16743,7 +16790,7 @@ declare module BABYLON {
         protected _initializeShadowMap(): void;
         protected _initializeBlurRTTAndPostProcesses(): void;
         protected _renderForShadowMap(opaqueSubMeshes: SmartArray<SubMesh>, alphaTestSubMeshes: SmartArray<SubMesh>, transparentSubMeshes: SmartArray<SubMesh>, depthOnlySubMeshes: SmartArray<SubMesh>): void;
-        protected _bindCustomEffectForRenderSubMeshForShadowMap(subMesh: SubMesh, effect: Effect): void;
+        protected _bindCustomEffectForRenderSubMeshForShadowMap(subMesh: SubMesh, effect: Effect, matriceNames: any): void;
         protected _renderSubMeshForShadowMap(subMesh: SubMesh): void;
         protected _applyFilterValues(): void;
         /**
@@ -16763,6 +16810,7 @@ declare module BABYLON {
             useInstances: boolean;
         }>): Promise<void>;
         protected _isReadyCustomDefines(defines: any, subMesh: SubMesh, useInstances: boolean): void;
+        private _prepareShadowDefines;
         /**
          * Determine wheter the shadow generator is ready or not (mainly all effects and related post processes needs to be ready).
          * @param subMesh The submesh we want to render in the shadow map
@@ -20954,6 +21002,86 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Class used to manipulate GUIDs
+     */
+    export class GUID {
+        /**
+         * Implementation from http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#answer-2117523
+         * Be aware Math.random() could cause collisions, but:
+         * "All but 6 of the 128 bits of the ID are randomly generated, which means that for any two ids, there's a 1 in 2^^122 (or 5.3x10^^36) chance they'll collide"
+         * @returns a pseudo random id
+         */
+        static RandomId(): string;
+    }
+}
+declare module BABYLON {
+    /**
+     * Options to be used when creating a shadow depth material
+     */
+    export interface IIOptionShadowDepthMaterial {
+        /** Variables in the vertex shader code that need to have their names remapped.
+         * The format is: ["var_name", "var_remapped_name", "var_name", "var_remapped_name", ...]
+         * "var_name" should be either: worldPos or vNormalW
+         * So, if the variable holding the world position in your vertex shader is not named worldPos, you must tell the system
+         * the name to use instead by using: ["worldPos", "myWorldPosVar"] assuming the variable is named myWorldPosVar in your code.
+         * If the normal must also be remapped: ["worldPos", "myWorldPosVar", "vNormalW", "myWorldNormal"]
+        */
+        remappedVariables?: string[];
+        /** Set standalone to true if the base material wrapped by ShadowDepthMaterial is not used for a regular object but for depth shadow generation only */
+        standalone?: boolean;
+    }
+    /**
+     * Class that can be used to wrap a base material to generate accurate shadows when using custom vertex/fragment code in the base material
+     */
+    export class ShadowDepthWrapper {
+        private _scene;
+        private _options?;
+        private _baseMaterial;
+        private _onEffectCreatedObserver;
+        private _subMeshToEffect;
+        private _subMeshToDepthEffect;
+        private _meshes;
+        /** @hidden */
+        _matriceNames: any;
+        /** Gets the standalone status of the wrapper */
+        get standalone(): boolean;
+        /** Gets the base material the wrapper is built upon */
+        get baseMaterial(): Material;
+        /**
+         * Instantiate a new shadow depth wrapper.
+         * It works by injecting some specific code in the vertex/fragment shaders of the base material and is used by a shadow generator to
+         * generate the shadow depth map. For more information, please refer to the documentation:
+         * https://doc.babylonjs.com/babylon101/shadows
+         * @param baseMaterial Material to wrap
+         * @param scene Define the scene the material belongs to
+         * @param options Options used to create the wrapper
+         */
+        constructor(baseMaterial: Material, scene: Scene, options?: IIOptionShadowDepthMaterial);
+        /**
+         * Gets the effect to use to generate the depth map
+         * @param subMesh subMesh to get the effect for
+         * @param shadowGenerator shadow generator to get the effect for
+         * @returns the effect to use to generate the depth map for the subMesh + shadow generator specified
+         */
+        getEffect(subMesh: Nullable<SubMesh>, shadowGenerator: ShadowGenerator): Nullable<Effect>;
+        /**
+         * Specifies that the submesh is ready to be used for depth rendering
+         * @param subMesh submesh to check
+         * @param defines the list of defines to take into account when checking the effect
+         * @param shadowGenerator combined with subMesh, it defines the effect to check
+         * @param useInstances specifies that instances should be used
+         * @returns a boolean indicating that the submesh is ready or not
+         */
+        isReadyForSubMesh(subMesh: SubMesh, defines: string[], shadowGenerator: ShadowGenerator, useInstances: boolean): boolean;
+        /**
+         * Disposes the resources
+         */
+        dispose(): void;
+        private _makeEffect;
+    }
+}
+declare module BABYLON {
+    /**
      * Options for compiling materials.
      */
     export interface IMaterialCompilationOptions {
@@ -21056,6 +21184,14 @@ declare module BABYLON {
          */
         static readonly MATERIAL_ALPHATESTANDBLEND: number;
         /**
+         * Custom callback helping to override the default shader used in the material.
+         */
+        customShaderNameResolve: (shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: MaterialDefines | string[], attributes?: string[]) => string;
+        /**
+         * Custom shadow depth material to use for shadow rendering instead of the in-built one
+         */
+        shadowDepthWrapper: Nullable<ShadowDepthWrapper>;
+        /**
          * The ID of the material
          */
         id: string;
@@ -21178,6 +21314,17 @@ declare module BABYLON {
         * An event triggered when the material is unbound
         */
         get onUnBindObservable(): Observable<Material>;
+        protected _onEffectCreatedObservable: Nullable<Observable<{
+            effect: Effect;
+            subMesh: Nullable<SubMesh>;
+        }>>;
+        /**
+        * An event triggered when the effect is (re)created
+        */
+        get onEffectCreatedObservable(): Observable<{
+            effect: Effect;
+            subMesh: Nullable<SubMesh>;
+        }>;
         /**
          * Stores the value of the alpha mode
          */
@@ -21679,6 +21826,8 @@ declare module BABYLON {
         _materialDefines: Nullable<MaterialDefines>;
         /** @hidden */
         _materialEffect: Nullable<Effect>;
+        /** @hidden */
+        _effectOverride: Nullable<Effect>;
         /**
          * Gets material defines used by the effect associated to the sub mesh
          */
@@ -27027,10 +27176,6 @@ declare module BABYLON {
          * corresponding to low luminance, medium luminance, and high luminance areas respectively.
          */
         set cameraColorCurves(value: Nullable<ColorCurves>);
-        /**
-         * Custom callback helping to override the default shader used in the material.
-         */
-        customShaderNameResolve: (shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: StandardMaterialDefines, attributes?: string[]) => string;
         protected _renderTargets: SmartArray<RenderTargetTexture>;
         protected _worldViewProjectionMatrix: Matrix;
         protected _globalAmbientColor: Color3;
@@ -29946,20 +30091,6 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Class used to manipulate GUIDs
-     */
-    export class GUID {
-        /**
-         * Implementation from http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#answer-2117523
-         * Be aware Math.random() could cause collisions, but:
-         * "All but 6 of the 128 bits of the ID are randomly generated, which means that for any two ids, there's a 1 in 2^^122 (or 5.3x10^^36) chance they'll collide"
-         * @returns a pseudo random id
-         */
-        static RandomId(): string;
-    }
-}
-declare module BABYLON {
-    /**
      * Base class of all the textures in babylon.
      * It groups all the common properties the materials, post process, lights... might need
      * in order to make a correct use of the texture.
@@ -30420,6 +30551,7 @@ declare module BABYLON {
         private static _uniqueIdSeed;
         private _engine;
         private _uniformBuffersNames;
+        private _uniformBuffersNamesList;
         private _uniformsNames;
         private _samplerList;
         private _samplers;
@@ -30521,10 +30653,25 @@ declare module BABYLON {
         getUniform(uniformName: string): Nullable<WebGLUniformLocation>;
         /**
          * Returns an array of sampler variable names
-         * @returns The array of sampler variable neames.
+         * @returns The array of sampler variable names.
          */
         getSamplers(): string[];
         /**
+         * Returns an array of uniform variable names
+         * @returns The array of uniform variable names.
+         */
+        getUniformNames(): string[];
+        /**
+         * Returns an array of uniform buffer variable names
+         * @returns The array of uniform buffer variable names.
+         */
+        getUniformBuffersNames(): string[];
+        /**
+         * Returns the index parameters used to create the effect
+         * @returns The index parameters object
+         */
+        getIndexParameters(): any;
+        /**
          * The error from the last compilation.
          * @returns the error string.
          */
@@ -30542,6 +30689,14 @@ declare module BABYLON {
         private _checkIsReady;
         private _loadShader;
         /**
+         * Gets the vertex shader source code of this effect
+         */
+        get vertexSourceCode(): string;
+        /**
+         * Gets the fragment shader source code of this effect
+         */
+        get fragmentSourceCode(): string;
+        /**
          * Recompiles the webGL program
          * @param vertexSourceCode The source code for the vertex shader.
          * @param fragmentSourceCode The source code for the fragment shader.
@@ -32129,63 +32284,6 @@ declare module BABYLON {
          * @hidden
          */
         _rescaleTexture(source: InternalTexture, destination: InternalTexture, scene: Nullable<any>, internalFormat: number, onComplete: () => void): void;
-        /**
-         * Creates a raw texture
-         * @param data defines the data to store in the texture
-         * @param width defines the width of the texture
-         * @param height defines the height of the texture
-         * @param format defines the format of the data
-         * @param generateMipMaps defines if the engine should generate the mip levels
-         * @param invertY defines if data must be stored with Y axis inverted
-         * @param samplingMode defines the required sampling mode (Texture.NEAREST_SAMPLINGMODE by default)
-         * @param compression defines the compression used (null by default)
-         * @param type defines the type fo the data (Engine.TEXTURETYPE_UNSIGNED_INT by default)
-         * @returns the raw texture inside an InternalTexture
-         */
-        createRawTexture(data: Nullable<ArrayBufferView>, width: number, height: number, format: number, generateMipMaps: boolean, invertY: boolean, samplingMode: number, compression?: Nullable<string>, type?: number): InternalTexture;
-        /**
-         * Creates a new raw cube texture
-         * @param data defines the array of data to use to create each face
-         * @param size defines the size of the textures
-         * @param format defines the format of the data
-         * @param type defines the type of the data (like Engine.TEXTURETYPE_UNSIGNED_INT)
-         * @param generateMipMaps  defines if the engine should generate the mip levels
-         * @param invertY defines if data must be stored with Y axis inverted
-         * @param samplingMode defines the required sampling mode (like Texture.NEAREST_SAMPLINGMODE)
-         * @param compression defines the compression used (null by default)
-         * @returns the cube texture as an InternalTexture
-         */
-        createRawCubeTexture(data: Nullable<ArrayBufferView[]>, size: number, format: number, type: number, generateMipMaps: boolean, invertY: boolean, samplingMode: number, compression?: Nullable<string>): InternalTexture;
-        /**
-         * Creates a new raw 3D texture
-         * @param data defines the data used to create the texture
-         * @param width defines the width of the texture
-         * @param height defines the height of the texture
-         * @param depth defines the depth of the texture
-         * @param format defines the format of the texture
-         * @param generateMipMaps defines if the engine must generate mip levels
-         * @param invertY defines if data must be stored with Y axis inverted
-         * @param samplingMode defines the required sampling mode (like Texture.NEAREST_SAMPLINGMODE)
-         * @param compression defines the compressed used (can be null)
-         * @param textureType defines the compressed used (can be null)
-         * @returns a new raw 3D texture (stored in an InternalTexture)
-         */
-        createRawTexture3D(data: Nullable<ArrayBufferView>, width: number, height: number, depth: number, format: number, generateMipMaps: boolean, invertY: boolean, samplingMode: number, compression?: Nullable<string>, textureType?: number): InternalTexture;
-        /**
-         * Creates a new raw 2D array texture
-         * @param data defines the data used to create the texture
-         * @param width defines the width of the texture
-         * @param height defines the height of the texture
-         * @param depth defines the number of layers of the texture
-         * @param format defines the format of the texture
-         * @param generateMipMaps defines if the engine must generate mip levels
-         * @param invertY defines if data must be stored with Y axis inverted
-         * @param samplingMode defines the required sampling mode (like Texture.NEAREST_SAMPLINGMODE)
-         * @param compression defines the compressed used (can be null)
-         * @param textureType defines the compressed used (can be null)
-         * @returns a new raw 2D array texture (stored in an InternalTexture)
-         */
-        createRawTexture2DArray(data: Nullable<ArrayBufferView>, width: number, height: number, depth: number, format: number, generateMipMaps: boolean, invertY: boolean, samplingMode: number, compression?: Nullable<string>, textureType?: number): InternalTexture;
         private _unpackFlipYCached;
         /**
          * In case you are sharing the context with other applications, it might
@@ -34084,8 +34182,6 @@ declare module BABYLON {
          * @param postProcess The post process which's output should be bound
          */
         setTextureFromPostProcessOutput(channel: number, postProcess: Nullable<PostProcess>): void;
-        /** @hidden */
-        _convertRGBtoRGBATextureData(rgbData: any, width: number, height: number, textureType: number): ArrayBufferView;
         protected _rebuildBuffers(): void;
         /** @hidden */
         _renderFrame(): void;
@@ -51953,10 +52049,6 @@ declare module BABYLON {
          * Defines the SubSurface parameters for the material.
          */
         readonly subSurface: PBRSubSurfaceConfiguration;
-        /**
-         * Custom callback helping to override the default shader used in the material.
-         */
-        customShaderNameResolve: (shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: PBRMaterialDefines, attributes?: string[]) => string;
         protected _rebuildInParallel: boolean;
         /**
          * Instantiates a new PBRMaterial instance.
@@ -54967,7 +55059,7 @@ declare module BABYLON {
         protected _initializeGenerator(): void;
         protected _createTargetRenderTexture(): void;
         protected _initializeShadowMap(): void;
-        protected _bindCustomEffectForRenderSubMeshForShadowMap(subMesh: SubMesh, effect: Effect): void;
+        protected _bindCustomEffectForRenderSubMeshForShadowMap(subMesh: SubMesh, effect: Effect, matriceNames: any): void;
         protected _isReadyCustomDefines(defines: any, subMesh: SubMesh, useInstances: boolean): void;
         /**
          * Prepare all the defines in a material relying on a shadow map at the specified light index.
@@ -55511,11 +55603,13 @@ declare module BABYLON {
 declare module BABYLON {
     /** @hidden */
     export class OimoJSPlugin implements IPhysicsEnginePlugin {
+        private _useDeltaForWorldStep;
         world: any;
         name: string;
         BJSOIMO: any;
         private _raycastResult;
-        constructor(iterations?: number, oimoInjection?: any);
+        private _fixedTimeStep;
+        constructor(_useDeltaForWorldStep?: boolean, iterations?: number, oimoInjection?: any);
         setGravity(gravity: Vector3): void;
         setTimeStep(timeStep: number): void;
         getTimeStep(): number;
@@ -56386,10 +56480,6 @@ declare module BABYLON {
      */
     export class ColorGradingTexture extends BaseTexture {
         /**
-         * The current texture matrix. (will always be identity in color grading texture)
-         */
-        private _textureMatrix;
-        /**
          * The texture URL.
          */
         url: string;
@@ -56397,14 +56487,21 @@ declare module BABYLON {
          * Empty line regex stored for GC.
          */
         private static _noneEmptyLineRegex;
+        private _textureMatrix;
         private _engine;
+        private _onLoad;
         /**
          * Instantiates a ColorGradingTexture from the following parameters.
          *
          * @param url The location of the color gradind data (currently only supporting 3dl)
-         * @param scene The scene the texture will be used in
+         * @param sceneOrEngine The scene or engine the texture will be used in
+         * @param onLoad defines a callback triggered when the texture has been loaded
+         */
+        constructor(url: string, sceneOrEngine: Scene | ThinEngine, onLoad?: Nullable<() => void>);
+        /**
+         * Fires the onload event from the constructor if requested.
          */
-        constructor(url: string, scene: Scene);
+        private _triggerOnLoad;
         /**
          * Returns the texture matrix used in most of the material.
          * This is not used in color grading but keep for troubleshooting purpose (easily swap diffuse by colorgrading to look in).
@@ -56438,6 +56535,11 @@ declare module BABYLON {
          * Serializes the LUT texture to json format.
          */
         serialize(): any;
+        /**
+         * Returns true if the passed parameter is a scene object (can be use for typings)
+         * @param sceneOrEngine The object to test.
+         */
+        private static _isScene;
     }
 }
 declare module BABYLON {

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2 - 2
dist/preview release/babylon.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 412 - 191
dist/preview release/babylon.module.d.ts


+ 202 - 96
dist/preview release/documentation.d.ts

@@ -9344,6 +9344,13 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /** @hidden */
+    export var shadowMapFragmentDeclaration: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /** @hidden */
     export var clipPlaneFragmentDeclaration: {
         name: string;
         shader: string;
@@ -9358,6 +9365,13 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /** @hidden */
+    export var shadowMapFragment: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /** @hidden */
     export var shadowMapPixelShader: {
         name: string;
         shader: string;
@@ -9400,6 +9414,13 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /** @hidden */
+    export var shadowMapVertexDeclaration: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /** @hidden */
     export var clipPlaneVertexDeclaration: {
         name: string;
         shader: string;
@@ -9428,6 +9449,20 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /** @hidden */
+    export var shadowMapVertexNormalBias: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /** @hidden */
+    export var shadowMapVertexMetric: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /** @hidden */
     export var clipPlaneVertex: {
         name: string;
         shader: string;
@@ -9475,6 +9510,7 @@ declare module BABYLON {
         length?: number);
         /**
          * Checks if the ray intersects a box
+         * This does not account for the ray lenght by design to improve perfs.
          * @param minimum bound of the box
          * @param maximum bound of the box
          * @param intersectionTreshold extra extend to be added to the box in all direction
@@ -9483,6 +9519,7 @@ declare module BABYLON {
         intersectsBoxMinMax(minimum: DeepImmutable<Vector3>, maximum: DeepImmutable<Vector3>, intersectionTreshold?: number): boolean;
         /**
          * Checks if the ray intersects a box
+         * This does not account for the ray lenght by design to improve perfs.
          * @param box the bounding box to check
          * @param intersectionTreshold extra extend to be added to the BoundingBox in all direction
          * @returns if the box was hit
@@ -10469,7 +10506,7 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
-        interface Engine {
+        interface ThinEngine {
             /**
              * Creates a raw texture
              * @param data defines the data to store in the texture
@@ -15476,6 +15513,7 @@ declare module BABYLON {
         private _cachedWorldViewProjectionMatrix;
         private _renderId;
         private _multiview;
+        private _cachedDefines;
         /**
          * Instantiate a new shader material.
          * The ShaderMaterial object has the necessary methods to pass data from your scene to the Vertex and Fragment Shaders and returns a material that can be applied to any mesh.
@@ -15675,14 +15713,23 @@ declare module BABYLON {
         /**
          * Binds the world matrix to the material
          * @param world defines the world transformation matrix
+         * @param effectOverride - If provided, use this effect instead of internal effect
          */
-        bindOnlyWorldMatrix(world: Matrix): void;
+        bindOnlyWorldMatrix(world: Matrix, effectOverride?: Nullable<Effect>): void;
+        /**
+         * Binds the submesh to this material by preparing the effect and shader to draw
+         * @param world defines the world transformation matrix
+         * @param mesh defines the mesh containing the submesh
+         * @param subMesh defines the submesh to bind the material to
+         */
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         /**
          * Binds the material to the mesh
          * @param world defines the world transformation matrix
          * @param mesh defines the mesh to bind the material to
+         * @param effectOverride - If provided, use this effect instead of internal effect
          */
-        bind(world: Matrix, mesh?: Mesh): void;
+        bind(world: Matrix, mesh?: Mesh, effectOverride?: Nullable<Effect>): void;
         protected _afterBind(mesh?: Mesh): void;
         /**
          * Gets the active textures from the material
@@ -16743,7 +16790,7 @@ declare module BABYLON {
         protected _initializeShadowMap(): void;
         protected _initializeBlurRTTAndPostProcesses(): void;
         protected _renderForShadowMap(opaqueSubMeshes: SmartArray<SubMesh>, alphaTestSubMeshes: SmartArray<SubMesh>, transparentSubMeshes: SmartArray<SubMesh>, depthOnlySubMeshes: SmartArray<SubMesh>): void;
-        protected _bindCustomEffectForRenderSubMeshForShadowMap(subMesh: SubMesh, effect: Effect): void;
+        protected _bindCustomEffectForRenderSubMeshForShadowMap(subMesh: SubMesh, effect: Effect, matriceNames: any): void;
         protected _renderSubMeshForShadowMap(subMesh: SubMesh): void;
         protected _applyFilterValues(): void;
         /**
@@ -16763,6 +16810,7 @@ declare module BABYLON {
             useInstances: boolean;
         }>): Promise<void>;
         protected _isReadyCustomDefines(defines: any, subMesh: SubMesh, useInstances: boolean): void;
+        private _prepareShadowDefines;
         /**
          * Determine wheter the shadow generator is ready or not (mainly all effects and related post processes needs to be ready).
          * @param subMesh The submesh we want to render in the shadow map
@@ -20954,6 +21002,86 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Class used to manipulate GUIDs
+     */
+    export class GUID {
+        /**
+         * Implementation from http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#answer-2117523
+         * Be aware Math.random() could cause collisions, but:
+         * "All but 6 of the 128 bits of the ID are randomly generated, which means that for any two ids, there's a 1 in 2^^122 (or 5.3x10^^36) chance they'll collide"
+         * @returns a pseudo random id
+         */
+        static RandomId(): string;
+    }
+}
+declare module BABYLON {
+    /**
+     * Options to be used when creating a shadow depth material
+     */
+    export interface IIOptionShadowDepthMaterial {
+        /** Variables in the vertex shader code that need to have their names remapped.
+         * The format is: ["var_name", "var_remapped_name", "var_name", "var_remapped_name", ...]
+         * "var_name" should be either: worldPos or vNormalW
+         * So, if the variable holding the world position in your vertex shader is not named worldPos, you must tell the system
+         * the name to use instead by using: ["worldPos", "myWorldPosVar"] assuming the variable is named myWorldPosVar in your code.
+         * If the normal must also be remapped: ["worldPos", "myWorldPosVar", "vNormalW", "myWorldNormal"]
+        */
+        remappedVariables?: string[];
+        /** Set standalone to true if the base material wrapped by ShadowDepthMaterial is not used for a regular object but for depth shadow generation only */
+        standalone?: boolean;
+    }
+    /**
+     * Class that can be used to wrap a base material to generate accurate shadows when using custom vertex/fragment code in the base material
+     */
+    export class ShadowDepthWrapper {
+        private _scene;
+        private _options?;
+        private _baseMaterial;
+        private _onEffectCreatedObserver;
+        private _subMeshToEffect;
+        private _subMeshToDepthEffect;
+        private _meshes;
+        /** @hidden */
+        _matriceNames: any;
+        /** Gets the standalone status of the wrapper */
+        get standalone(): boolean;
+        /** Gets the base material the wrapper is built upon */
+        get baseMaterial(): Material;
+        /**
+         * Instantiate a new shadow depth wrapper.
+         * It works by injecting some specific code in the vertex/fragment shaders of the base material and is used by a shadow generator to
+         * generate the shadow depth map. For more information, please refer to the documentation:
+         * https://doc.babylonjs.com/babylon101/shadows
+         * @param baseMaterial Material to wrap
+         * @param scene Define the scene the material belongs to
+         * @param options Options used to create the wrapper
+         */
+        constructor(baseMaterial: Material, scene: Scene, options?: IIOptionShadowDepthMaterial);
+        /**
+         * Gets the effect to use to generate the depth map
+         * @param subMesh subMesh to get the effect for
+         * @param shadowGenerator shadow generator to get the effect for
+         * @returns the effect to use to generate the depth map for the subMesh + shadow generator specified
+         */
+        getEffect(subMesh: Nullable<SubMesh>, shadowGenerator: ShadowGenerator): Nullable<Effect>;
+        /**
+         * Specifies that the submesh is ready to be used for depth rendering
+         * @param subMesh submesh to check
+         * @param defines the list of defines to take into account when checking the effect
+         * @param shadowGenerator combined with subMesh, it defines the effect to check
+         * @param useInstances specifies that instances should be used
+         * @returns a boolean indicating that the submesh is ready or not
+         */
+        isReadyForSubMesh(subMesh: SubMesh, defines: string[], shadowGenerator: ShadowGenerator, useInstances: boolean): boolean;
+        /**
+         * Disposes the resources
+         */
+        dispose(): void;
+        private _makeEffect;
+    }
+}
+declare module BABYLON {
+    /**
      * Options for compiling materials.
      */
     export interface IMaterialCompilationOptions {
@@ -21056,6 +21184,14 @@ declare module BABYLON {
          */
         static readonly MATERIAL_ALPHATESTANDBLEND: number;
         /**
+         * Custom callback helping to override the default shader used in the material.
+         */
+        customShaderNameResolve: (shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: MaterialDefines | string[], attributes?: string[]) => string;
+        /**
+         * Custom shadow depth material to use for shadow rendering instead of the in-built one
+         */
+        shadowDepthWrapper: Nullable<ShadowDepthWrapper>;
+        /**
          * The ID of the material
          */
         id: string;
@@ -21178,6 +21314,17 @@ declare module BABYLON {
         * An event triggered when the material is unbound
         */
         get onUnBindObservable(): Observable<Material>;
+        protected _onEffectCreatedObservable: Nullable<Observable<{
+            effect: Effect;
+            subMesh: Nullable<SubMesh>;
+        }>>;
+        /**
+        * An event triggered when the effect is (re)created
+        */
+        get onEffectCreatedObservable(): Observable<{
+            effect: Effect;
+            subMesh: Nullable<SubMesh>;
+        }>;
         /**
          * Stores the value of the alpha mode
          */
@@ -21679,6 +21826,8 @@ declare module BABYLON {
         _materialDefines: Nullable<MaterialDefines>;
         /** @hidden */
         _materialEffect: Nullable<Effect>;
+        /** @hidden */
+        _effectOverride: Nullable<Effect>;
         /**
          * Gets material defines used by the effect associated to the sub mesh
          */
@@ -27027,10 +27176,6 @@ declare module BABYLON {
          * corresponding to low luminance, medium luminance, and high luminance areas respectively.
          */
         set cameraColorCurves(value: Nullable<ColorCurves>);
-        /**
-         * Custom callback helping to override the default shader used in the material.
-         */
-        customShaderNameResolve: (shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: StandardMaterialDefines, attributes?: string[]) => string;
         protected _renderTargets: SmartArray<RenderTargetTexture>;
         protected _worldViewProjectionMatrix: Matrix;
         protected _globalAmbientColor: Color3;
@@ -29946,20 +30091,6 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Class used to manipulate GUIDs
-     */
-    export class GUID {
-        /**
-         * Implementation from http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#answer-2117523
-         * Be aware Math.random() could cause collisions, but:
-         * "All but 6 of the 128 bits of the ID are randomly generated, which means that for any two ids, there's a 1 in 2^^122 (or 5.3x10^^36) chance they'll collide"
-         * @returns a pseudo random id
-         */
-        static RandomId(): string;
-    }
-}
-declare module BABYLON {
-    /**
      * Base class of all the textures in babylon.
      * It groups all the common properties the materials, post process, lights... might need
      * in order to make a correct use of the texture.
@@ -30420,6 +30551,7 @@ declare module BABYLON {
         private static _uniqueIdSeed;
         private _engine;
         private _uniformBuffersNames;
+        private _uniformBuffersNamesList;
         private _uniformsNames;
         private _samplerList;
         private _samplers;
@@ -30521,10 +30653,25 @@ declare module BABYLON {
         getUniform(uniformName: string): Nullable<WebGLUniformLocation>;
         /**
          * Returns an array of sampler variable names
-         * @returns The array of sampler variable neames.
+         * @returns The array of sampler variable names.
          */
         getSamplers(): string[];
         /**
+         * Returns an array of uniform variable names
+         * @returns The array of uniform variable names.
+         */
+        getUniformNames(): string[];
+        /**
+         * Returns an array of uniform buffer variable names
+         * @returns The array of uniform buffer variable names.
+         */
+        getUniformBuffersNames(): string[];
+        /**
+         * Returns the index parameters used to create the effect
+         * @returns The index parameters object
+         */
+        getIndexParameters(): any;
+        /**
          * The error from the last compilation.
          * @returns the error string.
          */
@@ -30542,6 +30689,14 @@ declare module BABYLON {
         private _checkIsReady;
         private _loadShader;
         /**
+         * Gets the vertex shader source code of this effect
+         */
+        get vertexSourceCode(): string;
+        /**
+         * Gets the fragment shader source code of this effect
+         */
+        get fragmentSourceCode(): string;
+        /**
          * Recompiles the webGL program
          * @param vertexSourceCode The source code for the vertex shader.
          * @param fragmentSourceCode The source code for the fragment shader.
@@ -32129,63 +32284,6 @@ declare module BABYLON {
          * @hidden
          */
         _rescaleTexture(source: InternalTexture, destination: InternalTexture, scene: Nullable<any>, internalFormat: number, onComplete: () => void): void;
-        /**
-         * Creates a raw texture
-         * @param data defines the data to store in the texture
-         * @param width defines the width of the texture
-         * @param height defines the height of the texture
-         * @param format defines the format of the data
-         * @param generateMipMaps defines if the engine should generate the mip levels
-         * @param invertY defines if data must be stored with Y axis inverted
-         * @param samplingMode defines the required sampling mode (Texture.NEAREST_SAMPLINGMODE by default)
-         * @param compression defines the compression used (null by default)
-         * @param type defines the type fo the data (Engine.TEXTURETYPE_UNSIGNED_INT by default)
-         * @returns the raw texture inside an InternalTexture
-         */
-        createRawTexture(data: Nullable<ArrayBufferView>, width: number, height: number, format: number, generateMipMaps: boolean, invertY: boolean, samplingMode: number, compression?: Nullable<string>, type?: number): InternalTexture;
-        /**
-         * Creates a new raw cube texture
-         * @param data defines the array of data to use to create each face
-         * @param size defines the size of the textures
-         * @param format defines the format of the data
-         * @param type defines the type of the data (like Engine.TEXTURETYPE_UNSIGNED_INT)
-         * @param generateMipMaps  defines if the engine should generate the mip levels
-         * @param invertY defines if data must be stored with Y axis inverted
-         * @param samplingMode defines the required sampling mode (like Texture.NEAREST_SAMPLINGMODE)
-         * @param compression defines the compression used (null by default)
-         * @returns the cube texture as an InternalTexture
-         */
-        createRawCubeTexture(data: Nullable<ArrayBufferView[]>, size: number, format: number, type: number, generateMipMaps: boolean, invertY: boolean, samplingMode: number, compression?: Nullable<string>): InternalTexture;
-        /**
-         * Creates a new raw 3D texture
-         * @param data defines the data used to create the texture
-         * @param width defines the width of the texture
-         * @param height defines the height of the texture
-         * @param depth defines the depth of the texture
-         * @param format defines the format of the texture
-         * @param generateMipMaps defines if the engine must generate mip levels
-         * @param invertY defines if data must be stored with Y axis inverted
-         * @param samplingMode defines the required sampling mode (like Texture.NEAREST_SAMPLINGMODE)
-         * @param compression defines the compressed used (can be null)
-         * @param textureType defines the compressed used (can be null)
-         * @returns a new raw 3D texture (stored in an InternalTexture)
-         */
-        createRawTexture3D(data: Nullable<ArrayBufferView>, width: number, height: number, depth: number, format: number, generateMipMaps: boolean, invertY: boolean, samplingMode: number, compression?: Nullable<string>, textureType?: number): InternalTexture;
-        /**
-         * Creates a new raw 2D array texture
-         * @param data defines the data used to create the texture
-         * @param width defines the width of the texture
-         * @param height defines the height of the texture
-         * @param depth defines the number of layers of the texture
-         * @param format defines the format of the texture
-         * @param generateMipMaps defines if the engine must generate mip levels
-         * @param invertY defines if data must be stored with Y axis inverted
-         * @param samplingMode defines the required sampling mode (like Texture.NEAREST_SAMPLINGMODE)
-         * @param compression defines the compressed used (can be null)
-         * @param textureType defines the compressed used (can be null)
-         * @returns a new raw 2D array texture (stored in an InternalTexture)
-         */
-        createRawTexture2DArray(data: Nullable<ArrayBufferView>, width: number, height: number, depth: number, format: number, generateMipMaps: boolean, invertY: boolean, samplingMode: number, compression?: Nullable<string>, textureType?: number): InternalTexture;
         private _unpackFlipYCached;
         /**
          * In case you are sharing the context with other applications, it might
@@ -34084,8 +34182,6 @@ declare module BABYLON {
          * @param postProcess The post process which's output should be bound
          */
         setTextureFromPostProcessOutput(channel: number, postProcess: Nullable<PostProcess>): void;
-        /** @hidden */
-        _convertRGBtoRGBATextureData(rgbData: any, width: number, height: number, textureType: number): ArrayBufferView;
         protected _rebuildBuffers(): void;
         /** @hidden */
         _renderFrame(): void;
@@ -51953,10 +52049,6 @@ declare module BABYLON {
          * Defines the SubSurface parameters for the material.
          */
         readonly subSurface: PBRSubSurfaceConfiguration;
-        /**
-         * Custom callback helping to override the default shader used in the material.
-         */
-        customShaderNameResolve: (shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: PBRMaterialDefines, attributes?: string[]) => string;
         protected _rebuildInParallel: boolean;
         /**
          * Instantiates a new PBRMaterial instance.
@@ -54967,7 +55059,7 @@ declare module BABYLON {
         protected _initializeGenerator(): void;
         protected _createTargetRenderTexture(): void;
         protected _initializeShadowMap(): void;
-        protected _bindCustomEffectForRenderSubMeshForShadowMap(subMesh: SubMesh, effect: Effect): void;
+        protected _bindCustomEffectForRenderSubMeshForShadowMap(subMesh: SubMesh, effect: Effect, matriceNames: any): void;
         protected _isReadyCustomDefines(defines: any, subMesh: SubMesh, useInstances: boolean): void;
         /**
          * Prepare all the defines in a material relying on a shadow map at the specified light index.
@@ -55511,11 +55603,13 @@ declare module BABYLON {
 declare module BABYLON {
     /** @hidden */
     export class OimoJSPlugin implements IPhysicsEnginePlugin {
+        private _useDeltaForWorldStep;
         world: any;
         name: string;
         BJSOIMO: any;
         private _raycastResult;
-        constructor(iterations?: number, oimoInjection?: any);
+        private _fixedTimeStep;
+        constructor(_useDeltaForWorldStep?: boolean, iterations?: number, oimoInjection?: any);
         setGravity(gravity: Vector3): void;
         setTimeStep(timeStep: number): void;
         getTimeStep(): number;
@@ -56386,10 +56480,6 @@ declare module BABYLON {
      */
     export class ColorGradingTexture extends BaseTexture {
         /**
-         * The current texture matrix. (will always be identity in color grading texture)
-         */
-        private _textureMatrix;
-        /**
          * The texture URL.
          */
         url: string;
@@ -56397,14 +56487,21 @@ declare module BABYLON {
          * Empty line regex stored for GC.
          */
         private static _noneEmptyLineRegex;
+        private _textureMatrix;
         private _engine;
+        private _onLoad;
         /**
          * Instantiates a ColorGradingTexture from the following parameters.
          *
          * @param url The location of the color gradind data (currently only supporting 3dl)
-         * @param scene The scene the texture will be used in
+         * @param sceneOrEngine The scene or engine the texture will be used in
+         * @param onLoad defines a callback triggered when the texture has been loaded
+         */
+        constructor(url: string, sceneOrEngine: Scene | ThinEngine, onLoad?: Nullable<() => void>);
+        /**
+         * Fires the onload event from the constructor if requested.
          */
-        constructor(url: string, scene: Scene);
+        private _triggerOnLoad;
         /**
          * Returns the texture matrix used in most of the material.
          * This is not used in color grading but keep for troubleshooting purpose (easily swap diffuse by colorgrading to look in).
@@ -56438,6 +56535,11 @@ declare module BABYLON {
          * Serializes the LUT texture to json format.
          */
         serialize(): any;
+        /**
+         * Returns true if the passed parameter is a scene object (can be use for typings)
+         * @param sceneOrEngine The object to test.
+         */
+        private static _isScene;
     }
 }
 declare module BABYLON {
@@ -79751,6 +79853,7 @@ declare module BABYLON {
         Vertex_MainBegin: string;
         Vertex_Before_PositionUpdated: string;
         Vertex_Before_NormalUpdated: string;
+        Vertex_After_WorldPosComputed: string;
         Vertex_MainEnd: string;
     }
     export class CustomMaterial extends BABYLON.StandardMaterial {
@@ -79767,7 +79870,7 @@ declare module BABYLON {
         VertexShader: string;
         AttachAfterBind(mesh: BABYLON.Mesh, effect: BABYLON.Effect): void;
         ReviewUniform(name: string, arr: string[]): string[];
-        Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: BABYLON.StandardMaterialDefines, attributes?: string[]): string;
+        Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: BABYLON.MaterialDefines | string[], attributes?: string[]): string;
         constructor(name: string, scene: BABYLON.Scene);
         AddUniform(name: string, kind: string, param: any): CustomMaterial;
         AddAttribute(name: string): CustomMaterial;
@@ -79784,6 +79887,7 @@ declare module BABYLON {
         Vertex_MainBegin(shaderPart: string): CustomMaterial;
         Vertex_Before_PositionUpdated(shaderPart: string): CustomMaterial;
         Vertex_Before_NormalUpdated(shaderPart: string): CustomMaterial;
+        Vertex_After_WorldPosComputed(shaderPart: string): CustomMaterial;
         Vertex_MainEnd(shaderPart: string): CustomMaterial;
     }
 }
@@ -79805,6 +79909,7 @@ declare module BABYLON {
         Vertex_MainBegin: string;
         Vertex_Before_PositionUpdated: string;
         Vertex_Before_NormalUpdated: string;
+        Vertex_After_WorldPosComputed: string;
         Vertex_MainEnd: string;
     }
     export class PBRCustomMaterial extends BABYLON.PBRMaterial {
@@ -79821,7 +79926,7 @@ declare module BABYLON {
         VertexShader: string;
         AttachAfterBind(mesh: BABYLON.Mesh, effect: BABYLON.Effect): void;
         ReviewUniform(name: string, arr: string[]): string[];
-        Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: BABYLON.PBRMaterialDefines, attributes?: string[]): string;
+        Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: BABYLON.MaterialDefines | string[], attributes?: string[]): string;
         constructor(name: string, scene: BABYLON.Scene);
         AddUniform(name: string, kind: string, param: any): PBRCustomMaterial;
         AddAttribute(name: string): PBRCustomMaterial;
@@ -79840,6 +79945,7 @@ declare module BABYLON {
         Vertex_MainBegin(shaderPart: string): PBRCustomMaterial;
         Vertex_Before_PositionUpdated(shaderPart: string): PBRCustomMaterial;
         Vertex_Before_NormalUpdated(shaderPart: string): PBRCustomMaterial;
+        Vertex_After_WorldPosComputed(shaderPart: string): PBRCustomMaterial;
         Vertex_MainEnd(shaderPart: string): PBRCustomMaterial;
     }
 }

+ 1 - 1
dist/preview release/glTF2Interface/package.json

@@ -1,7 +1,7 @@
 {
     "name": "babylonjs-gltf2interface",
     "description": "A typescript declaration of babylon's gltf2 inteface.",
-    "version": "4.2.0-alpha.9",
+    "version": "4.2.0-alpha.10",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 2 - 2
dist/preview release/gui/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-gui",
     "description": "The Babylon.js GUI library is an extension you can use to generate interactive user interface. It is build on top of the DynamicTexture.",
-    "version": "4.2.0-alpha.9",
+    "version": "4.2.0-alpha.10",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,7 +28,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.2.0-alpha.9"
+        "babylonjs": "4.2.0-alpha.10"
     },
     "engines": {
         "node": "*"

+ 7 - 7
dist/preview release/inspector/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-inspector",
     "description": "The Babylon.js inspector.",
-    "version": "4.2.0-alpha.9",
+    "version": "4.2.0-alpha.10",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -29,12 +29,12 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.2.0-alpha.9",
-        "babylonjs-gui": "4.2.0-alpha.9",
-        "babylonjs-loaders": "4.2.0-alpha.9",
-        "babylonjs-materials": "4.2.0-alpha.9",
-        "babylonjs-serializers": "4.2.0-alpha.9",
-        "babylonjs-gltf2interface": "4.2.0-alpha.9"
+        "babylonjs": "4.2.0-alpha.10",
+        "babylonjs-gui": "4.2.0-alpha.10",
+        "babylonjs-loaders": "4.2.0-alpha.10",
+        "babylonjs-materials": "4.2.0-alpha.10",
+        "babylonjs-serializers": "4.2.0-alpha.10",
+        "babylonjs-gltf2interface": "4.2.0-alpha.10"
     },
     "devDependencies": {
         "@types/react": "~16.7.3",

+ 3 - 3
dist/preview release/loaders/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-loaders",
     "description": "The Babylon.js file loaders library is an extension you can use to load different 3D file types into a Babylon scene.",
-    "version": "4.2.0-alpha.9",
+    "version": "4.2.0-alpha.10",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,8 +28,8 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs-gltf2interface": "4.2.0-alpha.9",
-        "babylonjs": "4.2.0-alpha.9"
+        "babylonjs-gltf2interface": "4.2.0-alpha.10",
+        "babylonjs": "4.2.0-alpha.10"
     },
     "engines": {
         "node": "*"

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2 - 2
dist/preview release/materialsLibrary/babylon.customMaterial.min.js


+ 6 - 2
dist/preview release/materialsLibrary/babylonjs.materials.d.ts

@@ -60,6 +60,7 @@ declare module BABYLON {
         Vertex_MainBegin: string;
         Vertex_Before_PositionUpdated: string;
         Vertex_Before_NormalUpdated: string;
+        Vertex_After_WorldPosComputed: string;
         Vertex_MainEnd: string;
     }
     export class CustomMaterial extends BABYLON.StandardMaterial {
@@ -76,7 +77,7 @@ declare module BABYLON {
         VertexShader: string;
         AttachAfterBind(mesh: BABYLON.Mesh, effect: BABYLON.Effect): void;
         ReviewUniform(name: string, arr: string[]): string[];
-        Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: BABYLON.StandardMaterialDefines, attributes?: string[]): string;
+        Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: BABYLON.MaterialDefines | string[], attributes?: string[]): string;
         constructor(name: string, scene: BABYLON.Scene);
         AddUniform(name: string, kind: string, param: any): CustomMaterial;
         AddAttribute(name: string): CustomMaterial;
@@ -93,6 +94,7 @@ declare module BABYLON {
         Vertex_MainBegin(shaderPart: string): CustomMaterial;
         Vertex_Before_PositionUpdated(shaderPart: string): CustomMaterial;
         Vertex_Before_NormalUpdated(shaderPart: string): CustomMaterial;
+        Vertex_After_WorldPosComputed(shaderPart: string): CustomMaterial;
         Vertex_MainEnd(shaderPart: string): CustomMaterial;
     }
 }
@@ -114,6 +116,7 @@ declare module BABYLON {
         Vertex_MainBegin: string;
         Vertex_Before_PositionUpdated: string;
         Vertex_Before_NormalUpdated: string;
+        Vertex_After_WorldPosComputed: string;
         Vertex_MainEnd: string;
     }
     export class PBRCustomMaterial extends BABYLON.PBRMaterial {
@@ -130,7 +133,7 @@ declare module BABYLON {
         VertexShader: string;
         AttachAfterBind(mesh: BABYLON.Mesh, effect: BABYLON.Effect): void;
         ReviewUniform(name: string, arr: string[]): string[];
-        Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: BABYLON.PBRMaterialDefines, attributes?: string[]): string;
+        Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: BABYLON.MaterialDefines | string[], attributes?: string[]): string;
         constructor(name: string, scene: BABYLON.Scene);
         AddUniform(name: string, kind: string, param: any): PBRCustomMaterial;
         AddAttribute(name: string): PBRCustomMaterial;
@@ -149,6 +152,7 @@ declare module BABYLON {
         Vertex_MainBegin(shaderPart: string): PBRCustomMaterial;
         Vertex_Before_PositionUpdated(shaderPart: string): PBRCustomMaterial;
         Vertex_Before_NormalUpdated(shaderPart: string): PBRCustomMaterial;
+        Vertex_After_WorldPosComputed(shaderPart: string): PBRCustomMaterial;
         Vertex_MainEnd(shaderPart: string): PBRCustomMaterial;
     }
 }

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 1
dist/preview release/materialsLibrary/babylonjs.materials.min.js


+ 14 - 6
dist/preview release/materialsLibrary/babylonjs.materials.module.d.ts

@@ -79,7 +79,7 @@ declare module "babylonjs-materials/cell/index" {
 declare module "babylonjs-materials/custom/customMaterial" {
     import { Texture } from "babylonjs/Materials/Textures/texture";
     import { Effect } from "babylonjs/Materials/effect";
-    import { StandardMaterialDefines } from "babylonjs/Materials/standardMaterial";
+    import { MaterialDefines } from "babylonjs/Materials/materialDefines";
     import { StandardMaterial } from "babylonjs/Materials/standardMaterial";
     import { Mesh } from "babylonjs/Meshes/mesh";
     import { Scene } from "babylonjs/scene";
@@ -103,6 +103,7 @@ declare module "babylonjs-materials/custom/customMaterial" {
         Vertex_MainBegin: string;
         Vertex_Before_PositionUpdated: string;
         Vertex_Before_NormalUpdated: string;
+        Vertex_After_WorldPosComputed: string;
         Vertex_MainEnd: string;
     }
     export class CustomMaterial extends StandardMaterial {
@@ -119,7 +120,7 @@ declare module "babylonjs-materials/custom/customMaterial" {
         VertexShader: string;
         AttachAfterBind(mesh: Mesh, effect: Effect): void;
         ReviewUniform(name: string, arr: string[]): string[];
-        Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: StandardMaterialDefines, attributes?: string[]): string;
+        Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: MaterialDefines | string[], attributes?: string[]): string;
         constructor(name: string, scene: Scene);
         AddUniform(name: string, kind: string, param: any): CustomMaterial;
         AddAttribute(name: string): CustomMaterial;
@@ -136,13 +137,14 @@ declare module "babylonjs-materials/custom/customMaterial" {
         Vertex_MainBegin(shaderPart: string): CustomMaterial;
         Vertex_Before_PositionUpdated(shaderPart: string): CustomMaterial;
         Vertex_Before_NormalUpdated(shaderPart: string): CustomMaterial;
+        Vertex_After_WorldPosComputed(shaderPart: string): CustomMaterial;
         Vertex_MainEnd(shaderPart: string): CustomMaterial;
     }
 }
 declare module "babylonjs-materials/custom/pbrCustomMaterial" {
     import { Texture } from "babylonjs/Materials/Textures/texture";
     import { Effect } from "babylonjs/Materials/effect";
-    import { PBRMaterialDefines } from "babylonjs/Materials/PBR/pbrBaseMaterial";
+    import { MaterialDefines } from "babylonjs/Materials/materialDefines";
     import { PBRMaterial } from "babylonjs/Materials/PBR/pbrMaterial";
     import { Mesh } from "babylonjs/Meshes/mesh";
     import { Scene } from "babylonjs/scene";
@@ -163,6 +165,7 @@ declare module "babylonjs-materials/custom/pbrCustomMaterial" {
         Vertex_MainBegin: string;
         Vertex_Before_PositionUpdated: string;
         Vertex_Before_NormalUpdated: string;
+        Vertex_After_WorldPosComputed: string;
         Vertex_MainEnd: string;
     }
     export class PBRCustomMaterial extends PBRMaterial {
@@ -179,7 +182,7 @@ declare module "babylonjs-materials/custom/pbrCustomMaterial" {
         VertexShader: string;
         AttachAfterBind(mesh: Mesh, effect: Effect): void;
         ReviewUniform(name: string, arr: string[]): string[];
-        Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: PBRMaterialDefines, attributes?: string[]): string;
+        Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: MaterialDefines | string[], attributes?: string[]): string;
         constructor(name: string, scene: Scene);
         AddUniform(name: string, kind: string, param: any): PBRCustomMaterial;
         AddAttribute(name: string): PBRCustomMaterial;
@@ -198,6 +201,7 @@ declare module "babylonjs-materials/custom/pbrCustomMaterial" {
         Vertex_MainBegin(shaderPart: string): PBRCustomMaterial;
         Vertex_Before_PositionUpdated(shaderPart: string): PBRCustomMaterial;
         Vertex_Before_NormalUpdated(shaderPart: string): PBRCustomMaterial;
+        Vertex_After_WorldPosComputed(shaderPart: string): PBRCustomMaterial;
         Vertex_MainEnd(shaderPart: string): PBRCustomMaterial;
     }
 }
@@ -1615,6 +1619,7 @@ declare module BABYLON {
         Vertex_MainBegin: string;
         Vertex_Before_PositionUpdated: string;
         Vertex_Before_NormalUpdated: string;
+        Vertex_After_WorldPosComputed: string;
         Vertex_MainEnd: string;
     }
     export class CustomMaterial extends BABYLON.StandardMaterial {
@@ -1631,7 +1636,7 @@ declare module BABYLON {
         VertexShader: string;
         AttachAfterBind(mesh: BABYLON.Mesh, effect: BABYLON.Effect): void;
         ReviewUniform(name: string, arr: string[]): string[];
-        Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: BABYLON.StandardMaterialDefines, attributes?: string[]): string;
+        Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: BABYLON.MaterialDefines | string[], attributes?: string[]): string;
         constructor(name: string, scene: BABYLON.Scene);
         AddUniform(name: string, kind: string, param: any): CustomMaterial;
         AddAttribute(name: string): CustomMaterial;
@@ -1648,6 +1653,7 @@ declare module BABYLON {
         Vertex_MainBegin(shaderPart: string): CustomMaterial;
         Vertex_Before_PositionUpdated(shaderPart: string): CustomMaterial;
         Vertex_Before_NormalUpdated(shaderPart: string): CustomMaterial;
+        Vertex_After_WorldPosComputed(shaderPart: string): CustomMaterial;
         Vertex_MainEnd(shaderPart: string): CustomMaterial;
     }
 }
@@ -1669,6 +1675,7 @@ declare module BABYLON {
         Vertex_MainBegin: string;
         Vertex_Before_PositionUpdated: string;
         Vertex_Before_NormalUpdated: string;
+        Vertex_After_WorldPosComputed: string;
         Vertex_MainEnd: string;
     }
     export class PBRCustomMaterial extends BABYLON.PBRMaterial {
@@ -1685,7 +1692,7 @@ declare module BABYLON {
         VertexShader: string;
         AttachAfterBind(mesh: BABYLON.Mesh, effect: BABYLON.Effect): void;
         ReviewUniform(name: string, arr: string[]): string[];
-        Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: BABYLON.PBRMaterialDefines, attributes?: string[]): string;
+        Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: BABYLON.MaterialDefines | string[], attributes?: string[]): string;
         constructor(name: string, scene: BABYLON.Scene);
         AddUniform(name: string, kind: string, param: any): PBRCustomMaterial;
         AddAttribute(name: string): PBRCustomMaterial;
@@ -1704,6 +1711,7 @@ declare module BABYLON {
         Vertex_MainBegin(shaderPart: string): PBRCustomMaterial;
         Vertex_Before_PositionUpdated(shaderPart: string): PBRCustomMaterial;
         Vertex_Before_NormalUpdated(shaderPart: string): PBRCustomMaterial;
+        Vertex_After_WorldPosComputed(shaderPart: string): PBRCustomMaterial;
         Vertex_MainEnd(shaderPart: string): PBRCustomMaterial;
     }
 }

+ 2 - 2
dist/preview release/materialsLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-materials",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "4.2.0-alpha.9",
+    "version": "4.2.0-alpha.10",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,7 +28,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.2.0-alpha.9"
+        "babylonjs": "4.2.0-alpha.10"
     },
     "engines": {
         "node": "*"

+ 19 - 14
dist/preview release/nodeEditor/babylon.nodeEditor.d.ts

@@ -100,24 +100,22 @@ declare module NODEEDITOR {
     export class FrameNodePort extends NodePort {
         connectionPoint: BABYLON.NodeMaterialConnectionPoint;
         node: GraphNode;
-        private _onFramePortMoveUpObservable;
-        private _onFramePortMoveDownObservable;
-        private _onFramePortPositionChangedObservable;
         private _portLabel;
+        private _parentFrameId;
         private _isInput;
         private _framePortPosition;
         private _framePortId;
-        get onFramePortMoveUpObservable(): BABYLON.Observable<FrameNodePort>;
-        get onFramePortMoveDownObservable(): BABYLON.Observable<FrameNodePort>;
-        get onFramePortPositionChangedObservable(): BABYLON.Observable<FramePortPosition>;
+        private _onFramePortPositionChangedObservable;
+        get parentFrameId(): number;
+        get onFramePortPositionChangedObservable(): BABYLON.Observable<FrameNodePort>;
         get isInput(): boolean;
         get portLabel(): string;
-        get framePortId(): BABYLON.Nullable<number>;
+        get framePortId(): number;
         set portLabel(newLabel: string);
         get framePortPosition(): FramePortPosition;
         set framePortPosition(position: FramePortPosition);
-        constructor(portContainer: HTMLElement, connectionPoint: BABYLON.NodeMaterialConnectionPoint, node: GraphNode, globalState: GlobalState, isInput: boolean, framePortId: number);
-        static CreateFrameNodePortElement(connectionPoint: BABYLON.NodeMaterialConnectionPoint, node: GraphNode, root: HTMLElement, displayManager: BABYLON.Nullable<IDisplayManager>, globalState: GlobalState, isInput: boolean, framePortId: number): FrameNodePort;
+        constructor(portContainer: HTMLElement, connectionPoint: BABYLON.NodeMaterialConnectionPoint, node: GraphNode, globalState: GlobalState, isInput: boolean, framePortId: number, parentFrameId: number);
+        static CreateFrameNodePortElement(connectionPoint: BABYLON.NodeMaterialConnectionPoint, node: GraphNode, root: HTMLElement, displayManager: BABYLON.Nullable<IDisplayManager>, globalState: GlobalState, isInput: boolean, framePortId: number, parentFrameId: number): FrameNodePort;
     }
 }
 declare module NODEEDITOR {
@@ -200,9 +198,9 @@ declare module NODEEDITOR {
         private _onUp;
         private _moveFrame;
         private _onMove;
-        private moveFramePortUp;
+        moveFramePortUp(nodePort: FrameNodePort): void;
         private _movePortUp;
-        private moveFramePortDown;
+        moveFramePortDown(nodePort: FrameNodePort): void;
         private _movePortDown;
         private initResizing;
         private cleanUpResizing;
@@ -263,7 +261,7 @@ declare module NODEEDITOR {
         protected _img: HTMLImageElement;
         protected _globalState: GlobalState;
         protected _onCandidateLinkMovedObserver: BABYLON.Nullable<BABYLON.Observer<BABYLON.Nullable<BABYLON.Vector2>>>;
-        protected _onSelectionChangedObserver: BABYLON.Nullable<BABYLON.Observer<BABYLON.Nullable<GraphNode | NodeLink | GraphFrame | NodePort | FrameNodePort>>>;
+        protected _onSelectionChangedObserver: BABYLON.Nullable<BABYLON.Observer<BABYLON.Nullable<GraphFrame | GraphNode | NodeLink | NodePort | FramePortData>>>;
         delegatedPort: BABYLON.Nullable<FrameNodePort>;
         get element(): HTMLDivElement;
         refresh(): void;
@@ -300,6 +298,11 @@ declare module NODEEDITOR {
     export interface IGraphCanvasComponentProps {
         globalState: GlobalState;
     }
+    export type FramePortData = {
+        frame: GraphFrame;
+        port: FrameNodePort;
+    };
+    export const isFramePortData: (variableToCheck: any) => variableToCheck is FramePortData;
     export class GraphCanvasComponent extends React.Component<IGraphCanvasComponentProps> {
         private readonly MinZoom;
         private readonly MaxZoom;
@@ -1184,7 +1187,7 @@ declare module NODEEDITOR {
         hostElement: HTMLElement;
         hostDocument: HTMLDocument;
         hostWindow: Window;
-        onSelectionChangedObservable: BABYLON.Observable<BABYLON.Nullable<GraphNode | NodePort | NodeLink | GraphFrame>>;
+        onSelectionChangedObservable: BABYLON.Observable<BABYLON.Nullable<GraphNode | NodePort | GraphFrame | NodeLink | FramePortData>>;
         onRebuildRequiredObservable: BABYLON.Observable<void>;
         onBuiltObservable: BABYLON.Observable<void>;
         onResetRequiredObservable: BABYLON.Observable<void>;
@@ -1267,11 +1270,13 @@ declare module NODEEDITOR {
     export interface IFrameNodePortPropertyTabComponentProps {
         globalState: GlobalState;
         frameNodePort: FrameNodePort;
+        frame: GraphFrame;
     }
     export class FrameNodePortPropertyTabComponent extends React.Component<IFrameNodePortPropertyTabComponentProps, {
-        framePortPosition: FramePortPosition;
+        port: FrameNodePort;
     }> {
         private _onFramePortPositionChangedObserver;
+        private _onSelectionChangedObserver;
         constructor(props: IFrameNodePortPropertyTabComponentProps);
         componentWillUnmount(): void;
         render(): JSX.Element;

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 4 - 4
dist/preview release/nodeEditor/babylon.nodeEditor.js


+ 42 - 29
dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts

@@ -177,24 +177,22 @@ declare module "babylonjs-node-editor/diagram/frameNodePort" {
     export class FrameNodePort extends NodePort {
         connectionPoint: NodeMaterialConnectionPoint;
         node: GraphNode;
-        private _onFramePortMoveUpObservable;
-        private _onFramePortMoveDownObservable;
-        private _onFramePortPositionChangedObservable;
         private _portLabel;
+        private _parentFrameId;
         private _isInput;
         private _framePortPosition;
         private _framePortId;
-        get onFramePortMoveUpObservable(): Observable<FrameNodePort>;
-        get onFramePortMoveDownObservable(): Observable<FrameNodePort>;
-        get onFramePortPositionChangedObservable(): Observable<FramePortPosition>;
+        private _onFramePortPositionChangedObservable;
+        get parentFrameId(): number;
+        get onFramePortPositionChangedObservable(): Observable<FrameNodePort>;
         get isInput(): boolean;
         get portLabel(): string;
-        get framePortId(): Nullable<number>;
+        get framePortId(): number;
         set portLabel(newLabel: string);
         get framePortPosition(): FramePortPosition;
         set framePortPosition(position: FramePortPosition);
-        constructor(portContainer: HTMLElement, connectionPoint: NodeMaterialConnectionPoint, node: GraphNode, globalState: GlobalState, isInput: boolean, framePortId: number);
-        static CreateFrameNodePortElement(connectionPoint: NodeMaterialConnectionPoint, node: GraphNode, root: HTMLElement, displayManager: Nullable<IDisplayManager>, globalState: GlobalState, isInput: boolean, framePortId: number): FrameNodePort;
+        constructor(portContainer: HTMLElement, connectionPoint: NodeMaterialConnectionPoint, node: GraphNode, globalState: GlobalState, isInput: boolean, framePortId: number, parentFrameId: number);
+        static CreateFrameNodePortElement(connectionPoint: NodeMaterialConnectionPoint, node: GraphNode, root: HTMLElement, displayManager: Nullable<IDisplayManager>, globalState: GlobalState, isInput: boolean, framePortId: number, parentFrameId: number): FrameNodePort;
     }
 }
 declare module "babylonjs-node-editor/diagram/graphFrame" {
@@ -284,9 +282,9 @@ declare module "babylonjs-node-editor/diagram/graphFrame" {
         private _onUp;
         private _moveFrame;
         private _onMove;
-        private moveFramePortUp;
+        moveFramePortUp(nodePort: FrameNodePort): void;
         private _movePortUp;
-        private moveFramePortDown;
+        moveFramePortDown(nodePort: FrameNodePort): void;
         private _movePortDown;
         private initResizing;
         private cleanUpResizing;
@@ -350,6 +348,7 @@ declare module "babylonjs-node-editor/diagram/nodePort" {
     import { NodeLink } from "babylonjs-node-editor/diagram/nodeLink";
     import { GraphFrame } from "babylonjs-node-editor/diagram/graphFrame";
     import { FrameNodePort } from "babylonjs-node-editor/diagram/frameNodePort";
+    import { FramePortData } from "babylonjs-node-editor/diagram/graphCanvas";
     export class NodePort {
         connectionPoint: NodeMaterialConnectionPoint;
         node: GraphNode;
@@ -357,7 +356,7 @@ declare module "babylonjs-node-editor/diagram/nodePort" {
         protected _img: HTMLImageElement;
         protected _globalState: GlobalState;
         protected _onCandidateLinkMovedObserver: Nullable<Observer<Nullable<Vector2>>>;
-        protected _onSelectionChangedObserver: Nullable<Observer<Nullable<GraphNode | NodeLink | GraphFrame | NodePort | FrameNodePort>>>;
+        protected _onSelectionChangedObserver: Nullable<Observer<Nullable<GraphFrame | GraphNode | NodeLink | NodePort | FramePortData>>>;
         delegatedPort: Nullable<FrameNodePort>;
         get element(): HTMLDivElement;
         refresh(): void;
@@ -406,9 +405,15 @@ declare module "babylonjs-node-editor/diagram/graphCanvas" {
     import { NodeMaterialConnectionPoint } from 'babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint';
     import { GraphFrame } from "babylonjs-node-editor/diagram/graphFrame";
     import { IEditorData } from "babylonjs-node-editor/nodeLocationInfo";
+    import { FrameNodePort } from "babylonjs-node-editor/diagram/frameNodePort";
     export interface IGraphCanvasComponentProps {
         globalState: GlobalState;
     }
+    export type FramePortData = {
+        frame: GraphFrame;
+        port: FrameNodePort;
+    };
+    export const isFramePortData: (variableToCheck: any) => variableToCheck is FramePortData;
     export class GraphCanvasComponent extends React.Component<IGraphCanvasComponentProps> {
         private readonly MinZoom;
         private readonly MaxZoom;
@@ -1438,12 +1443,13 @@ declare module "babylonjs-node-editor/globalState" {
     import { NodeLink } from "babylonjs-node-editor/diagram/nodeLink";
     import { GraphFrame } from "babylonjs-node-editor/diagram/graphFrame";
     import { FrameNodePort } from "babylonjs-node-editor/diagram/frameNodePort";
+    import { FramePortData } from "babylonjs-node-editor/diagram/graphCanvas";
     export class GlobalState {
         nodeMaterial: NodeMaterial;
         hostElement: HTMLElement;
         hostDocument: HTMLDocument;
         hostWindow: Window;
-        onSelectionChangedObservable: Observable<Nullable<GraphNode | NodePort | NodeLink | GraphFrame>>;
+        onSelectionChangedObservable: Observable<Nullable<GraphNode | NodePort | GraphFrame | NodeLink | FramePortData>>;
         onRebuildRequiredObservable: Observable<void>;
         onBuiltObservable: Observable<void>;
         onResetRequiredObservable: Observable<void>;
@@ -1531,16 +1537,18 @@ declare module "babylonjs-node-editor/diagram/properties/framePropertyComponent"
 declare module "babylonjs-node-editor/diagram/properties/frameNodePortPropertyComponent" {
     import * as React from "react";
     import { GlobalState } from "babylonjs-node-editor/globalState";
-    import { FramePortPosition } from "babylonjs-node-editor/diagram/graphFrame";
+    import { GraphFrame } from "babylonjs-node-editor/diagram/graphFrame";
     import { FrameNodePort } from "babylonjs-node-editor/diagram/frameNodePort";
     export interface IFrameNodePortPropertyTabComponentProps {
         globalState: GlobalState;
         frameNodePort: FrameNodePort;
+        frame: GraphFrame;
     }
     export class FrameNodePortPropertyTabComponent extends React.Component<IFrameNodePortPropertyTabComponentProps, {
-        framePortPosition: FramePortPosition;
+        port: FrameNodePort;
     }> {
         private _onFramePortPositionChangedObserver;
+        private _onSelectionChangedObserver;
         constructor(props: IFrameNodePortPropertyTabComponentProps);
         componentWillUnmount(): void;
         render(): JSX.Element;
@@ -1884,24 +1892,22 @@ declare module NODEEDITOR {
     export class FrameNodePort extends NodePort {
         connectionPoint: BABYLON.NodeMaterialConnectionPoint;
         node: GraphNode;
-        private _onFramePortMoveUpObservable;
-        private _onFramePortMoveDownObservable;
-        private _onFramePortPositionChangedObservable;
         private _portLabel;
+        private _parentFrameId;
         private _isInput;
         private _framePortPosition;
         private _framePortId;
-        get onFramePortMoveUpObservable(): BABYLON.Observable<FrameNodePort>;
-        get onFramePortMoveDownObservable(): BABYLON.Observable<FrameNodePort>;
-        get onFramePortPositionChangedObservable(): BABYLON.Observable<FramePortPosition>;
+        private _onFramePortPositionChangedObservable;
+        get parentFrameId(): number;
+        get onFramePortPositionChangedObservable(): BABYLON.Observable<FrameNodePort>;
         get isInput(): boolean;
         get portLabel(): string;
-        get framePortId(): BABYLON.Nullable<number>;
+        get framePortId(): number;
         set portLabel(newLabel: string);
         get framePortPosition(): FramePortPosition;
         set framePortPosition(position: FramePortPosition);
-        constructor(portContainer: HTMLElement, connectionPoint: BABYLON.NodeMaterialConnectionPoint, node: GraphNode, globalState: GlobalState, isInput: boolean, framePortId: number);
-        static CreateFrameNodePortElement(connectionPoint: BABYLON.NodeMaterialConnectionPoint, node: GraphNode, root: HTMLElement, displayManager: BABYLON.Nullable<IDisplayManager>, globalState: GlobalState, isInput: boolean, framePortId: number): FrameNodePort;
+        constructor(portContainer: HTMLElement, connectionPoint: BABYLON.NodeMaterialConnectionPoint, node: GraphNode, globalState: GlobalState, isInput: boolean, framePortId: number, parentFrameId: number);
+        static CreateFrameNodePortElement(connectionPoint: BABYLON.NodeMaterialConnectionPoint, node: GraphNode, root: HTMLElement, displayManager: BABYLON.Nullable<IDisplayManager>, globalState: GlobalState, isInput: boolean, framePortId: number, parentFrameId: number): FrameNodePort;
     }
 }
 declare module NODEEDITOR {
@@ -1984,9 +1990,9 @@ declare module NODEEDITOR {
         private _onUp;
         private _moveFrame;
         private _onMove;
-        private moveFramePortUp;
+        moveFramePortUp(nodePort: FrameNodePort): void;
         private _movePortUp;
-        private moveFramePortDown;
+        moveFramePortDown(nodePort: FrameNodePort): void;
         private _movePortDown;
         private initResizing;
         private cleanUpResizing;
@@ -2047,7 +2053,7 @@ declare module NODEEDITOR {
         protected _img: HTMLImageElement;
         protected _globalState: GlobalState;
         protected _onCandidateLinkMovedObserver: BABYLON.Nullable<BABYLON.Observer<BABYLON.Nullable<BABYLON.Vector2>>>;
-        protected _onSelectionChangedObserver: BABYLON.Nullable<BABYLON.Observer<BABYLON.Nullable<GraphNode | NodeLink | GraphFrame | NodePort | FrameNodePort>>>;
+        protected _onSelectionChangedObserver: BABYLON.Nullable<BABYLON.Observer<BABYLON.Nullable<GraphFrame | GraphNode | NodeLink | NodePort | FramePortData>>>;
         delegatedPort: BABYLON.Nullable<FrameNodePort>;
         get element(): HTMLDivElement;
         refresh(): void;
@@ -2084,6 +2090,11 @@ declare module NODEEDITOR {
     export interface IGraphCanvasComponentProps {
         globalState: GlobalState;
     }
+    export type FramePortData = {
+        frame: GraphFrame;
+        port: FrameNodePort;
+    };
+    export const isFramePortData: (variableToCheck: any) => variableToCheck is FramePortData;
     export class GraphCanvasComponent extends React.Component<IGraphCanvasComponentProps> {
         private readonly MinZoom;
         private readonly MaxZoom;
@@ -2968,7 +2979,7 @@ declare module NODEEDITOR {
         hostElement: HTMLElement;
         hostDocument: HTMLDocument;
         hostWindow: Window;
-        onSelectionChangedObservable: BABYLON.Observable<BABYLON.Nullable<GraphNode | NodePort | NodeLink | GraphFrame>>;
+        onSelectionChangedObservable: BABYLON.Observable<BABYLON.Nullable<GraphNode | NodePort | GraphFrame | NodeLink | FramePortData>>;
         onRebuildRequiredObservable: BABYLON.Observable<void>;
         onBuiltObservable: BABYLON.Observable<void>;
         onResetRequiredObservable: BABYLON.Observable<void>;
@@ -3051,11 +3062,13 @@ declare module NODEEDITOR {
     export interface IFrameNodePortPropertyTabComponentProps {
         globalState: GlobalState;
         frameNodePort: FrameNodePort;
+        frame: GraphFrame;
     }
     export class FrameNodePortPropertyTabComponent extends React.Component<IFrameNodePortPropertyTabComponentProps, {
-        framePortPosition: FramePortPosition;
+        port: FrameNodePort;
     }> {
         private _onFramePortPositionChangedObserver;
+        private _onSelectionChangedObserver;
         constructor(props: IFrameNodePortPropertyTabComponentProps);
         componentWillUnmount(): void;
         render(): JSX.Element;

+ 2 - 2
dist/preview release/nodeEditor/package.json

@@ -4,14 +4,14 @@
     },
     "name": "babylonjs-node-editor",
     "description": "The Babylon.js node material editor.",
-    "version": "4.2.0-alpha.9",
+    "version": "4.2.0-alpha.10",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
     },
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.2.0-alpha.9"
+        "babylonjs": "4.2.0-alpha.10"
     },
     "files": [
         "babylon.nodeEditor.max.js.map",

+ 1 - 1
dist/preview release/package.json

@@ -7,7 +7,7 @@
     ],
     "name": "babylonjs",
     "description": "Babylon.js is a JavaScript 3D engine based on webgl.",
-    "version": "4.2.0-alpha.9",
+    "version": "4.2.0-alpha.10",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 1
dist/preview release/packagesSizeBaseLine.json

@@ -1 +1 @@
-{"thinEngineOnly":114719,"engineOnly":151377,"sceneOnly":508946,"minGridMaterial":641242,"minStandardMaterial":782423}
+{"thinEngineOnly":115611,"engineOnly":152019,"sceneOnly":510028,"minGridMaterial":642324,"minStandardMaterial":783686}

+ 2 - 2
dist/preview release/postProcessesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-post-process",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "4.2.0-alpha.9",
+    "version": "4.2.0-alpha.10",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,7 +28,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.2.0-alpha.9"
+        "babylonjs": "4.2.0-alpha.10"
     },
     "engines": {
         "node": "*"

+ 2 - 2
dist/preview release/proceduralTexturesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-procedural-textures",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "4.2.0-alpha.9",
+    "version": "4.2.0-alpha.10",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,7 +28,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.2.0-alpha.9"
+        "babylonjs": "4.2.0-alpha.10"
     },
     "engines": {
         "node": "*"

+ 3 - 3
dist/preview release/serializers/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-serializers",
     "description": "The Babylon.js serializers library is an extension you can use to serialize Babylon scenes.",
-    "version": "4.2.0-alpha.9",
+    "version": "4.2.0-alpha.10",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,8 +28,8 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.2.0-alpha.9",
-        "babylonjs-gltf2interface": "4.2.0-alpha.9"
+        "babylonjs": "4.2.0-alpha.10",
+        "babylonjs-gltf2interface": "4.2.0-alpha.10"
     },
     "engines": {
         "node": "*"

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 412 - 191
dist/preview release/viewer/babylon.module.d.ts


+ 10 - 5
dist/preview release/what's new.md

@@ -9,7 +9,7 @@
 
 ### General
 
-- Refactored React refs from old string API to React.createRef() API ([Kyle Belfort](https://github.com/belfortk)
+- Refactored React refs from old string API to React.createRef() API ([belfortk](https://github.com/belfortk)
 
 - Scale on one axis for `BoundingBoxGizmo` ([cedricguillemet](https://github.com/cedricguillemet))
 
@@ -23,8 +23,8 @@
 
 ### NME
 
-- Frames are now resizable from the corners ([Kyle Belfort](https://github.com/belfortk)
-- Can now rename and re-order frame inputs and outputs ([Kyle Belfort](https://github.com/belfortk)
+- Frames are now resizable from the corners ([belfortk](https://github.com/belfortk)
+- Can now rename and re-order frame inputs and outputs ([belfortk](https://github.com/belfortk)
 
 ### Inspector
 
@@ -43,6 +43,7 @@
 
 ### Physics
 
+- Fixed time steps or delta time with sub time step for Oimo.js and Cannon.js ([cedricguillemet](https://github.com/cedricguillemet))
 - Ammo.js IDL exposed property update and raycast vehicle stablization support ([MackeyK24](https://github.com/MackeyK24))
 - Recast.js plugin nav mesh and crowd agent to ref performance optimizations. ([MackeyK24](https://github.com/MackeyK24))
 
@@ -72,6 +73,7 @@
 - Implemented the new WebXR HitTest API ([#7364](https://github.com/BabylonJS/Babylon.js/issues/7364)) ([RaananW](https://github.com/RaananW))
 - Playground doesn't update FPS when in XR in main and frame ([#7875](https://github.com/BabylonJS/Babylon.js/issues/7875)) ([RaananW](https://github.com/RaananW))
 - Added support for teleportation using pointer events ([RaananW](https://github.com/RaananW))
+- AR reference space type recommendation changed to 'unbounded' ([#7959](https://github.com/BabylonJS/Babylon.js/issues/7959)) ([RaananW](https://github.com/RaananW))
 
 ### Collisions
 
@@ -90,7 +92,7 @@
 - Fix infinite loop in `GlowLayer.unReferenceMeshFromUsingItsOwnMaterial` ([Popov72](https://github.com/Popov72)
 - Fix picking issue in the Solid Particle System when MultiMaterial is enabled ([jerome](https://github.com/jbousquie))
 - `QuadraticErrorSimplification` was not exported ([RaananW](https://github.com/Raananw)
-- Fix NME Frames bug where collapsing and moving a frame removed the nodes inside ([Kyle Belfort](https://github.com/belfortk)
+- Fix NME Frames bug where collapsing and moving a frame removed the nodes inside ([belfortk](https://github.com/belfortk)
 - Fix moving / disappearing controls when freezing/unfreezing the ScrollViewer ([Popov72](https://github.com/Popov72)
 - Fix: when using instances, master mesh (if displayed) does not have correct instance buffer values ([Popov72](https://github.com/Popov72)
 - Exit XR will only trigger only if state is IN_XR ([RaananW](https://github.com/RaananW))
@@ -117,7 +119,10 @@
 - Fixed error when downloading async createScene function in playground ([#7926](https://github.com/BabylonJS/Babylon.js/issues/7926)) ([RaananW](https://github.com/RaananW))
 - Fix issue where ThinEngine.prototype.createDynamicEngine is undefined when using VideoTexture with es6 packages ([rvadhavk](https://github.com/rvadhavk))
 - Fix [issue](https://forum.babylonjs.com/t/virtualjoystick-needs-to-set-style-touch-action-none-explicitly/9562) that canvas for `VirtualJoystick` does not have `touch-action: "none"` set by default ([joergplewe](https://github.com/joergplewe))
-- Fix [issue](https://github.com/BabylonJS/Babylon.js/issues/7943) that prevented user from re-loading custom meshes
+- Fix [issue](https://github.com/BabylonJS/Babylon.js/issues/7943) that prevented user from re-loading custom meshes([belfortk](https://github.com/belfortk))
+- Fix bug in NME where collapsed frames didn't redraw output links to outside nodes([belfortk](https://github.com/belfortk))
+- Fix bug in NME where links were not redrawn after moving frame port ([belfortk](https://github.com/belfortk))
+- Fix bugs in NME that were causing inconsistent behavior displaying Move Node Up and Down buttons on frame ports([belfortk](https://github.com/belfortk))
 
 ## Breaking changes
 

+ 4 - 4
materialsLibrary/src/custom/customMaterial.ts

@@ -65,7 +65,7 @@ export class CustomMaterial extends StandardMaterial {
     public VertexShader: string;
 
     public AttachAfterBind(mesh: Mesh, effect: Effect) {
-        for (var el in this._newUniformInstances) {
+         for (var el in this._newUniformInstances) {
             var ea = el.toString().split('-');
             if (ea[0] == 'vec2') {
                 effect.setVector2(ea[1], this._newUniformInstances[el]);
@@ -93,14 +93,14 @@ export class CustomMaterial extends StandardMaterial {
 
     public ReviewUniform(name: string, arr: string[]): string[] {
         if (name == "uniform") {
-            for (var ind in this._newUniforms) {
+            for (var ind = 0; ind < this._newUniforms.length ; ind ++) {
                 if (this._customUniform[ind].indexOf('sampler') == -1) {
                     arr.push(this._newUniforms[ind]);
                 }
             }
         }
         if (name == "sampler") {
-            for (var ind in this._newUniforms) {
+            for (var ind = 0; ind < this._newUniforms.length ; ind ++) {
                 if (this._customUniform[ind].indexOf('sampler') != -1) {
                     arr.push(this._newUniforms[ind]);
                 }
@@ -280,4 +280,4 @@ export class CustomMaterial extends StandardMaterial {
     }
 }
 
-_TypeStore.RegisteredTypes["BABYLON.CustomMaterial"] = CustomMaterial;
+_TypeStore.RegisteredTypes["BABYLON.CustomMaterial"] = CustomMaterial;

+ 3 - 3
materialsLibrary/src/custom/pbrCustomMaterial.ts

@@ -89,14 +89,14 @@ export class PBRCustomMaterial extends PBRMaterial {
 
     public ReviewUniform(name: string, arr: string[]): string[] {
         if (name == "uniform") {
-            for (var ind in this._newUniforms) {
+            for (var ind = 0; ind < this._newUniforms.length ; ind ++) {
                 if (this._customUniform[ind].indexOf('sampler') == -1) {
                     arr.push(this._newUniforms[ind]);
                 }
             }
         }
         if (name == "sampler") {
-            for (var ind in this._newUniforms) {
+            for (var ind = 0; ind < this._newUniforms.length ; ind ++) {
                 if (this._customUniform[ind].indexOf('sampler') != -1) {
                     arr.push(this._newUniforms[ind]);
                 }
@@ -288,4 +288,4 @@ export class PBRCustomMaterial extends PBRMaterial {
     }
 }
 
-_TypeStore.RegisteredTypes["BABYLON.PBRCustomMaterial"] = PBRCustomMaterial;
+_TypeStore.RegisteredTypes["BABYLON.PBRCustomMaterial"] = PBRCustomMaterial;

+ 9 - 8
nodeEditor/src/components/propertyTab/propertyTabComponent.tsx

@@ -26,8 +26,9 @@ import { Vector2LineComponent } from '../../sharedComponents/vector2LineComponen
 import { Vector3LineComponent } from '../../sharedComponents/vector3LineComponent';
 import { Vector4LineComponent } from '../../sharedComponents/vector4LineComponent';
 import { Observer } from 'babylonjs/Misc/observable';
-import { FrameNodePort } from '../../diagram/frameNodePort';
 import { NodeMaterial } from 'babylonjs/Materials/Node/nodeMaterial';
+import { FrameNodePort } from '../../diagram/frameNodePort';
+import { isFramePortData } from '../../diagram/graphCanvas';
 require("./propertyTab.scss");
 
 interface IPropertyTabComponentProps {
@@ -49,8 +50,8 @@ export class PropertyTabComponent extends React.Component<IPropertyTabComponentP
                 this.setState({ currentNode: selection, currentFrame: null, currentFrameNodePort: null });
             } else if (selection instanceof GraphFrame) {
                 this.setState({ currentNode: null, currentFrame: selection, currentFrameNodePort: null });
-            } else if(selection instanceof FrameNodePort) {
-                this.setState({ currentNode: null, currentFrame: null, currentFrameNodePort: selection });
+            } else if(isFramePortData(selection)) {
+                this.setState({ currentNode: null, currentFrame: selection.frame, currentFrameNodePort: selection.port });
             } else {
                 this.setState({ currentNode: null, currentFrame: null, currentFrameNodePort: null });
             }
@@ -243,16 +244,16 @@ export class PropertyTabComponent extends React.Component<IPropertyTabComponentP
                 </div>
             );
         }
-
-        if (this.state.currentFrame) {
+        
+        if (this.state.currentFrameNodePort && this.state.currentFrame) {
             return (
-                <FramePropertyTabComponent globalState={this.props.globalState} frame={this.state.currentFrame}/>
+                <FrameNodePortPropertyTabComponent globalState={this.props.globalState} frame={this.state.currentFrame} frameNodePort={this.state.currentFrameNodePort}/>
             );
         }
 
-        if (this.state.currentFrameNodePort) {
+        if (this.state.currentFrame) {
             return (
-                <FrameNodePortPropertyTabComponent globalState={this.props.globalState} frameNodePort={this.state.currentFrameNodePort}/>
+                <FramePropertyTabComponent globalState={this.props.globalState} frame={this.state.currentFrame}/>
             );
         }
 

+ 13 - 15
nodeEditor/src/diagram/frameNodePort.ts

@@ -6,22 +6,18 @@ import { IDisplayManager } from './display/displayManager';
 import { Observable } from 'babylonjs/Misc/observable';
 import { Nullable } from 'babylonjs/types';
 import { NodeMaterialConnectionPoint } from 'babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint';
+import { FramePortData, isFramePortData } from './graphCanvas';
 
 export class FrameNodePort extends NodePort {
-    private _onFramePortMoveUpObservable = new Observable<FrameNodePort>();
-    private _onFramePortMoveDownObservable = new Observable<FrameNodePort>();
-    private _onFramePortPositionChangedObservable = new Observable<FramePortPosition>();
     private _portLabel: Element;
+    private _parentFrameId: number;
     private _isInput: boolean;
     private _framePortPosition: FramePortPosition
-    private _framePortId: Nullable<number>;
+    private _framePortId: number;
+    private _onFramePortPositionChangedObservable = new Observable<FrameNodePort>();
 
-    public get onFramePortMoveUpObservable() {
-        return this._onFramePortMoveUpObservable;
-    }
-
-    public get onFramePortMoveDownObservable() {
-        return this._onFramePortMoveDownObservable;
+    public get parentFrameId () {
+        return this._parentFrameId;
     }
 
     public get onFramePortPositionChangedObservable() {
@@ -50,18 +46,20 @@ export class FrameNodePort extends NodePort {
 
     public set framePortPosition(position: FramePortPosition) {
         this._framePortPosition = position;
-        this.onFramePortPositionChangedObservable.notifyObservers(position);
+        console.log(this.onFramePortPositionChangedObservable.observers);
+        this.onFramePortPositionChangedObservable.notifyObservers(this);
     }
 
-    public constructor(portContainer: HTMLElement, public connectionPoint: NodeMaterialConnectionPoint, public node: GraphNode, globalState: GlobalState, isInput: boolean, framePortId: number) {
+    public constructor(portContainer: HTMLElement, public connectionPoint: NodeMaterialConnectionPoint, public node: GraphNode, globalState: GlobalState, isInput: boolean, framePortId: number, parentFrameId: number) {
         super(portContainer, connectionPoint,node, globalState);
 
+        this._parentFrameId = parentFrameId;
         this._portLabel = portContainer.children[0];
         this._isInput = isInput;
         this._framePortId = framePortId;
 
         this._onSelectionChangedObserver = this._globalState.onSelectionChangedObservable.add((selection) => {
-            if (selection === this) {
+            if (isFramePortData(selection) && (selection as FramePortData).port === this) {
                 this._img.classList.add("selected");
             } else {
                 this._img.classList.remove("selected");
@@ -72,7 +70,7 @@ export class FrameNodePort extends NodePort {
     }
 
     public static CreateFrameNodePortElement(connectionPoint: NodeMaterialConnectionPoint, node: GraphNode, root: HTMLElement, 
-        displayManager: Nullable<IDisplayManager>, globalState: GlobalState, isInput: boolean, framePortId: number) {
+        displayManager: Nullable<IDisplayManager>, globalState: GlobalState, isInput: boolean, framePortId: number, parentFrameId: number) {
         let portContainer = root.ownerDocument!.createElement("div");
         let block = connectionPoint.ownerBlock;
 
@@ -89,7 +87,7 @@ export class FrameNodePort extends NodePort {
             portContainer.appendChild(portLabel);
         }
 
-        return new FrameNodePort(portContainer, connectionPoint, node, globalState, isInput, framePortId);
+        return new FrameNodePort(portContainer, connectionPoint, node, globalState, isInput, framePortId, parentFrameId);
     }
 
 } 

+ 28 - 4
nodeEditor/src/diagram/graphCanvas.tsx

@@ -22,6 +22,18 @@ export interface IGraphCanvasComponentProps {
     globalState: GlobalState
 }
 
+export type FramePortData = {
+    frame: GraphFrame,
+    port: FrameNodePort
+}
+
+export const isFramePortData = (variableToCheck: any): variableToCheck is FramePortData => {
+    if (variableToCheck) {
+        return (variableToCheck as FramePortData).port !== undefined;
+    }
+    else return false;
+}
+
 export class GraphCanvasComponent extends React.Component<IGraphCanvasComponentProps> {
     private readonly MinZoom = 0.1;
     private readonly MaxZoom = 4;
@@ -186,12 +198,16 @@ export class GraphCanvasComponent extends React.Component<IGraphCanvasComponentP
                     } else {                    
                         this._selectedNodes = [selection];
                     }
-                }
-                else {
+                } else if(selection instanceof NodePort){
                     this._selectedNodes = [];
                     this._selectedFrame = null;
                     this._selectedLink = null;
                     this._selectedPort = selection;
+                } else {
+                    this._selectedNodes = [];
+                    this._selectedFrame = null;
+                    this._selectedLink = null;
+                    this._selectedPort = selection.port;
                 }
             }
         });
@@ -599,8 +615,16 @@ export class GraphCanvasComponent extends React.Component<IGraphCanvasComponentP
                 this.processCandidatePort();          
                 this.props.globalState.onCandidateLinkMoved.notifyObservers(null);
             } else { // is a click event on NodePort
-                if(this._candidateLink.portA instanceof FrameNodePort) { //only on Frame Ports
-                    this.props.globalState.onSelectionChangedObservable.notifyObservers(this._candidateLink.portA);
+                if(this._candidateLink.portA instanceof FrameNodePort) { //only on Frame Node Ports
+                    const port = this._candidateLink.portA;
+                    const frame = this.frames.find((frame: GraphFrame) => frame.id === port.parentFrameId);
+                    if (frame) {
+                        const data: FramePortData = {
+                            frame,
+                            port
+                        }
+                        this.props.globalState.onSelectionChangedObservable.notifyObservers(data);
+                    }
                 }
             }
             this._candidateLink.dispose();

+ 83 - 69
nodeEditor/src/diagram/graphFrame.ts

@@ -1,5 +1,5 @@
 import { GraphNode } from './graphNode';
-import { GraphCanvasComponent } from './graphCanvas';
+import { GraphCanvasComponent, FramePortData } from './graphCanvas';
 import { Nullable } from 'babylonjs/types';
 import { Observer, Observable } from 'babylonjs/Misc/observable';
 import { NodeLink } from './nodeLink';
@@ -51,7 +51,7 @@ export class GraphFrame {
     private _ownerCanvas: GraphCanvasComponent;
     private _mouseStartPointX: Nullable<number> = null;
     private _mouseStartPointY: Nullable<number> = null;
-    private _onSelectionChangedObserver: Nullable<Observer<Nullable<GraphNode | NodeLink | GraphFrame | NodePort>>>;
+    private _onSelectionChangedObserver: Nullable<Observer<Nullable<GraphFrame | GraphNode | NodeLink | NodePort | FramePortData>>>;
     private _onGraphNodeRemovalObserver: Nullable<Observer<GraphNode>>; 
     private _isCollapsed = false;
     private _frameInPorts: FrameNodePort[] = [];
@@ -80,18 +80,11 @@ export class GraphFrame {
     }
 
     private _createInputPort(port: NodePort, node: GraphNode) {
-        let localPort = FrameNodePort.CreateFrameNodePortElement(port.connectionPoint, node, this._inputPortContainer, null, this._ownerCanvas.globalState, true, GraphFrame._FramePortCounter++)
+        let localPort = FrameNodePort.CreateFrameNodePortElement(port.connectionPoint, node, this._inputPortContainer, null, this._ownerCanvas.globalState, true, GraphFrame._FramePortCounter++, this.id);
         this._frameInPorts.push(localPort);
 
         port.delegatedPort = localPort;
         this._controlledPorts.push(port);
-        localPort.onFramePortMoveUpObservable.add((nodePort: FrameNodePort) => {
-                this.moveFramePortUp(nodePort);
-        });
-
-        localPort.onFramePortMoveDownObservable.add((nodePort: FrameNodePort) => {
-                this.moveFramePortDown(nodePort);
-        })
     }
 
     public set isCollapsed(value: boolean) {
@@ -120,38 +113,25 @@ export class GraphFrame {
 
                                 if (!portAdded) {
                                     portAdded = true;
-                                    localPort = FrameNodePort.CreateFrameNodePortElement(port.connectionPoint, link.nodeB!, this._outputPortContainer, null, this._ownerCanvas.globalState, false, GraphFrame._FramePortCounter++);
+                                    localPort = FrameNodePort.CreateFrameNodePortElement(port.connectionPoint, link.nodeB!, this._outputPortContainer, null, this._ownerCanvas.globalState, false, GraphFrame._FramePortCounter++, this.id);
                                     this._frameOutPorts.push(localPort);
 
-                                    localPort.onFramePortMoveUpObservable.add((nodePort: FrameNodePort) => {
-                                            this.moveFramePortUp(nodePort);
-                                    });
-                            
-                                    localPort.onFramePortMoveDownObservable.add((nodePort: FrameNodePort) => {
-                                            this.moveFramePortDown(nodePort);
-                                    })
+                                    link.isVisible = true;
+
                                 } else {
                                     localPort = this.ports.filter(p => p.connectionPoint === port.connectionPoint)[0];
                                 }
 
                                 port.delegatedPort = localPort;
                                 this._controlledPorts.push(port);
-                                link.isVisible = false;
                             }
                         }
                     } else {
-                        let localPort = FrameNodePort.CreateFrameNodePortElement(port.connectionPoint, node, this._outputPortContainer, null, this._ownerCanvas.globalState, false, GraphFrame._FramePortCounter++)
+                        let localPort = FrameNodePort.CreateFrameNodePortElement(port.connectionPoint, node, this._outputPortContainer, null, this._ownerCanvas.globalState, false, GraphFrame._FramePortCounter++, this.id);
                         this._frameOutPorts.push(localPort);
                         port.delegatedPort = localPort;
                         this._controlledPorts.push(port);
 
-                        localPort.onFramePortMoveUpObservable.add((nodePort: FrameNodePort) => {
-                                this.moveFramePortUp(nodePort);
-                        });
-                
-                        localPort.onFramePortMoveDownObservable.add((nodePort: FrameNodePort) => {
-                                this.moveFramePortDown(nodePort);
-                        });
                     }
                 }
 
@@ -169,25 +149,37 @@ export class GraphFrame {
                 }
             }
 
-            for(let i = 0; i < this._frameInPorts.length; i++) {
-                const port = this._frameInPorts[i];
-                if(i === 0){
-                    port.framePortPosition = FramePortPosition.Top;
-                } else if(i === this._frameInPorts.length -1){
-                    port.framePortPosition = FramePortPosition.Bottom;
-                } else {
-                    port.framePortPosition = FramePortPosition.Middle;
+            // mark FrameInPorts with position
+            if(this._frameInPorts.length == 2){
+                this._frameInPorts[0].framePortPosition = FramePortPosition.Top;
+                this._frameInPorts[1].framePortPosition = FramePortPosition.Bottom;
+            } else {
+                for(let i = 0; i < this._frameInPorts.length; i++) {
+                    const port = this._frameInPorts[i];
+                    if(i === 0){
+                        port.framePortPosition = FramePortPosition.Top;
+                    } else if(i === this._frameInPorts.length -1){
+                        port.framePortPosition = FramePortPosition.Bottom;
+                    } else {
+                        port.framePortPosition = FramePortPosition.Middle;
+                    }
                 }
             }
 
-            for(let i = 0; i < this._frameOutPorts.length; i++) {
-                const port = this._frameOutPorts[i];
-                if(i === 0){
-                    port.framePortPosition = FramePortPosition.Top
-                } else if(i === this._frameInPorts.length -1){
-                    port.framePortPosition = FramePortPosition.Bottom
-                } else {
-                    port.framePortPosition = FramePortPosition.Middle
+            // mark FrameOutPorts with position
+            if(this._frameOutPorts.length == 2){
+                this._frameOutPorts[0].framePortPosition = FramePortPosition.Top;
+                this._frameOutPorts[1].framePortPosition = FramePortPosition.Bottom;
+            } else {
+                for(let i = 0; i < this._frameOutPorts.length; i++) {
+                    const port = this._frameOutPorts[i];
+                    if(i === 0){
+                        port.framePortPosition = FramePortPosition.Top
+                    } else if(i === this._frameInPorts.length -1){
+                        port.framePortPosition = FramePortPosition.Bottom
+                    } else {
+                        port.framePortPosition = FramePortPosition.Middle
+                    }
                 }
             }
 
@@ -617,24 +609,25 @@ export class GraphFrame {
         evt.stopPropagation();
     }
 
-    private moveFramePortUp(nodePort: FrameNodePort){
+    public moveFramePortUp(nodePort: FrameNodePort){
+        let elementsArray: ChildNode[];
         if(nodePort.isInput) {
             if(this._inputPortContainer.children.length < 2) {
                 return;
             }
-            const elementsArray = Array.from(this._inputPortContainer.childNodes);
-            this._movePortUp(elementsArray, nodePort);
+            elementsArray = Array.from(this._inputPortContainer.childNodes);
+            this._movePortUp(elementsArray, nodePort, this._frameInPorts);
         } else {
             if(this._outputPortContainer.children.length < 2) {
                 return;
             }
-            const elementsArray = Array.from(this._outputPortContainer.childNodes);
-            this._movePortUp(elementsArray, nodePort);
+            elementsArray = Array.from(this._outputPortContainer.childNodes);
+            this._movePortUp(elementsArray, nodePort, this._frameOutPorts);
         }
-
+        this.ports.forEach((framePort: FrameNodePort) => framePort.node._refreshLinks());
     }
 
-    private _movePortUp(elementsArray: ChildNode[], nodePort: FrameNodePort) {
+    private _movePortUp(elementsArray: ChildNode[], nodePort: FrameNodePort, framePortList: FrameNodePort[]) {
         // update UI
         const indexInElementArray = (elementsArray as HTMLElement[]).findIndex(elem => elem.dataset.framePortId === `${nodePort.framePortId}`)
         if(indexInElementArray === 0){
@@ -645,34 +638,47 @@ export class GraphFrame {
         firstPortElement.parentElement?.insertBefore(secondPortElement, firstPortElement);
 
         // update Frame Port Container
-        const indexInContainer = this._frameInPorts.findIndex(framePort => framePort === nodePort);
-        [this._frameInPorts[indexInContainer -1], this._frameInPorts[indexInContainer]] = [this._frameInPorts[indexInContainer], this._frameInPorts[indexInContainer -1]]; // swap idicies
+        const indexInContainer = framePortList.findIndex(framePort => framePort === nodePort);
+        [framePortList[indexInContainer -1], framePortList[indexInContainer]] = [framePortList[indexInContainer], framePortList[indexInContainer -1]]; // swap idicies
         
-        // notify nodePort if it is now at Top (indexInElementArray === 1)
-        if (indexInElementArray === 1) {
-            nodePort.onFramePortPositionChangedObservable.notifyObservers(FramePortPosition.Top);
+        //special case framePortList.length == 2
+        if(framePortList.length == 2) {
+            framePortList[1].framePortPosition = FramePortPosition.Bottom;
+            framePortList[0].framePortPosition = FramePortPosition.Top;
         } else {
-            nodePort.onFramePortPositionChangedObservable.notifyObservers(FramePortPosition.Middle);
+            // notify nodePort if it is now at Top (indexInElementArray === 1)
+            if (indexInElementArray === 1) {
+                framePortList[1].framePortPosition = FramePortPosition.Middle;
+                framePortList[0].framePortPosition = FramePortPosition.Top;
+            } else if(indexInContainer === elementsArray.length-1) {
+                framePortList[framePortList.length -1].framePortPosition = FramePortPosition.Bottom;
+                framePortList[framePortList.length -2].framePortPosition = FramePortPosition.Middle;
+            } else {
+                nodePort.framePortPosition = FramePortPosition.Middle;
+            }
         }
     }
     
-    private moveFramePortDown(nodePort: FrameNodePort){
+    public moveFramePortDown(nodePort: FrameNodePort){
+        let elementsArray: ChildNode[];
         if(nodePort.isInput) {
             if(this._inputPortContainer.children.length < 2) {
                 return;
             }
-            const elementsArray = Array.from(this._inputPortContainer.childNodes);
-            this._movePortDown(elementsArray, nodePort);
+            elementsArray = Array.from(this._inputPortContainer.childNodes);
+            this._movePortDown(elementsArray, nodePort, this._frameInPorts);
         } else {
             if(this._outputPortContainer.children.length < 2) {
                 return;
             }
-            const elementsArray = Array.from(this._outputPortContainer.childNodes);
-            this._movePortDown(elementsArray, nodePort);
+            elementsArray = Array.from(this._outputPortContainer.childNodes);
+            this._movePortDown(elementsArray, nodePort, this._frameOutPorts);
         }
+
+        this.ports.forEach((framePort: FrameNodePort) => framePort.node._refreshLinks());
     }
 
-    private _movePortDown(elementsArray: ChildNode[], nodePort: FrameNodePort) {
+    private _movePortDown(elementsArray: ChildNode[], nodePort: FrameNodePort, framePortList: FrameNodePort[]) {
         // update UI
         const indexInElementArray = (elementsArray as HTMLElement[]).findIndex(elem => elem.dataset.framePortId === `${nodePort.framePortId}`)
         if(indexInElementArray === elementsArray.length -1){
@@ -683,16 +689,24 @@ export class GraphFrame {
         firstPort.parentElement?.insertBefore(secondPort, firstPort);
 
         // update Frame Port Container
-        const indexInContainer = this._frameInPorts.findIndex(framePort => framePort === nodePort);
-        [this._frameInPorts[indexInContainer], this._frameInPorts[indexInContainer + 1]] = [this._frameInPorts[indexInContainer + 1], this._frameInPorts[indexInContainer]]; // swap idicies
+        const indexInContainer = framePortList.findIndex(framePort => framePort === nodePort);
+        [framePortList[indexInContainer], framePortList[indexInContainer + 1]] = [framePortList[indexInContainer + 1], framePortList[indexInContainer]]; // swap idicies
 
         // notify nodePort if it is now at bottom (indexInContainer === elementsArray.length-2)
-        if(indexInContainer === elementsArray.length-2) {
-            nodePort.onFramePortPositionChangedObservable.notifyObservers(FramePortPosition.Bottom);
+        if(framePortList.length == 2) {
+            framePortList[0].framePortPosition = FramePortPosition.Top;
+            framePortList[1].framePortPosition = FramePortPosition.Bottom;
         } else {
-            nodePort.onFramePortPositionChangedObservable.notifyObservers(FramePortPosition.Middle);
-        }
-
+            if(indexInContainer === elementsArray.length-2) {
+                framePortList[elementsArray.length-2].framePortPosition = FramePortPosition.Middle;
+                framePortList[elementsArray.length-1].framePortPosition = FramePortPosition.Bottom;
+            } else if(indexInContainer === 0){
+                framePortList[0].framePortPosition = FramePortPosition.Top;
+                framePortList[1].framePortPosition = FramePortPosition.Middle;
+            } else {
+                nodePort.framePortPosition = FramePortPosition.Middle;
+            }
+         }
     }
 
     private initResizing = (evt: PointerEvent) => {

+ 2 - 2
nodeEditor/src/diagram/graphNode.ts

@@ -3,7 +3,7 @@ import { GlobalState } from '../globalState';
 import { Nullable } from 'babylonjs/types';
 import { Observer } from 'babylonjs/Misc/observable';
 import { NodeMaterialConnectionPoint } from 'babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint';
-import { GraphCanvasComponent } from './graphCanvas';
+import { GraphCanvasComponent, FramePortData } from './graphCanvas';
 import { PropertyLedger } from './propertyLedger';
 import * as React from 'react';
 import { GenericPropertyTabComponent } from './properties/genericNodePropertyComponent';
@@ -31,7 +31,7 @@ export class GraphNode {
     private _mouseStartPointX: Nullable<number> = null;
     private _mouseStartPointY: Nullable<number> = null    
     private _globalState: GlobalState;
-    private _onSelectionChangedObserver: Nullable<Observer<Nullable<GraphNode | NodeLink | GraphFrame | NodePort>>>;   
+    private _onSelectionChangedObserver: Nullable<Observer<Nullable<GraphFrame | GraphNode | NodeLink | NodePort | FramePortData>>>;  
     private _onSelectionBoxMovedObserver: Nullable<Observer<ClientRect | DOMRect>>;  
     private _onFrameCreatedObserver: Nullable<Observer<GraphFrame>>; 
     private _onUpdateRequiredObserver: Nullable<Observer<void>>;  

+ 2 - 2
nodeEditor/src/diagram/nodeLink.ts

@@ -1,4 +1,4 @@
-import { GraphCanvasComponent } from './graphCanvas';
+import { GraphCanvasComponent, FramePortData } from './graphCanvas';
 import { GraphNode } from './graphNode';
 import { NodePort } from './nodePort';
 import { Nullable } from 'babylonjs/types';
@@ -14,7 +14,7 @@ export class NodeLink {
     private _nodeB?: GraphNode;
     private _path: SVGPathElement;
     private _selectionPath: SVGPathElement;
-    private _onSelectionChangedObserver: Nullable<Observer<Nullable<GraphNode | NodeLink | GraphFrame | NodePort>>>;
+    private _onSelectionChangedObserver: Nullable<Observer<Nullable<GraphFrame | GraphNode | NodeLink | NodePort | FramePortData>>>;  
     private _isVisible = true;
 
     public onDisposedObservable = new Observable<NodeLink>();

+ 2 - 1
nodeEditor/src/diagram/nodePort.ts

@@ -10,13 +10,14 @@ import { GraphNode } from './graphNode';
 import { NodeLink } from './nodeLink';
 import { GraphFrame } from './graphFrame';
 import { FrameNodePort } from './frameNodePort';
+import { FramePortData } from './graphCanvas';
 
 export class NodePort {
     protected _element: HTMLDivElement;
     protected _img: HTMLImageElement;
     protected _globalState: GlobalState;
     protected _onCandidateLinkMovedObserver: Nullable<Observer<Nullable<Vector2>>>;
-    protected _onSelectionChangedObserver: Nullable<Observer<Nullable<GraphNode | NodeLink | GraphFrame | NodePort | FrameNodePort>>>;  
+    protected _onSelectionChangedObserver: Nullable<Observer<Nullable<GraphFrame | GraphNode | NodeLink | NodePort | FramePortData>>>;  
     
     public delegatedPort: Nullable<FrameNodePort> = null;
 

+ 45 - 26
nodeEditor/src/diagram/properties/frameNodePortPropertyComponent.tsx

@@ -4,56 +4,75 @@ import { LineContainerComponent } from '../../sharedComponents/lineContainerComp
 import { GlobalState } from '../../globalState';
 import { TextInputLineComponent } from '../../sharedComponents/textInputLineComponent';
 import { ButtonLineComponent } from '../../sharedComponents/buttonLineComponent';
-import { FramePortPosition } from '../graphFrame';
+import { FramePortPosition, GraphFrame } from '../graphFrame';
 import { Nullable } from 'babylonjs/types';
 import { Observer } from 'babylonjs/Misc/observable';
 import { FrameNodePort } from '../frameNodePort';
+import { NodePort } from '../nodePort';
+import { GraphNode } from '../graphNode';
+import { NodeLink } from '../nodeLink';
+import { FramePortData, isFramePortData } from '../graphCanvas';
 
 export interface IFrameNodePortPropertyTabComponentProps {
     globalState: GlobalState
     frameNodePort: FrameNodePort;
+    frame: GraphFrame;
 }
 
-export class FrameNodePortPropertyTabComponent extends React.Component<IFrameNodePortPropertyTabComponentProps, {framePortPosition: FramePortPosition}> {    
-    private _onFramePortPositionChangedObserver: Nullable<Observer<FramePortPosition>>;
+export class FrameNodePortPropertyTabComponent extends React.Component<IFrameNodePortPropertyTabComponentProps, { port: FrameNodePort }> {
+    private _onFramePortPositionChangedObserver: Nullable<Observer<FrameNodePort>>;
+    private _onSelectionChangedObserver: Nullable<Observer<Nullable<GraphFrame | NodePort | GraphNode | NodeLink | FramePortData>>>;
 
     constructor(props: IFrameNodePortPropertyTabComponentProps) {
         super(props);
         this.state = {
-            framePortPosition: this.props.frameNodePort.framePortPosition
-        };
+            port: this.props.frameNodePort
+        }
 
-        this._onFramePortPositionChangedObserver = this.props.frameNodePort.onFramePortPositionChangedObservable.add((position) => {
-            this.setState({framePortPosition: position})
+        const _this = this;
+        this._onSelectionChangedObserver = this.props.globalState.onSelectionChangedObservable.add((selection) => {
+            if (isFramePortData(selection)) {
+                selection.port.onFramePortPositionChangedObservable.clear();
+                _this._onFramePortPositionChangedObserver = selection.port.onFramePortPositionChangedObservable.add((port: FrameNodePort) => {
+                    _this.setState({ port: port });
+                });
+
+                _this.setState({ port: selection.port });
+            }
+        });
+
+        this._onFramePortPositionChangedObserver = this.props.frameNodePort.onFramePortPositionChangedObservable.add((port: FrameNodePort) => {
+            _this.setState({ port: port });
         });
     }
 
     componentWillUnmount() {
-        this.props.frameNodePort.onFramePortPositionChangedObservable.remove(this._onFramePortPositionChangedObserver)
+        this.props.frameNodePort.onFramePortPositionChangedObservable.remove(this._onFramePortPositionChangedObserver);
+        this.props.globalState.onSelectionChangedObservable.remove(this._onSelectionChangedObserver);
     }
 
-    render() {      
+    render() {
         return (
             <div id="propertyTab">
-            <div id="header">
-                <img id="logo" src="https://www.babylonjs.com/Assets/logo-babylonjs-social-twitter.png" />
-                <div id="title">
-                    NODE MATERIAL EDITOR
+                <div id="header">
+                    <img id="logo" src="https://www.babylonjs.com/Assets/logo-babylonjs-social-twitter.png" />
+                    <div id="title">
+                        NODE MATERIAL EDITOR
+                </div>
+                </div>
+                <div>
+                    <LineContainerComponent title="GENERAL">
+                        <TextInputLineComponent globalState={this.props.globalState} label="Port Label" propertyName="portLabel" target={this.props.frameNodePort} />
+                        {this.props.frameNodePort.framePortPosition !== FramePortPosition.Top && <ButtonLineComponent label="Move Port Up" onClick={() => {
+                            this.props.frame.moveFramePortUp(this.props.frameNodePort);
+                        }} />}
+
+                        {this.props.frameNodePort.framePortPosition !== FramePortPosition.Bottom && <ButtonLineComponent label="Move Port Down" onClick={() => {
+                            this.props.frame.moveFramePortDown(this.props.frameNodePort);
+                        }} />}
+                    </LineContainerComponent>
                 </div>
             </div>
-            <div>
-                <LineContainerComponent title="GENERAL">
-                    <TextInputLineComponent globalState={this.props.globalState} label="Port Label" propertyName="portLabel" target={this.props.frameNodePort}/>
-                     {this.state.framePortPosition !== FramePortPosition.Top && <ButtonLineComponent label="Move Node Up" onClick={() => {
-                                this.props.frameNodePort.onFramePortMoveUpObservable.notifyObservers(this.props.frameNodePort);
-                            }} />}
-
-                    {this.state.framePortPosition !== FramePortPosition.Bottom && <ButtonLineComponent label="Move Node Down" onClick={() => {
-                                this.props.frameNodePort.onFramePortMoveDownObservable.notifyObservers(this.props.frameNodePort);
-                            }} />}
-                </LineContainerComponent>
-            </div>
-        </div>
         );
     }
 }

+ 2 - 1
nodeEditor/src/globalState.ts

@@ -12,13 +12,14 @@ import { NodePort } from './diagram/nodePort';
 import { NodeLink } from './diagram/nodeLink';
 import { GraphFrame } from './diagram/graphFrame';
 import { FrameNodePort } from './diagram/frameNodePort';
+import { FramePortData } from './diagram/graphCanvas';
 
 export class GlobalState {
     nodeMaterial: NodeMaterial;
     hostElement: HTMLElement;
     hostDocument: HTMLDocument;
     hostWindow: Window;
-    onSelectionChangedObservable = new Observable<Nullable<GraphNode | NodeLink | GraphFrame | NodePort>>();
+    onSelectionChangedObservable = new Observable<Nullable<GraphNode | NodeLink | GraphFrame | NodePort | FramePortData>>();
     onRebuildRequiredObservable = new Observable<void>();
     onBuiltObservable = new Observable<void>();
     onResetRequiredObservable = new Observable<void>();

+ 2 - 2
package.json

@@ -7,7 +7,7 @@
     ],
     "name": "babylonjs",
     "description": "Babylon.js is a JavaScript 3D engine based on webgl.",
-    "version": "4.2.0-alpha.9",
+    "version": "4.2.0-alpha.10",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -109,4 +109,4 @@
         "react-color": "^2.18.0",
         "@types/react-color": "^3.0.1"
     }
-}
+}

+ 2 - 0
src/Culling/ray.ts

@@ -34,6 +34,7 @@ export class Ray {
     // Methods
     /**
      * Checks if the ray intersects a box
+     * This does not account for the ray lenght by design to improve perfs.
      * @param minimum bound of the box
      * @param maximum bound of the box
      * @param intersectionTreshold extra extend to be added to the box in all direction
@@ -135,6 +136,7 @@ export class Ray {
 
     /**
      * Checks if the ray intersects a box
+     * This does not account for the ray lenght by design to improve perfs.
      * @param box the bounding box to check
      * @param intersectionTreshold extra extend to be added to the BoundingBox in all direction
      * @returns if the box was hit

+ 46 - 16
src/Engines/Extensions/engine.rawTexture.ts

@@ -4,11 +4,11 @@ import { Logger } from '../../Misc/logger';
 import { Tools } from '../../Misc/tools';
 import { Scene } from '../../scene';
 import { Constants } from '../constants';
-import { Engine } from '../engine';
+import { ThinEngine } from '../thinEngine';
 import { IWebRequest } from '../../Misc/interfaces/iWebRequest';
 
-declare module "../../Engines/engine" {
-    export interface Engine {
+declare module "../../Engines/thinEngine" {
+    export interface ThinEngine {
         /**
          * Creates a raw texture
          * @param data defines the data to store in the texture
@@ -209,7 +209,7 @@ declare module "../../Engines/engine" {
     }
 }
 
-Engine.prototype.updateRawTexture = function(texture: Nullable<InternalTexture>, data: Nullable<ArrayBufferView>, format: number, invertY: boolean, compression: Nullable<string> = null, type: number = Constants.TEXTURETYPE_UNSIGNED_INT): void {
+ThinEngine.prototype.updateRawTexture = function(texture: Nullable<InternalTexture>, data: Nullable<ArrayBufferView>, format: number, invertY: boolean, compression: Nullable<string> = null, type: number = Constants.TEXTURETYPE_UNSIGNED_INT): void {
     if (!texture) {
         return;
     }
@@ -248,7 +248,7 @@ Engine.prototype.updateRawTexture = function(texture: Nullable<InternalTexture>,
     texture.isReady = true;
 };
 
-Engine.prototype.createRawTexture = function(data: Nullable<ArrayBufferView>, width: number, height: number, format: number, generateMipMaps: boolean, invertY: boolean, samplingMode: number, compression: Nullable<string> = null, type: number = Constants.TEXTURETYPE_UNSIGNED_INT): InternalTexture {
+ThinEngine.prototype.createRawTexture = function(data: Nullable<ArrayBufferView>, width: number, height: number, format: number, generateMipMaps: boolean, invertY: boolean, samplingMode: number, compression: Nullable<string> = null, type: number = Constants.TEXTURETYPE_UNSIGNED_INT): InternalTexture {
     var texture = new InternalTexture(this, InternalTextureSource.Raw);
     texture.baseWidth = width;
     texture.baseHeight = height;
@@ -285,7 +285,7 @@ Engine.prototype.createRawTexture = function(data: Nullable<ArrayBufferView>, wi
     return texture;
 };
 
-Engine.prototype.createRawCubeTexture = function(data: Nullable<ArrayBufferView[]>, size: number, format: number, type: number,
+ThinEngine.prototype.createRawCubeTexture = function(data: Nullable<ArrayBufferView[]>, size: number, format: number, type: number,
     generateMipMaps: boolean, invertY: boolean, samplingMode: number,
     compression: Nullable<string> = null): InternalTexture {
     var gl = this._gl;
@@ -361,7 +361,7 @@ Engine.prototype.createRawCubeTexture = function(data: Nullable<ArrayBufferView[
     return texture;
 };
 
-Engine.prototype.updateRawCubeTexture = function(texture: InternalTexture, data: ArrayBufferView[], format: number, type: number, invertY: boolean, compression: Nullable<string> = null, level: number = 0): void {
+ThinEngine.prototype.updateRawCubeTexture = function(texture: InternalTexture, data: ArrayBufferView[], format: number, type: number, invertY: boolean, compression: Nullable<string> = null, level: number = 0): void {
     texture._bufferViewArray = data;
     texture.format = format;
     texture.type = type;
@@ -394,7 +394,7 @@ Engine.prototype.updateRawCubeTexture = function(texture: InternalTexture, data:
             gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, (<any>(this.getCaps().s3tc))[compression], texture.width, texture.height, 0, <DataView>faceData);
         } else {
             if (needConversion) {
-                faceData = this._convertRGBtoRGBATextureData(faceData, texture.width, texture.height, type);
+                faceData = _convertRGBtoRGBATextureData(faceData, texture.width, texture.height, type);
             }
             gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, internalSizedFomat, texture.width, texture.height, 0, internalFormat, textureType, faceData);
         }
@@ -410,7 +410,7 @@ Engine.prototype.updateRawCubeTexture = function(texture: InternalTexture, data:
     texture.isReady = true;
 };
 
-Engine.prototype.createRawCubeTextureFromUrl = function(url: string, scene: Scene, size: number, format: number, type: number, noMipmap: boolean,
+ThinEngine.prototype.createRawCubeTextureFromUrl = function(url: string, scene: Scene, size: number, format: number, type: number, noMipmap: boolean,
     callback: (ArrayBuffer: ArrayBuffer) => Nullable<ArrayBufferView[]>,
     mipmapGenerator: Nullable<((faces: ArrayBufferView[]) => ArrayBufferView[][])>,
     onLoad: Nullable<() => void> = null,
@@ -460,7 +460,7 @@ Engine.prototype.createRawCubeTextureFromUrl = function(url: string, scene: Scen
                 for (var faceIndex = 0; faceIndex < 6; faceIndex++) {
                     let mipFaceData = mipData[level][faceIndex];
                     if (needConversion) {
-                        mipFaceData = this._convertRGBtoRGBATextureData(mipFaceData, mipSize, mipSize, type);
+                        mipFaceData = _convertRGBtoRGBATextureData(mipFaceData, mipSize, mipSize, type);
                     }
                     gl.texImage2D(faceIndex, level, internalSizedFomat, mipSize, mipSize, 0, internalFormat, textureType, mipFaceData);
                 }
@@ -488,13 +488,43 @@ Engine.prototype.createRawCubeTextureFromUrl = function(url: string, scene: Scen
     return texture;
 };
 
+/** @hidden */
+function _convertRGBtoRGBATextureData(rgbData: any, width: number, height: number, textureType: number): ArrayBufferView {
+    // Create new RGBA data container.
+    var rgbaData: any;
+    if (textureType === Constants.TEXTURETYPE_FLOAT) {
+        rgbaData = new Float32Array(width * height * 4);
+    }
+    else {
+        rgbaData = new Uint32Array(width * height * 4);
+    }
+
+    // Convert each pixel.
+    for (let x = 0; x < width; x++) {
+        for (let y = 0; y < height; y++) {
+            let index = (y * width + x) * 3;
+            let newIndex = (y * width + x) * 4;
+
+            // Map Old Value to new value.
+            rgbaData[newIndex + 0] = rgbData[index + 0];
+            rgbaData[newIndex + 1] = rgbData[index + 1];
+            rgbaData[newIndex + 2] = rgbData[index + 2];
+
+            // Add fully opaque alpha channel.
+            rgbaData[newIndex + 3] = 1;
+        }
+    }
+
+    return rgbaData;
+}
+
 /**
  * Create a function for createRawTexture3D/createRawTexture2DArray
  * @param is3D true for TEXTURE_3D and false for TEXTURE_2D_ARRAY
  * @hidden
  */
 function _makeCreateRawTextureFunction(is3D: boolean) {
-    return function(this: Engine, data: Nullable<ArrayBufferView>, width: number, height: number, depth: number, format: number, generateMipMaps: boolean, invertY: boolean, samplingMode: number, compression: Nullable<string> = null, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT): InternalTexture {
+    return function(this: ThinEngine, data: Nullable<ArrayBufferView>, width: number, height: number, depth: number, format: number, generateMipMaps: boolean, invertY: boolean, samplingMode: number, compression: Nullable<string> = null, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT): InternalTexture {
         var target = is3D ? this._gl.TEXTURE_3D : this._gl.TEXTURE_2D_ARRAY;
         var source = is3D ? InternalTextureSource.Raw3D : InternalTextureSource.Raw2DArray;
         var texture = new InternalTexture(this, source);
@@ -543,8 +573,8 @@ function _makeCreateRawTextureFunction(is3D: boolean) {
     };
 }
 
-Engine.prototype.createRawTexture2DArray = _makeCreateRawTextureFunction(false);
-Engine.prototype.createRawTexture3D = _makeCreateRawTextureFunction(true);
+ThinEngine.prototype.createRawTexture2DArray = _makeCreateRawTextureFunction(false);
+ThinEngine.prototype.createRawTexture3D = _makeCreateRawTextureFunction(true);
 
 /**
  * Create a function for updateRawTexture3D/updateRawTexture2DArray
@@ -552,7 +582,7 @@ Engine.prototype.createRawTexture3D = _makeCreateRawTextureFunction(true);
  * @hidden
  */
 function _makeUpdateRawTextureFunction(is3D: boolean) {
-    return function(this: Engine, texture: InternalTexture, data: Nullable<ArrayBufferView>, format: number, invertY: boolean, compression: Nullable<string> = null, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT): void {
+    return function(this: ThinEngine, texture: InternalTexture, data: Nullable<ArrayBufferView>, format: number, invertY: boolean, compression: Nullable<string> = null, textureType: number = Constants.TEXTURETYPE_UNSIGNED_INT): void {
         var target = is3D ? this._gl.TEXTURE_3D : this._gl.TEXTURE_2D_ARRAY;
         var internalType = this._getWebGLTextureType(textureType);
         var internalFormat = this._getInternalFormat(format);
@@ -587,5 +617,5 @@ function _makeUpdateRawTextureFunction(is3D: boolean) {
     };
 }
 
-Engine.prototype.updateRawTexture2DArray = _makeUpdateRawTextureFunction(false);
-Engine.prototype.updateRawTexture3D = _makeUpdateRawTextureFunction(true);
+ThinEngine.prototype.updateRawTexture2DArray = _makeUpdateRawTextureFunction(false);
+ThinEngine.prototype.updateRawTexture3D = _makeUpdateRawTextureFunction(true);

+ 0 - 30
src/Engines/engine.ts

@@ -1167,36 +1167,6 @@ export class Engine extends ThinEngine {
         this._bindTexture(channel, postProcess ? postProcess._outputTexture : null);
     }
 
-    /** @hidden */
-    public _convertRGBtoRGBATextureData(rgbData: any, width: number, height: number, textureType: number): ArrayBufferView {
-        // Create new RGBA data container.
-        var rgbaData: any;
-        if (textureType === Constants.TEXTURETYPE_FLOAT) {
-            rgbaData = new Float32Array(width * height * 4);
-        }
-        else {
-            rgbaData = new Uint32Array(width * height * 4);
-        }
-
-        // Convert each pixel.
-        for (let x = 0; x < width; x++) {
-            for (let y = 0; y < height; y++) {
-                let index = (y * width + x) * 3;
-                let newIndex = (y * width + x) * 4;
-
-                // Map Old Value to new value.
-                rgbaData[newIndex + 0] = rgbData[index + 0];
-                rgbaData[newIndex + 1] = rgbData[index + 1];
-                rgbaData[newIndex + 2] = rgbData[index + 2];
-
-                // Add fully opaque alpha channel.
-                rgbaData[newIndex + 3] = 1;
-            }
-        }
-
-        return rgbaData;
-    }
-
     protected _rebuildBuffers(): void {
         // Index / Vertex
         for (var scene of this.scenes) {

+ 2 - 2
src/Engines/thinEngine.ts

@@ -132,14 +132,14 @@ export class ThinEngine {
      */
     // Not mixed with Version for tooling purpose.
     public static get NpmPackage(): string {
-        return "babylonjs@4.2.0-alpha.9";
+        return "babylonjs@4.2.0-alpha.10";
     }
 
     /**
      * Returns the current version of the framework
      */
     public static get Version(): string {
-        return "4.2.0-alpha.9";
+        return "4.2.0-alpha.10";
     }
 
     /**

+ 58 - 24
src/Materials/Textures/colorGradingTexture.ts

@@ -1,11 +1,14 @@
 import { Nullable } from "../../types";
 import { Scene } from "../../scene";
 import { Matrix } from "../../Maths/math.vector";
-import { Engine } from "../../Engines/engine";
 import { InternalTexture } from "../../Materials/Textures/internalTexture";
 import { BaseTexture } from "../../Materials/Textures/baseTexture";
 import { Constants } from "../../Engines/constants";
-import { _TypeStore } from '../../Misc/typeStore';
+import { _TypeStore } from "../../Misc/typeStore";
+import { ThinEngine } from "../../Engines/thinEngine";
+
+// Ensures Raw texture are included
+import "../../Engines/Extensions/engine.rawTexture";
 
 /**
  * This represents a color grading texture. This acts as a lookup table LUT, useful during post process
@@ -17,11 +20,6 @@ import { _TypeStore } from '../../Misc/typeStore';
  */
 export class ColorGradingTexture extends BaseTexture {
     /**
-     * The current texture matrix. (will always be identity in color grading texture)
-     */
-    private _textureMatrix: Matrix;
-
-    /**
      * The texture URL.
      */
     public url: string;
@@ -31,43 +29,60 @@ export class ColorGradingTexture extends BaseTexture {
      */
     private static _noneEmptyLineRegex = /\S+/;
 
-    private _engine: Engine;
+    private _textureMatrix: Matrix;
+    private _engine: ThinEngine;
+    private _onLoad: Nullable<() => void>;
 
     /**
      * Instantiates a ColorGradingTexture from the following parameters.
      *
      * @param url The location of the color gradind data (currently only supporting 3dl)
-     * @param scene The scene the texture will be used in
+     * @param sceneOrEngine The scene or engine the texture will be used in
+     * @param onLoad defines a callback triggered when the texture has been loaded
      */
-    constructor(url: string, scene: Scene) {
-        super(scene);
+    constructor(url: string, sceneOrEngine: Scene | ThinEngine, onLoad: Nullable<() => void> = null) {
+        const isScene = ColorGradingTexture._isScene(sceneOrEngine);
+        super(isScene ? (sceneOrEngine as Scene) : null);
 
         if (!url) {
             return;
         }
 
-        this._engine = scene.getEngine();
         this._textureMatrix = Matrix.Identity();
         this.name = url;
         this.url = url;
-        this.hasAlpha = false;
-        this.isCube = false;
-        this.is3D = this._engine.webGLVersion > 1;
-        this.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;
-        this.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;
-        this.wrapR = Constants.TEXTURE_CLAMP_ADDRESSMODE;
-
-        this.anisotropicFilteringLevel = 1;
+        this._onLoad = onLoad;
 
         this._texture = this._getFromCache(url, true);
 
         if (!this._texture) {
-            if (!scene.useDelayedTextureLoading) {
+            if (ColorGradingTexture._isScene(sceneOrEngine)) {
+                this._engine = sceneOrEngine.getEngine();
+
+                if (!sceneOrEngine.useDelayedTextureLoading) {
+                    this.loadTexture();
+                } else {
+                    this.delayLoadState = Constants.DELAYLOADSTATE_NOTLOADED;
+                }
+            }
+            else {
+                this._engine = sceneOrEngine;
                 this.loadTexture();
-            } else {
-                this.delayLoadState = Constants.DELAYLOADSTATE_NOTLOADED;
             }
         }
+        else {
+            this._engine = this._texture.getEngine();
+            this._triggerOnLoad();
+        }
+    }
+
+    /**
+     * Fires the onload event from the constructor if requested.
+     */
+    private _triggerOnLoad(): void {
+        if (this._onLoad) {
+            this._onLoad();
+        }
     }
 
     /**
@@ -82,7 +97,7 @@ export class ColorGradingTexture extends BaseTexture {
      * Occurs when the file being loaded is a .3dl LUT file.
      */
     private load3dlTexture() {
-        var engine = this._engine as Engine;
+        var engine = this._engine as ThinEngine;
         var texture: InternalTexture;
         if (engine.webGLVersion === 1) {
             texture = engine.createRawTexture(null, 1, 1, Constants.TEXTUREFORMAT_RGBA, false, false, Constants.TEXTURE_BILINEAR_SAMPLINGMODE, null, Constants.TEXTURETYPE_UNSIGNED_INT);
@@ -92,6 +107,14 @@ export class ColorGradingTexture extends BaseTexture {
         }
 
         this._texture = texture;
+        this._texture.isReady = false;
+
+        this.isCube = false;
+        this.is3D = this._engine.webGLVersion > 1;
+        this.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;
+        this.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;
+        this.wrapR = Constants.TEXTURE_CLAMP_ADDRESSMODE;
+        this.anisotropicFilteringLevel = 1;
 
         var callback = (text: string | ArrayBuffer) => {
 
@@ -187,6 +210,9 @@ export class ColorGradingTexture extends BaseTexture {
                 texture.updateSize(size * size, size);
                 engine.updateRawTexture(texture, data, Constants.TEXTUREFORMAT_RGBA, false);
             }
+
+            texture.isReady = true;
+            this._triggerOnLoad();
         };
 
         let scene = this.getScene();
@@ -269,6 +295,14 @@ export class ColorGradingTexture extends BaseTexture {
 
         return serializationObject;
     }
+
+    /**
+     * Returns true if the passed parameter is a scene object (can be use for typings)
+     * @param sceneOrEngine The object to test.
+     */
+    private static _isScene(sceneOrEngine: Scene | ThinEngine): sceneOrEngine is Scene {
+        return sceneOrEngine.getClassName() === "Scene";
+    }
 }
 
 _TypeStore.RegisteredTypes["BABYLON.ColorGradingTexture"] = ColorGradingTexture;

+ 2 - 0
src/Meshes/transformNode.ts

@@ -520,6 +520,8 @@ export class TransformNode extends Node {
             this.position.y = absolutePositionY;
             this.position.z = absolutePositionZ;
         }
+
+        this._absolutePosition.copyFrom(absolutePosition);
         return this;
     }
 

+ 1 - 1
src/Physics/Plugins/cannonJSPlugin.ts

@@ -54,7 +54,7 @@ export class CannonJSPlugin implements IPhysicsEnginePlugin {
     }
 
     public executeStep(delta: number): void {
-        this.world.step(this._fixedTimeStep, this._useDeltaForWorldStep ? delta : 0, 3);
+        this.world.step(this._useDeltaForWorldStep ? delta : this._fixedTimeStep);
         this._removeMarkedPhysicsBodiesFromWorld();
     }
 

+ 3 - 1
src/Physics/Plugins/oimoJSPlugin.ts

@@ -17,8 +17,9 @@ export class OimoJSPlugin implements IPhysicsEnginePlugin {
     public name: string = "OimoJSPlugin";
     public BJSOIMO: any;
     private _raycastResult: PhysicsRaycastResult;
+    private _fixedTimeStep: number = 1 / 60;
 
-    constructor(iterations?: number, oimoInjection = OIMO) {
+    constructor(private _useDeltaForWorldStep: boolean = true, iterations?: number, oimoInjection = OIMO) {
         this.BJSOIMO = oimoInjection;
         this.world = new this.BJSOIMO.World({
             iterations: iterations
@@ -47,6 +48,7 @@ export class OimoJSPlugin implements IPhysicsEnginePlugin {
             impostor.beforeStep();
         });
 
+        this.world.timeStep = this._useDeltaForWorldStep ? delta : this._fixedTimeStep;
         this.world.step();
 
         impostors.forEach((impostor) => {

+ 6 - 2
src/PostProcesses/imageProcessingPostProcess.ts

@@ -10,7 +10,6 @@ import { ImageProcessingConfiguration, IImageProcessingConfigurationDefines } fr
 import { PostProcess, PostProcessOptions } from "./postProcess";
 import { Engine } from "../Engines/engine";
 import { EngineStore } from "../Engines/engineStore";
-import { Scene } from "../scene";
 import { Constants } from "../Engines/constants";
 
 import "../Shaders/imageProcessing.fragment";
@@ -82,7 +81,12 @@ export class ImageProcessingPostProcess extends PostProcess {
                 scene = EngineStore.LastCreatedScene;
             }
 
-            this._imageProcessingConfiguration = (<Scene>scene).imageProcessingConfiguration;
+            if (scene) {
+                this._imageProcessingConfiguration = scene.imageProcessingConfiguration;
+            }
+            else {
+                this._imageProcessingConfiguration = new ImageProcessingConfiguration();
+            }
         }
         else {
             this._imageProcessingConfiguration = configuration;

+ 3 - 3
src/XR/webXRExperienceHelper.ts

@@ -101,9 +101,9 @@ export class WebXRExperienceHelper implements IDisposable {
         let sessionCreationOptions: XRSessionInit = {
             optionalFeatures: (referenceSpaceType !== "viewer" && referenceSpaceType !== "local") ? [referenceSpaceType] : []
         };
-        // we currently recommend "local" space in AR
-        if (sessionMode === "immersive-ar" && referenceSpaceType !== "local") {
-            Logger.Warn("We recommend using 'local' reference space type when using 'immersive-ar' session mode");
+        // we currently recommend "unbounded" space in AR (#7959)
+        if (sessionMode === "immersive-ar" && referenceSpaceType !== "unbounded") {
+            Logger.Warn("We recommend using 'unbounded' reference space type when using 'immersive-ar' session mode");
         }
         // make sure that the session mode is supported
         return this.sessionManager.isSessionSupportedAsync(sessionMode).then((supported) => {