David Catuhe 6 年之前
父节点
当前提交
7915dc8bdd

+ 12 - 1
Playground/babylon.d.txt

@@ -40166,6 +40166,14 @@ declare module BABYLON {
          */
         onNewMeshSelected: Observable<AbstractMesh>;
         /**
+         * Observable raised when a new mesh is selected based on meshSelectionPredicate.
+         * This observable will provide the mesh and the controller used to select the mesh
+         */
+        onMeshSelectedWithController: Observable<{
+            mesh: AbstractMesh;
+            controller: WebVRController;
+        }>;
+        /**
          * Observable raised when a new mesh is picked based on meshSelectionPredicate
          */
         onNewMeshPicked: Observable<PickingInfo>;
@@ -51922,7 +51930,7 @@ declare module BABYLON {
         /**
          * Gets a boolean indicating that the current point is connected to an input block
          */
-        readonly isConnectedToInput: boolean;
+        readonly isConnectedToInputBlock: boolean;
         /**
          * Gets a the connected input block (if any)
          */
@@ -51937,6 +51945,8 @@ declare module BABYLON {
         readonly connectedBlocks: Array<NodeMaterialBlock>;
         /** Gets the list of connected endpoints */
         readonly endpoints: NodeMaterialConnectionPoint[];
+        /** Gets a boolean indicating if that output point is connected to at least one input */
+        readonly hasEndpoints: boolean;
         /**
          * Creates a new connection point
          * @param name defines the connection point name
@@ -58088,6 +58098,7 @@ declare module BABYLON {
         private _motionStrength;
         private _isObjectBasedMotionBlur;
         private _floatTextureType;
+        private _camerasToBeAttached;
         private _ratio;
         private _bloomEnabled;
         private _depthOfFieldEnabled;

+ 12 - 1
dist/preview release/babylon.d.ts

@@ -40882,6 +40882,14 @@ declare module BABYLON {
          */
         onNewMeshSelected: Observable<AbstractMesh>;
         /**
+         * Observable raised when a new mesh is selected based on meshSelectionPredicate.
+         * This observable will provide the mesh and the controller used to select the mesh
+         */
+        onMeshSelectedWithController: Observable<{
+            mesh: AbstractMesh;
+            controller: WebVRController;
+        }>;
+        /**
          * Observable raised when a new mesh is picked based on meshSelectionPredicate
          */
         onNewMeshPicked: Observable<PickingInfo>;
@@ -52732,7 +52740,7 @@ declare module BABYLON {
         /**
          * Gets a boolean indicating that the current point is connected to an input block
          */
-        readonly isConnectedToInput: boolean;
+        readonly isConnectedToInputBlock: boolean;
         /**
          * Gets a the connected input block (if any)
          */
@@ -52747,6 +52755,8 @@ declare module BABYLON {
         readonly connectedBlocks: Array<NodeMaterialBlock>;
         /** Gets the list of connected endpoints */
         readonly endpoints: NodeMaterialConnectionPoint[];
+        /** Gets a boolean indicating if that output point is connected to at least one input */
+        readonly hasEndpoints: boolean;
         /**
          * Creates a new connection point
          * @param name defines the connection point name
@@ -58945,6 +58955,7 @@ declare module BABYLON {
         private _motionStrength;
         private _isObjectBasedMotionBlur;
         private _floatTextureType;
+        private _camerasToBeAttached;
         private _ratio;
         private _bloomEnabled;
         private _depthOfFieldEnabled;

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/babylon.js


+ 39 - 9
dist/preview release/babylon.max.js

@@ -17564,6 +17564,11 @@ var VRExperienceHelper = /** @class */ (function () {
          */
         this.onNewMeshSelected = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
         /**
+         * Observable raised when a new mesh is selected based on meshSelectionPredicate.
+         * This observable will provide the mesh and the controller used to select the mesh
+         */
+        this.onMeshSelectedWithController = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
+        /**
          * Observable raised when a new mesh is picked based on meshSelectionPredicate
          */
         this.onNewMeshPicked = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
@@ -19022,9 +19027,13 @@ var VRExperienceHelper = /** @class */ (function () {
                     }
                     try {
                         this.onNewMeshSelected.notifyObservers(hit.pickedMesh);
+                        var gazerAsControllerGazer = gazer;
+                        if (gazerAsControllerGazer.webVRController) {
+                            this.onMeshSelectedWithController.notifyObservers({ mesh: hit.pickedMesh, controller: gazerAsControllerGazer.webVRController });
+                        }
                     }
                     catch (err) {
-                        _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("Error in your custom logic onNewMeshSelected: " + err);
+                        _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("Error while raising onNewMeshSelected or onMeshSelectedWithController: " + err);
                     }
                 }
                 else {
@@ -59517,9 +59526,11 @@ var LightBlock = /** @class */ (function (_super) {
         var diffuseOutput = this.diffuseOutput;
         var specularOutput = this.specularOutput;
         state.compilationString += this._declareOutput(diffuseOutput, state) + " = diffuseBase;\r\n";
-        state.compilationString += "#ifdef SPECULARTERM\r\n";
-        state.compilationString += this._declareOutput(specularOutput, state) + " = specularBase;\r\n";
-        state.compilationString += "#endif\r\n";
+        if (specularOutput.hasEndpoints) {
+            state.compilationString += "#ifdef SPECULARTERM\r\n";
+            state.compilationString += this._declareOutput(specularOutput, state) + " = specularBase;\r\n";
+            state.compilationString += "#endif\r\n";
+        }
         return this;
     };
     LightBlock.prototype.serialize = function () {
@@ -65124,7 +65135,7 @@ var NodeMaterialConnectionPoint = /** @class */ (function () {
         enumerable: true,
         configurable: true
     });
-    Object.defineProperty(NodeMaterialConnectionPoint.prototype, "isConnectedToInput", {
+    Object.defineProperty(NodeMaterialConnectionPoint.prototype, "isConnectedToInputBlock", {
         /**
          * Gets a boolean indicating that the current point is connected to an input block
          */
@@ -65139,7 +65150,7 @@ var NodeMaterialConnectionPoint = /** @class */ (function () {
          * Gets a the connected input block (if any)
          */
         get: function () {
-            if (!this.isConnectedToInput) {
+            if (!this.isConnectedToInputBlock) {
                 return null;
             }
             return this.connectedPoint.ownerBlock;
@@ -65188,7 +65199,15 @@ var NodeMaterialConnectionPoint = /** @class */ (function () {
     Object.defineProperty(NodeMaterialConnectionPoint.prototype, "endpoints", {
         /** Gets the list of connected endpoints */
         get: function () {
-            return this, this._endpoints;
+            return this._endpoints;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(NodeMaterialConnectionPoint.prototype, "hasEndpoints", {
+        /** Gets a boolean indicating if that output point is connected to at least one input */
+        get: function () {
+            return this._endpoints && this._endpoints.length > 0;
         },
         enumerable: true,
         configurable: true
@@ -73366,7 +73385,7 @@ var CubeTexture = /** @class */ (function (_super) {
             if (parsedTexture.prefiltered) {
                 prefiltered = parsedTexture.prefiltered;
             }
-            return new CubeTexture(rootUrl + parsedTexture.name, scene, parsedTexture.extensions, false, null, null, null, undefined, prefiltered);
+            return new CubeTexture(rootUrl + parsedTexture.name, scene, parsedTexture.extensions, false, parsedTexture.files || null, null, null, undefined, prefiltered);
         }, parsedTexture, scene);
         // Local Cubemaps
         if (parsedTexture.boundingBoxPosition) {
@@ -73410,6 +73429,9 @@ var CubeTexture = /** @class */ (function (_super) {
         Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("rotationY")
     ], CubeTexture.prototype, "rotationY", null);
     tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
+        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("files")
+    ], CubeTexture.prototype, "_files", void 0);
+    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
         Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsMatrix"])("textureMatrix")
     ], CubeTexture.prototype, "_textureMatrix", void 0);
     return CubeTexture;
@@ -141684,6 +141706,7 @@ var StandardRenderingPipeline = /** @class */ (function (_super) {
         _this._hdrCurrentLuminance = 1.0;
         _this._motionStrength = 1.0;
         _this._isObjectBasedMotionBlur = false;
+        _this._camerasToBeAttached = [];
         // Getters and setters
         _this._bloomEnabled = false;
         _this._depthOfFieldEnabled = false;
@@ -141695,7 +141718,9 @@ var StandardRenderingPipeline = /** @class */ (function (_super) {
         _this._motionBlurSamples = 64.0;
         _this._volumetricLightStepsCount = 50.0;
         _this._samples = 1;
-        _this._cameras = cameras || [];
+        _this._cameras = cameras || scene.cameras;
+        _this._cameras = _this._cameras.slice();
+        _this._camerasToBeAttached = _this._cameras.slice();
         // Initialize
         _this._scene = scene;
         _this._basePostProcess = originalPostProcess;
@@ -141979,6 +142004,11 @@ var StandardRenderingPipeline = /** @class */ (function (_super) {
         var ratio = this._ratio;
         var scene = this._scene;
         this._disposePostProcesses();
+        if (this._cameras !== null) {
+            this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
+            // get back cameras to be used to reattach pipeline
+            this._cameras = this._camerasToBeAttached.slice();
+        }
         this._reset();
         // Create pass post-process
         if (!this._basePostProcess) {

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/babylon.max.js.map


+ 24 - 2
dist/preview release/babylon.module.d.ts

@@ -42297,6 +42297,14 @@ declare module "babylonjs/Cameras/VR/vrExperienceHelper" {
          */
         onNewMeshSelected: Observable<AbstractMesh>;
         /**
+         * Observable raised when a new mesh is selected based on meshSelectionPredicate.
+         * This observable will provide the mesh and the controller used to select the mesh
+         */
+        onMeshSelectedWithController: Observable<{
+            mesh: AbstractMesh;
+            controller: WebVRController;
+        }>;
+        /**
          * Observable raised when a new mesh is picked based on meshSelectionPredicate
          */
         onNewMeshPicked: Observable<PickingInfo>;
@@ -55195,7 +55203,7 @@ declare module "babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint" {
         /**
          * Gets a boolean indicating that the current point is connected to an input block
          */
-        readonly isConnectedToInput: boolean;
+        readonly isConnectedToInputBlock: boolean;
         /**
          * Gets a the connected input block (if any)
          */
@@ -55210,6 +55218,8 @@ declare module "babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint" {
         readonly connectedBlocks: Array<NodeMaterialBlock>;
         /** Gets the list of connected endpoints */
         readonly endpoints: NodeMaterialConnectionPoint[];
+        /** Gets a boolean indicating if that output point is connected to at least one input */
+        readonly hasEndpoints: boolean;
         /**
          * Creates a new connection point
          * @param name defines the connection point name
@@ -62000,6 +62010,7 @@ declare module "babylonjs/PostProcesses/RenderPipeline/Pipelines/standardRenderi
         private _motionStrength;
         private _isObjectBasedMotionBlur;
         private _floatTextureType;
+        private _camerasToBeAttached;
         private _ratio;
         private _bloomEnabled;
         private _depthOfFieldEnabled;
@@ -105452,6 +105463,14 @@ declare module BABYLON {
          */
         onNewMeshSelected: Observable<AbstractMesh>;
         /**
+         * Observable raised when a new mesh is selected based on meshSelectionPredicate.
+         * This observable will provide the mesh and the controller used to select the mesh
+         */
+        onMeshSelectedWithController: Observable<{
+            mesh: AbstractMesh;
+            controller: WebVRController;
+        }>;
+        /**
          * Observable raised when a new mesh is picked based on meshSelectionPredicate
          */
         onNewMeshPicked: Observable<PickingInfo>;
@@ -117302,7 +117321,7 @@ declare module BABYLON {
         /**
          * Gets a boolean indicating that the current point is connected to an input block
          */
-        readonly isConnectedToInput: boolean;
+        readonly isConnectedToInputBlock: boolean;
         /**
          * Gets a the connected input block (if any)
          */
@@ -117317,6 +117336,8 @@ declare module BABYLON {
         readonly connectedBlocks: Array<NodeMaterialBlock>;
         /** Gets the list of connected endpoints */
         readonly endpoints: NodeMaterialConnectionPoint[];
+        /** Gets a boolean indicating if that output point is connected to at least one input */
+        readonly hasEndpoints: boolean;
         /**
          * Creates a new connection point
          * @param name defines the connection point name
@@ -123515,6 +123536,7 @@ declare module BABYLON {
         private _motionStrength;
         private _isObjectBasedMotionBlur;
         private _floatTextureType;
+        private _camerasToBeAttached;
         private _ratio;
         private _bloomEnabled;
         private _depthOfFieldEnabled;

+ 12 - 1
dist/preview release/documentation.d.ts

@@ -40882,6 +40882,14 @@ declare module BABYLON {
          */
         onNewMeshSelected: Observable<AbstractMesh>;
         /**
+         * Observable raised when a new mesh is selected based on meshSelectionPredicate.
+         * This observable will provide the mesh and the controller used to select the mesh
+         */
+        onMeshSelectedWithController: Observable<{
+            mesh: AbstractMesh;
+            controller: WebVRController;
+        }>;
+        /**
          * Observable raised when a new mesh is picked based on meshSelectionPredicate
          */
         onNewMeshPicked: Observable<PickingInfo>;
@@ -52732,7 +52740,7 @@ declare module BABYLON {
         /**
          * Gets a boolean indicating that the current point is connected to an input block
          */
-        readonly isConnectedToInput: boolean;
+        readonly isConnectedToInputBlock: boolean;
         /**
          * Gets a the connected input block (if any)
          */
@@ -52747,6 +52755,8 @@ declare module BABYLON {
         readonly connectedBlocks: Array<NodeMaterialBlock>;
         /** Gets the list of connected endpoints */
         readonly endpoints: NodeMaterialConnectionPoint[];
+        /** Gets a boolean indicating if that output point is connected to at least one input */
+        readonly hasEndpoints: boolean;
         /**
          * Creates a new connection point
          * @param name defines the connection point name
@@ -58945,6 +58955,7 @@ declare module BABYLON {
         private _motionStrength;
         private _isObjectBasedMotionBlur;
         private _floatTextureType;
+        private _camerasToBeAttached;
         private _ratio;
         private _bloomEnabled;
         private _depthOfFieldEnabled;

+ 24 - 2
dist/preview release/viewer/babylon.module.d.ts

@@ -42297,6 +42297,14 @@ declare module "babylonjs/Cameras/VR/vrExperienceHelper" {
          */
         onNewMeshSelected: Observable<AbstractMesh>;
         /**
+         * Observable raised when a new mesh is selected based on meshSelectionPredicate.
+         * This observable will provide the mesh and the controller used to select the mesh
+         */
+        onMeshSelectedWithController: Observable<{
+            mesh: AbstractMesh;
+            controller: WebVRController;
+        }>;
+        /**
          * Observable raised when a new mesh is picked based on meshSelectionPredicate
          */
         onNewMeshPicked: Observable<PickingInfo>;
@@ -55195,7 +55203,7 @@ declare module "babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint" {
         /**
          * Gets a boolean indicating that the current point is connected to an input block
          */
-        readonly isConnectedToInput: boolean;
+        readonly isConnectedToInputBlock: boolean;
         /**
          * Gets a the connected input block (if any)
          */
@@ -55210,6 +55218,8 @@ declare module "babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint" {
         readonly connectedBlocks: Array<NodeMaterialBlock>;
         /** Gets the list of connected endpoints */
         readonly endpoints: NodeMaterialConnectionPoint[];
+        /** Gets a boolean indicating if that output point is connected to at least one input */
+        readonly hasEndpoints: boolean;
         /**
          * Creates a new connection point
          * @param name defines the connection point name
@@ -62000,6 +62010,7 @@ declare module "babylonjs/PostProcesses/RenderPipeline/Pipelines/standardRenderi
         private _motionStrength;
         private _isObjectBasedMotionBlur;
         private _floatTextureType;
+        private _camerasToBeAttached;
         private _ratio;
         private _bloomEnabled;
         private _depthOfFieldEnabled;
@@ -105452,6 +105463,14 @@ declare module BABYLON {
          */
         onNewMeshSelected: Observable<AbstractMesh>;
         /**
+         * Observable raised when a new mesh is selected based on meshSelectionPredicate.
+         * This observable will provide the mesh and the controller used to select the mesh
+         */
+        onMeshSelectedWithController: Observable<{
+            mesh: AbstractMesh;
+            controller: WebVRController;
+        }>;
+        /**
          * Observable raised when a new mesh is picked based on meshSelectionPredicate
          */
         onNewMeshPicked: Observable<PickingInfo>;
@@ -117302,7 +117321,7 @@ declare module BABYLON {
         /**
          * Gets a boolean indicating that the current point is connected to an input block
          */
-        readonly isConnectedToInput: boolean;
+        readonly isConnectedToInputBlock: boolean;
         /**
          * Gets a the connected input block (if any)
          */
@@ -117317,6 +117336,8 @@ declare module BABYLON {
         readonly connectedBlocks: Array<NodeMaterialBlock>;
         /** Gets the list of connected endpoints */
         readonly endpoints: NodeMaterialConnectionPoint[];
+        /** Gets a boolean indicating if that output point is connected to at least one input */
+        readonly hasEndpoints: boolean;
         /**
          * Creates a new connection point
          * @param name defines the connection point name
@@ -123515,6 +123536,7 @@ declare module BABYLON {
         private _motionStrength;
         private _isObjectBasedMotionBlur;
         private _floatTextureType;
+        private _camerasToBeAttached;
         private _ratio;
         private _bloomEnabled;
         private _depthOfFieldEnabled;

文件差异内容过多而无法显示
+ 5 - 5
dist/preview release/viewer/babylon.viewer.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


+ 12 - 1
src/Cameras/VR/vrExperienceHelper.ts

@@ -271,6 +271,7 @@ class VRExperienceHelperCameraGazer extends VRExperienceHelperGazer {
     constructor(private getCamera: () => Nullable<Camera>, scene: Scene) {
         super(scene);
     }
+
     _getForwardRay(length: number): Ray {
         var camera = this.getCamera();
         if (camera) {
@@ -406,6 +407,12 @@ export class VRExperienceHelper {
     public onNewMeshSelected = new Observable<AbstractMesh>();
 
     /**
+     * Observable raised when a new mesh is selected based on meshSelectionPredicate.
+     * This observable will provide the mesh and the controller used to select the mesh
+     */
+    public onMeshSelectedWithController = new Observable<{mesh: AbstractMesh, controller: WebVRController}>();
+
+    /**
      * Observable raised when a new mesh is picked based on meshSelectionPredicate
      */
     public onNewMeshPicked = new Observable<PickingInfo>();
@@ -1970,9 +1977,13 @@ export class VRExperienceHelper {
                     }
                     try {
                         this.onNewMeshSelected.notifyObservers(hit.pickedMesh);
+                        let gazerAsControllerGazer = gazer as VRExperienceHelperControllerGazer;
+                        if (gazerAsControllerGazer.webVRController) {
+                            this.onMeshSelectedWithController.notifyObservers({mesh: hit.pickedMesh, controller: gazerAsControllerGazer.webVRController});
+                        }
                     }
                     catch (err) {
-                        Logger.Warn("Error in your custom logic onNewMeshSelected: " + err);
+                        Logger.Warn("Error while raising onNewMeshSelected or onMeshSelectedWithController: " + err);
                     }
                 }
                 else {

+ 5 - 3
src/Materials/Node/Blocks/Dual/lightBlock.ts

@@ -262,9 +262,11 @@ export class LightBlock extends NodeMaterialBlock {
         let specularOutput = this.specularOutput;
 
         state.compilationString += this._declareOutput(diffuseOutput, state) + ` = diffuseBase;\r\n`;
-        state.compilationString += `#ifdef SPECULARTERM\r\n`;
-        state.compilationString += this._declareOutput(specularOutput, state) + ` = specularBase;\r\n`;
-        state.compilationString += `#endif\r\n`;
+        if (specularOutput.hasEndpoints) {
+            state.compilationString += `#ifdef SPECULARTERM\r\n`;
+            state.compilationString += this._declareOutput(specularOutput, state) + ` = specularBase;\r\n`;
+            state.compilationString += `#endif\r\n`;
+        }
 
         return this;
     }

+ 1 - 1
src/Materials/Node/Blocks/Dual/reflectionTextureBlock.ts

@@ -361,7 +361,7 @@ export class ReflectionTextureBlock extends NodeMaterialBlock {
         state.compilationString += `#endif\r\n`;
 
         for (var output of this._outputs) {
-            if (output.connectedBlocks.length) {
+            if (output.hasEndpoints) {
                 this._writeOutput(state, output, output.name);
             }
         }

+ 1 - 1
src/Materials/Node/Blocks/Dual/textureBlock.ts

@@ -227,7 +227,7 @@ export class TextureBlock extends NodeMaterialBlock {
         state._emitUniformFromString(this._textureInfoName, "float");
 
         for (var output of this._outputs) {
-            if (output.connectedBlocks.length) {
+            if (output.hasEndpoints) {
                 this._writeOutput(state, output, output.name);
             }
         }

+ 2 - 2
src/Materials/Node/Blocks/colorMergerBlock.ts

@@ -86,9 +86,9 @@ export class ColorMergerBlock extends NodeMaterialBlock {
         let color4Output = this._outputs[0];
         let color3Output = this._outputs[1];
 
-        if (color4Output.endpoints.length) {
+        if (color4Output.hasEndpoints) {
             state.compilationString += this._declareOutput(color4Output, state) + ` = vec4(${this._writeVariable(rInput)}, ${this._writeVariable(gInput)}, ${this._writeVariable(bInput)}, ${aInput.isConnected ? this._writeVariable(aInput) : "0.0"});\r\n`;
-        } else if (color3Output.endpoints.length) {
+        } else if (color3Output.hasEndpoints) {
             state.compilationString += this._declareOutput(color3Output, state) + ` = vec3(${this._writeVariable(rInput)}, ${this._writeVariable(gInput)}, ${this._writeVariable(bInput)});\r\n`;
         }
 

+ 5 - 5
src/Materials/Node/Blocks/colorSplitterBlock.ts

@@ -93,19 +93,19 @@ export class ColorSplitterBlock extends NodeMaterialBlock {
         let bOutput = this._outputs[3];
         let aOutput = this._outputs[4];
 
-        if (rgbOutput.connectedBlocks.length > 0) {
+        if (rgbOutput.hasEndpoints) {
             state.compilationString += this._declareOutput(rgbOutput, state) + ` = ${input.associatedVariableName}.rgb;\r\n`;
         }
-        if (rOutput.connectedBlocks.length > 0) {
+        if (rOutput.hasEndpoints) {
             state.compilationString += this._declareOutput(rOutput, state) + ` = ${input.associatedVariableName}.r;\r\n`;
         }
-        if (gOutput.connectedBlocks.length > 0) {
+        if (gOutput.hasEndpoints) {
             state.compilationString += this._declareOutput(gOutput, state) + ` = ${input.associatedVariableName}.g;\r\n`;
         }
-        if (bOutput.connectedBlocks.length > 0) {
+        if (bOutput.hasEndpoints) {
             state.compilationString += this._declareOutput(bOutput, state) + ` = ${input.associatedVariableName}.b;\r\n`;
         }
-        if (aOutput.connectedBlocks.length > 0) {
+        if (aOutput.hasEndpoints) {
             state.compilationString += this._declareOutput(aOutput, state) + ` = ${input.associatedVariableName}.a;\r\n`;
         }
 

+ 3 - 3
src/Materials/Node/Blocks/vectorMergerBlock.ts

@@ -95,11 +95,11 @@ export class VectorMergerBlock extends NodeMaterialBlock {
         let v3Output = this._outputs[1];
         let v2Output = this._outputs[2];
 
-        if (v4Output.endpoints.length) {
+        if (v4Output.hasEndpoints) {
             state.compilationString += this._declareOutput(v4Output, state) + ` = vec4(${this._writeVariable(xInput)}, ${this._writeVariable(yInput)}, ${zInput.isConnected ? this._writeVariable(zInput) : "0.0"}, ${zInput.isConnected ? this._writeVariable(wInput) : "0.0"});\r\n`;
-        } else if (v3Output.endpoints.length) {
+        } else if (v3Output.hasEndpoints) {
             state.compilationString += this._declareOutput(v3Output, state) + ` = vec3(${this._writeVariable(xInput)}, ${this._writeVariable(yInput)}, ${zInput.isConnected ? this._writeVariable(zInput) : "0.0"});\r\n`;
-        } else if (v2Output.endpoints.length) {
+        } else if (v2Output.hasEndpoints) {
             state.compilationString += this._declareOutput(v2Output, state) + ` = vec2(${this._writeVariable(xInput)}, ${this._writeVariable(yInput)});\r\n`;
         }
 

+ 6 - 6
src/Materials/Node/Blocks/vectorSplitterBlock.ts

@@ -111,26 +111,26 @@ export class VectorSplitterBlock extends NodeMaterialBlock {
         let zOutput = this._outputs[4];
         let wOutput = this._outputs[5];
 
-        if (xyzOutput.connectedBlocks.length > 0) {
+        if (xyzOutput.hasEndpoints) {
             if (input === this.xyIn) {
                 state.compilationString += this._declareOutput(xyzOutput, state) + ` = vec3(${input.associatedVariableName}, 0.0);\r\n`;
             } else {
                 state.compilationString += this._declareOutput(xyzOutput, state) + ` = ${input.associatedVariableName}.xyz;\r\n`;
             }
         }
-        if (xyOutput.connectedBlocks.length > 0) {
+        if (xyOutput.hasEndpoints) {
             state.compilationString += this._declareOutput(xyOutput, state) + ` = ${input.associatedVariableName}.xy;\r\n`;
         }
-        if (xOutput.connectedBlocks.length > 0) {
+        if (xOutput.hasEndpoints) {
             state.compilationString += this._declareOutput(xOutput, state) + ` = ${input.associatedVariableName}.x;\r\n`;
         }
-        if (yOutput.connectedBlocks.length > 0) {
+        if (yOutput.hasEndpoints) {
             state.compilationString += this._declareOutput(yOutput, state) + ` = ${input.associatedVariableName}.y;\r\n`;
         }
-        if (zOutput.connectedBlocks.length > 0) {
+        if (zOutput.hasEndpoints) {
             state.compilationString += this._declareOutput(zOutput, state) + ` = ${input.associatedVariableName}.z;\r\n`;
         }
-        if (wOutput.connectedBlocks.length > 0) {
+        if (wOutput.hasEndpoints) {
             state.compilationString += this._declareOutput(wOutput, state) + ` = ${input.associatedVariableName}.w;\r\n`;
         }
 

+ 29 - 0
src/Materials/Node/nodeMaterial.ts

@@ -253,6 +253,21 @@ export class NodeMaterial extends PushMaterial {
     }
 
     /**
+     * Get a block by its name
+     * @param name defines the name of the block to retrieve
+     * @returns the required block or null if not found
+     */
+    public getBlockByName(name: string) {
+        for (var block of this.attachedBlocks) {
+            if (block.name === name) {
+                return block;
+            }
+        }
+
+        return null;
+    }
+
+    /**
      * Adds a new optimizer to the list of optimizers
      * @param optimizer defines the optimizers to add
      * @returns the current material
@@ -1035,6 +1050,20 @@ export class NodeMaterial extends PushMaterial {
 
         return nodeMaterial;
     }
+
+    /**
+     * Creates a new node material set to default basic configuration
+     * @param name defines the name of the material
+     * @param scene defines the hosting scene
+     * @returns a new NodeMaterial
+     */
+    public static CreateDefault(name: string, scene?: Scene) {
+        let newMaterial = new NodeMaterial(name, scene);
+        newMaterial.setToDefault();
+        newMaterial.build();
+
+        return newMaterial;
+    }
 }
 
 _TypeStore.RegisteredTypes["BABYLON.NodeMaterial"] = NodeMaterial;

+ 8 - 3
src/Materials/Node/nodeMaterialBlockConnectionPoint.ts

@@ -102,7 +102,7 @@ export class NodeMaterialConnectionPoint {
     /**
      * Gets a boolean indicating that the current point is connected to an input block
      */
-    public get isConnectedToInput(): boolean {
+    public get isConnectedToInputBlock(): boolean {
         return this.connectedPoint !== null && this.connectedPoint.ownerBlock.isInput;
     }
 
@@ -110,7 +110,7 @@ export class NodeMaterialConnectionPoint {
      * Gets a the connected input block (if any)
      */
     public get connectInputBlock(): Nullable<InputBlock> {
-        if (!this.isConnectedToInput) {
+        if (!this.isConnectedToInputBlock) {
             return null;
         }
 
@@ -147,7 +147,12 @@ export class NodeMaterialConnectionPoint {
 
     /** Gets the list of connected endpoints */
     public get endpoints() {
-        return this, this._endpoints;
+        return this._endpoints;
+    }
+
+    /** Gets a boolean indicating if that output point is connected to at least one input */
+    public get hasEndpoints(): boolean {
+        return this._endpoints && this._endpoints.length > 0;
     }
 
     /**

+ 1 - 1
tests/validation/validation.js

@@ -185,7 +185,7 @@ function runTest(index, done) {
 
     var title = document.createElement("div");
     title.className = "title";
-    titleContainer.appendChild(title);
+    titleContainer.appendChild("#" + index + "> " + title);
 
     var result = document.createElement("div");
     result.className = "result";