瀏覽代碼

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

Conflicts:
	Tools/BuildOurOwnBabylonJS/BuildOurOwnBabylonJS/babylonJS.xml
michael-korbas 11 年之前
父節點
當前提交
80baae9af9

+ 101 - 0
Babylon/Cameras/babylon.anaglyphCamera.js

@@ -0,0 +1,101 @@
+"use strict";
+
+var BABYLON = BABYLON || {};
+
+(function () {
+    // Common
+    var buildCamera = function (that, name) {
+        that._leftCamera.isIntermediate = true;
+
+        that.subCameras.push(that._leftCamera);
+        that.subCameras.push(that._rightCamera);
+
+        that._leftTexture = new BABYLON.PassPostProcess(name + "_leftTexture", 1.0, that._leftCamera);
+        that._anaglyphPostProcess = new BABYLON.AnaglyphPostProcess(name + "_anaglyph", 1.0, that._rightCamera);
+
+        that._anaglyphPostProcess.onApply = function(effect) {
+            effect.setTextureFromPostProcess("leftSampler", that._leftTexture);
+        };
+
+        that._update();
+    };
+
+    // ArcRotate
+    BABYLON.AnaglyphArcRotateCamera = function (name, alpha, beta, radius, target, eyeSpace, scene) {
+        BABYLON.ArcRotateCamera.call(this, name, alpha, beta, radius, target, scene);
+
+        this._eyeSpace = BABYLON.Tools.ToRadians(eyeSpace);
+
+        this._leftCamera = new BABYLON.ArcRotateCamera(name + "_left", alpha - this._eyeSpace, beta, radius, target, scene);
+        this._rightCamera = new BABYLON.ArcRotateCamera(name + "_right", alpha + this._eyeSpace, beta, radius, target, scene);
+
+        buildCamera(this, name);
+    };
+
+    BABYLON.AnaglyphArcRotateCamera.prototype = Object.create(BABYLON.ArcRotateCamera.prototype);
+
+    BABYLON.AnaglyphArcRotateCamera.prototype._update = function () {
+        this._updateCamera(this._leftCamera);
+        this._updateCamera(this._rightCamera);
+
+        this._leftCamera.alpha = this.alpha - this._eyeSpace;
+        this._rightCamera.alpha = this.alpha + this._eyeSpace;
+
+        BABYLON.ArcRotateCamera.prototype._update.call(this);
+    };
+
+    BABYLON.AnaglyphArcRotateCamera.prototype._updateCamera = function (camera) {
+        camera.beta = this.beta;
+        camera.radius = this.radius;
+
+        camera.minZ = this.minZ;
+        camera.maxZ = this.maxZ;
+
+        camera.fov = this.fov;
+
+        camera.target = this.target;
+    };
+
+    // FreeCamera
+    BABYLON.AnaglyphFreeCamera = function (name, position, eyeSpace, scene) {
+        BABYLON.FreeCamera.call(this, name, position, scene);
+
+        this._eyeSpace = BABYLON.Tools.ToRadians(eyeSpace);
+        this._transformMatrix = new BABYLON.Matrix();
+
+        this._leftCamera = new BABYLON.FreeCamera(name + "_left", position, scene);
+        this._rightCamera = new BABYLON.FreeCamera(name + "_right", position, scene);
+
+        buildCamera(this, name, eyeSpace);
+    };
+
+    BABYLON.AnaglyphFreeCamera.prototype = Object.create(BABYLON.FreeCamera.prototype);
+
+    BABYLON.AnaglyphFreeCamera.prototype._getSubCameraPosition = function(eyeSpace, result) {
+        var target = this.getTarget();
+        BABYLON.Matrix.Translation(-target.x, -target.y, -target.z).multiplyToRef(BABYLON.Matrix.RotationY(eyeSpace), this._transformMatrix);
+
+        this._transformMatrix = this._transformMatrix.multiply(BABYLON.Matrix.Translation(target.x, target.y, target.z));
+
+        BABYLON.Vector3.TransformCoordinatesToRef(this.position, this._transformMatrix, result);
+    };
+
+    BABYLON.AnaglyphFreeCamera.prototype._update = function () {
+        this._getSubCameraPosition(-this._eyeSpace, this._leftCamera.position);
+        this._getSubCameraPosition(this._eyeSpace, this._rightCamera.position);
+
+        this._updateCamera(this._leftCamera);
+        this._updateCamera(this._rightCamera);
+
+        BABYLON.FreeCamera.prototype._update.call(this);
+    };
+
+    BABYLON.AnaglyphFreeCamera.prototype._updateCamera = function (camera) {
+        camera.minZ = this.minZ;
+        camera.maxZ = this.maxZ;
+
+        camera.fov = this.fov;
+
+        camera.setTarget(this.getTarget());
+    };
+})();

+ 6 - 2
Babylon/Cameras/babylon.camera.js

@@ -8,7 +8,7 @@ var BABYLON = BABYLON || {};
         
         this.name = name;
         this.id = name;
-        this.position = position;
+        this.position = position.clone();
         this.upVector = BABYLON.Vector3.Up();
 
         scene.cameras.push(this);
@@ -20,6 +20,9 @@ var BABYLON = BABYLON || {};
         this._computedViewMatrix = BABYLON.Matrix.Identity();
         this._projectionMatrix = new BABYLON.Matrix();
 
+        // Sub-cameras
+        this.subCameras = [];
+
         // Animations
         this.animations = [];
 
@@ -50,6 +53,7 @@ var BABYLON = BABYLON || {};
     BABYLON.Camera.prototype.maxZ = 1000.0;
     BABYLON.Camera.prototype.inertia = 0.9;
     BABYLON.Camera.prototype.mode = BABYLON.Camera.PERSPECTIVE_CAMERA;
+    BABYLON.Camera.prototype.isIntermediate = false;
 
     // Properties
     BABYLON.Camera.prototype.getScene = function () {
@@ -290,10 +294,10 @@ var BABYLON = BABYLON || {};
     
     BABYLON.Camera.prototype._computeViewMatrix = function (force) {
         if (!force && this._isSynchronizedViewMatrix()) {
-            this._currentRenderId = this._scene.getRenderId();
             return this._computedViewMatrix;
         }
 
+        this._currentRenderId = this._scene.getRenderId();
         this._computedViewMatrix = this._getViewMatrix();
         return this._computedViewMatrix;
     };

+ 4 - 0
Babylon/Cameras/babylon.freeCamera.js

@@ -132,6 +132,10 @@ var BABYLON = BABYLON || {};
         }
     };
 
+    BABYLON.FreeCamera.prototype.getTarget = function () {
+        return this._currentTarget;
+    };
+
     // Controls
     BABYLON.FreeCamera.prototype.attachControl = function (canvas, noPreventDefault) {
         var previousPosition;

+ 30 - 1
Babylon/Lights/Shadows/babylon.shadowGenerator.js

@@ -14,6 +14,12 @@ var BABYLON = BABYLON || {};
         this._shadowMap.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE;
         this._shadowMap.wrapV = BABYLON.Texture.CLAMP_ADDRESSMODE;
         this._shadowMap.renderParticles = false;
+
+        // Darkness
+        this._darkness = 0.;
+
+        // Darkness
+        this._transparencyShadow = false;        
                 
         // Custom render function
         var that = this;
@@ -42,7 +48,7 @@ var BABYLON = BABYLON || {};
             }
         };
 
-        this._shadowMap.customRenderFunction = function (opaqueSubMeshes, alphaTestSubMeshes) {
+        this._shadowMap.customRenderFunction = function (opaqueSubMeshes, alphaTestSubMeshes, transparentSubMeshes) {
             var index;
             
             for (index = 0; index < opaqueSubMeshes.length; index++) {
@@ -52,6 +58,12 @@ var BABYLON = BABYLON || {};
             for (index = 0; index < alphaTestSubMeshes.length; index++) {
                 renderSubMesh(alphaTestSubMeshes.data[index]);
             }
+
+            if (that._transparencyShadow) {
+                for (index = 0; index < transparentSubMeshes.length; index++) {
+                    renderSubMesh(transparentSubMeshes.data[index]);
+                }                
+            }
         };
         
         // Internals
@@ -126,6 +138,23 @@ var BABYLON = BABYLON || {};
         return this._transformMatrix;
     };
 
+    BABYLON.ShadowGenerator.prototype.getDarkness = function () {
+        return this._darkness;
+    };
+
+    BABYLON.ShadowGenerator.prototype.setDarkness = function (darkness) {
+        if (darkness >= 1.0)
+            this._darkness = 1.0;
+        else if (darkness <= 0.0)   
+            this._darkness = 0.0;
+        else
+            this._darkness = darkness;
+    };
+
+    BABYLON.ShadowGenerator.prototype.setTransparencyShadow = function (hasShadow) {
+        this._transparencyShadow = hasShadow;
+    };
+
     BABYLON.ShadowGenerator.prototype.dispose = function() {
         this._shadowMap.dispose();
     };

+ 10 - 0
Babylon/Loading/Plugins/babylon.babylonFileLoader.js

@@ -99,6 +99,8 @@ var BABYLON = BABYLON || {};
         material.alpha = parsedMaterial.alpha;
 
         material.id = parsedMaterial.id;
+
+        BABYLON.Tags.AddTagsTo(material, parsedMaterial.tags);
         material.backFaceCulling = parsedMaterial.backFaceCulling;
 
         if (parsedMaterial.diffuseTexture) {
@@ -148,6 +150,8 @@ var BABYLON = BABYLON || {};
 
         multiMaterial.id = parsedMultiMaterial.id;
 
+        BABYLON.Tags.AddTagsTo(multiMaterial, parsedMultiMaterial.tags);
+
         for (var matIndex = 0; matIndex < parsedMultiMaterial.materials.length; matIndex++) {
             var subMatId = parsedMultiMaterial.materials[matIndex];
 
@@ -282,6 +286,8 @@ var BABYLON = BABYLON || {};
 
         light.id = parsedLight.id;
 
+        BABYLON.Tags.AddTagsTo(light, parsedLight.tags);
+
         if (parsedLight.intensity) {
             light.intensity = parsedLight.intensity;
         }
@@ -293,6 +299,8 @@ var BABYLON = BABYLON || {};
         var camera = new BABYLON.FreeCamera(parsedCamera.name, BABYLON.Vector3.FromArray(parsedCamera.position), scene);
         camera.id = parsedCamera.id;
 
+        BABYLON.Tags.AddTagsTo(camera, parsedCamera.tags);
+
         // Parent
         if (parsedCamera.parentId) {
             camera._waitingParentId = parsedCamera.parentId;
@@ -343,6 +351,8 @@ var BABYLON = BABYLON || {};
         var mesh = new BABYLON.Mesh(parsedMesh.name, scene);
         mesh.id = parsedMesh.id;
 
+        BABYLON.Tags.AddTagsTo(mesh, parsedMesh.tags);
+
         mesh.position = BABYLON.Vector3.FromArray(parsedMesh.position);
         if (parsedMesh.rotation) {
             mesh.rotation = BABYLON.Vector3.FromArray(parsedMesh.rotation);

+ 28 - 15
Babylon/Materials/babylon.standardMaterial.js

@@ -64,7 +64,7 @@ var BABYLON = BABYLON || {};
 
         // Textures
         if (this._scene.texturesEnabled) {
-            if (this.diffuseTexture) {
+            if (this.diffuseTexture && BABYLON.StandardMaterial.DiffuseTextureEnabled) {
                 if (!this.diffuseTexture.isReady()) {
                     return false;
                 } else {
@@ -72,7 +72,7 @@ var BABYLON = BABYLON || {};
                 }
             }
 
-            if (this.ambientTexture) {
+            if (this.ambientTexture && BABYLON.StandardMaterial.AmbientTextureEnabled) {
                 if (!this.ambientTexture.isReady()) {
                     return false;
                 } else {
@@ -80,7 +80,7 @@ var BABYLON = BABYLON || {};
                 }
             }
 
-            if (this.opacityTexture) {
+            if (this.opacityTexture && BABYLON.StandardMaterial.OpacityTextureEnabled) {
                 if (!this.opacityTexture.isReady()) {
                     return false;
                 } else {
@@ -88,7 +88,7 @@ var BABYLON = BABYLON || {};
                 }
             }
 
-            if (this.reflectionTexture) {
+            if (this.reflectionTexture && BABYLON.StandardMaterial.ReflectionTextureEnabled) {
                 if (!this.reflectionTexture.isReady()) {
                     return false;
                 } else {
@@ -96,7 +96,7 @@ var BABYLON = BABYLON || {};
                 }
             }
 
-            if (this.emissiveTexture) {
+            if (this.emissiveTexture && BABYLON.StandardMaterial.EmissiveTextureEnabled) {
                 if (!this.emissiveTexture.isReady()) {
                     return false;
                 } else {
@@ -104,7 +104,7 @@ var BABYLON = BABYLON || {};
                 }
             }
 
-            if (this.specularTexture) {
+            if (this.specularTexture && BABYLON.StandardMaterial.SpecularTextureEnabled) {
                 if (!this.specularTexture.isReady()) {
                     return false;
                 } else {
@@ -114,7 +114,7 @@ var BABYLON = BABYLON || {};
             }
         }
 
-        if (this._scene.getEngine().getCaps().standardDerivatives && this.bumpTexture) {
+        if (this._scene.getEngine().getCaps().standardDerivatives && this.bumpTexture && BABYLON.StandardMaterial.BumpTextureEnabled) {
             if (!this.bumpTexture.isReady()) {
                 return false;
             } else {
@@ -245,7 +245,8 @@ var BABYLON = BABYLON || {};
                 "vFogInfos", "vFogColor",
                  "vDiffuseInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vEmissiveInfos", "vSpecularInfos", "vBumpInfos",
                  "mBones",
-                 "vClipPlane", "diffuseMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "specularMatrix", "bumpMatrix"],
+                 "vClipPlane", "diffuseMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "specularMatrix", "bumpMatrix",
+                 "darkness0", "darkness1", "darkness2", "darkness3"],
                 ["diffuseSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler", "reflection2DSampler", "emissiveSampler", "specularSampler", "bumpSampler",
                  "shadowSampler0", "shadowSampler1", "shadowSampler2", "shadowSampler3"
                 ],
@@ -289,7 +290,7 @@ var BABYLON = BABYLON || {};
         }
 
         // Textures        
-        if (this.diffuseTexture) {
+        if (this.diffuseTexture && BABYLON.StandardMaterial.DiffuseTextureEnabled) {
             this._effect.setTexture("diffuseSampler", this.diffuseTexture);
 
             this._effect.setFloat2("vDiffuseInfos", this.diffuseTexture.coordinatesIndex, this.diffuseTexture.level);
@@ -298,21 +299,21 @@ var BABYLON = BABYLON || {};
             this._baseColor.copyFromFloats(1, 1, 1);
         }
 
-        if (this.ambientTexture) {
+        if (this.ambientTexture && BABYLON.StandardMaterial.AmbientTextureEnabled) {
             this._effect.setTexture("ambientSampler", this.ambientTexture);
 
             this._effect.setFloat2("vAmbientInfos", this.ambientTexture.coordinatesIndex, this.ambientTexture.level);
             this._effect.setMatrix("ambientMatrix", this.ambientTexture._computeTextureMatrix());
         }
 
-        if (this.opacityTexture) {
+        if (this.opacityTexture && BABYLON.StandardMaterial.OpacityTextureEnabled) {
             this._effect.setTexture("opacitySampler", this.opacityTexture);
 
             this._effect.setFloat2("vOpacityInfos", this.opacityTexture.coordinatesIndex, this.opacityTexture.level);
             this._effect.setMatrix("opacityMatrix", this.opacityTexture._computeTextureMatrix());
         }
 
-        if (this.reflectionTexture) {
+        if (this.reflectionTexture && BABYLON.StandardMaterial.ReflectionTextureEnabled) {
             if (this.reflectionTexture.isCube) {
                 this._effect.setTexture("reflectionCubeSampler", this.reflectionTexture);
             } else {
@@ -323,21 +324,21 @@ var BABYLON = BABYLON || {};
             this._effect.setFloat3("vReflectionInfos", this.reflectionTexture.coordinatesMode, this.reflectionTexture.level, this.reflectionTexture.isCube ? 1 : 0);
         }
 
-        if (this.emissiveTexture) {
+        if (this.emissiveTexture && BABYLON.StandardMaterial.EmissiveTextureEnabled) {
             this._effect.setTexture("emissiveSampler", this.emissiveTexture);
 
             this._effect.setFloat2("vEmissiveInfos", this.emissiveTexture.coordinatesIndex, this.emissiveTexture.level);
             this._effect.setMatrix("emissiveMatrix", this.emissiveTexture._computeTextureMatrix());
         }
 
-        if (this.specularTexture) {
+        if (this.specularTexture && BABYLON.StandardMaterial.SpecularTextureEnabled) {
             this._effect.setTexture("specularSampler", this.specularTexture);
 
             this._effect.setFloat2("vSpecularInfos", this.specularTexture.coordinatesIndex, this.specularTexture.level);
             this._effect.setMatrix("specularMatrix", this.specularTexture._computeTextureMatrix());
         }
 
-        if (this.bumpTexture && this._scene.getEngine().getCaps().standardDerivatives) {
+        if (this.bumpTexture && this._scene.getEngine().getCaps().standardDerivatives && BABYLON.StandardMaterial.BumpTextureEnabled) {
             this._effect.setTexture("bumpSampler", this.bumpTexture);
 
             this._effect.setFloat2("vBumpInfos", this.bumpTexture.coordinatesIndex, this.bumpTexture.level);
@@ -391,6 +392,7 @@ var BABYLON = BABYLON || {};
                     world.multiplyToRef(shadowGenerator.getTransformMatrix(), this._lightMatrix);
                     this._effect.setMatrix("lightMatrix" + lightIndex, this._lightMatrix);
                     this._effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMap());
+                    this._effect.setFloat("darkness" + lightIndex, shadowGenerator.getDarkness());
                 }
 
                 lightIndex++;
@@ -523,4 +525,15 @@ var BABYLON = BABYLON || {};
         return newStandardMaterial;
     };
 
+    // Statics
+
+    // Flags used to enable or disable a type of texture for all Standard Materials
+    BABYLON.StandardMaterial.DiffuseTextureEnabled = true;
+    BABYLON.StandardMaterial.AmbientTextureEnabled = true;
+    BABYLON.StandardMaterial.OpacityTextureEnabled = true;
+    BABYLON.StandardMaterial.ReflectionTextureEnabled = true;
+    BABYLON.StandardMaterial.EmissiveTextureEnabled = true;
+    BABYLON.StandardMaterial.SpecularTextureEnabled = true;
+    BABYLON.StandardMaterial.BumpTextureEnabled = true;
+
 })();

+ 1 - 2
Babylon/Mesh/babylon.mesh.js

@@ -324,8 +324,7 @@ var BABYLON = BABYLON || {};
     };
 
     BABYLON.Mesh.prototype.computeWorldMatrix = function (force) {
-        if (!force && (this._currentRenderId == this._scene.getRenderId() || this.isSynchronized(true))) {
-            this._currentRenderId = this._scene.getRenderId();
+        if (!force && this.isSynchronized(true)) {
             return this._worldMatrix;
         }
 

+ 88 - 0
Babylon/Mesh/babylon.mesh.vertexData.js

@@ -20,6 +20,22 @@ var BABYLON = BABYLON || {};
             mesh.setVerticesData(this.uvs, BABYLON.VertexBuffer.UVKind, updatable);
         }
 
+        if (this.uv2s) {
+            mesh.setVerticesData(this.uv2s, BABYLON.VertexBuffer.UV2Kind, updatable);
+        }
+
+        if (this.colors) {
+            mesh.setVerticesData(this.colors, BABYLON.VertexBuffer.ColorKind, updatable);
+        }
+
+        if (this.matricesIndices) {
+            mesh.setVerticesData(this.matricesIndices, BABYLON.VertexBuffer.MatricesIndicesKind, updatable);
+        }
+
+        if (this.matricesWeights) {
+            mesh.setVerticesData(this.matricesWeights, BABYLON.VertexBuffer.MatricesWeightsKind, updatable);
+        }
+
         if (this.indices) {
             mesh.setIndices(this.indices);
         }
@@ -94,9 +110,81 @@ var BABYLON = BABYLON || {};
                 this.uvs.push(other.uvs[index]);
             }
         }
+
+        if (other.uv2s) {
+            if (!this.uv2s) {
+                this.uv2s = [];
+            }
+            for (index = 0; index < other.uv2s.length; index++) {
+                this.uv2s.push(other.uv2s[index]);
+            }
+        }
+
+        if (other.matricesIndices) {
+            if (!this.matricesIndices) {
+                this.matricesIndices = [];
+            }
+            for (index = 0; index < other.matricesIndices.length; index++) {
+                this.matricesIndices.push(other.matricesIndices[index]);
+            }
+        }
+
+        if (other.matricesWeights) {
+            if (!this.matricesWeights) {
+                this.matricesWeights = [];
+            }
+            for (index = 0; index < other.matricesWeights.length; index++) {
+                this.matricesWeights.push(other.matricesWeights[index]);
+            }
+        }
+
+        if (other.colors) {
+            if (!this.colors) {
+                this.colors = [];
+            }
+            for (index = 0; index < other.colors.length; index++) {
+                this.colors.push(other.colors[index]);
+            }
+        }
     };
 
     // Statics
+    BABYLON.VertexData.ExtractFromMesh = function (mesh) {
+        var result = new BABYLON.VertexData();
+
+        if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.PositionKind)) {
+            result.positions = mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
+        }
+
+        if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
+            result.normals = mesh.getVerticesData(BABYLON.VertexBuffer.NormalKind);
+        }
+
+        if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
+            result.uvs = mesh.getVerticesData(BABYLON.VertexBuffer.UVKind);
+        }
+
+        if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.UV2Kind)) {
+            result.uv2s = mesh.getVerticesData(BABYLON.VertexBuffer.UV2Kind);
+        }
+
+        if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
+            result.colors = mesh.getVerticesData(BABYLON.VertexBuffer.ColorKind);
+        }
+
+        if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesKind)) {
+            result.matricesIndices = mesh.getVerticesData(BABYLON.VertexBuffer.MatricesIndicesKind);
+        }
+
+        if (mesh.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsKind)) {
+            result.matricesWeights = mesh.getVerticesData(BABYLON.VertexBuffer.MatricesWeightsKind);
+        }
+
+        result.indices = mesh.getIndices();
+
+        return result;
+    };
+
     BABYLON.VertexData.CreateBox = function(size) {
         var normalsSource = [
             new BABYLON.Vector3(0, 0, 1),

+ 1 - 1
Babylon/Particles/babylon.particleSystem.js

@@ -380,7 +380,7 @@ var BABYLON = BABYLON || {};
 
         result.emitter = newEmitter;
         if (this.particleTexture) {
-            result.particleTexture = new BABYLON.Texture(this.particleTexture.name, this._scene);
+            result.particleTexture = new BABYLON.Texture(this.particleTexture.url, this._scene);
         }
 
         result.start();

+ 12 - 0
Babylon/PostProcess/babylon.anaglyphPostProcess.js

@@ -0,0 +1,12 @@
+"use strict";
+
+var BABYLON = BABYLON || {};
+
+(function () {
+    BABYLON.AnaglyphPostProcess = function (name, ratio, camera, samplingMode, engine, reusable) {
+        BABYLON.PostProcess.call(this, name, "anaglyph", null, ["leftSampler"], ratio, camera, samplingMode, engine, reusable);
+    };
+
+    BABYLON.AnaglyphPostProcess.prototype = Object.create(BABYLON.PostProcess.prototype);
+
+})();

+ 5 - 1
Babylon/PostProcess/babylon.postProcessManager.js

@@ -41,7 +41,7 @@ var BABYLON = BABYLON || {};
         postProcesses[this._scene.activeCamera._postProcessesTakenIndices[0]].activate(this._scene.activeCamera);
     };
     
-    BABYLON.PostProcessManager.prototype._finalizeFrame = function () {
+    BABYLON.PostProcessManager.prototype._finalizeFrame = function (doNotPresent) {
         var postProcesses = this._scene.activeCamera._postProcesses;
         var postProcessesTakenIndices = this._scene.activeCamera._postProcessesTakenIndices;
         if (postProcessesTakenIndices.length === 0 || !this._scene.postProcessesEnabled) {
@@ -57,6 +57,10 @@ var BABYLON = BABYLON || {};
                 engine.restoreDefaultFramebuffer();
             }
 
+            if (doNotPresent) {
+                break;
+            }
+
             var effect = postProcesses[postProcessesTakenIndices[index]].apply();
 
             if (effect) {

+ 19 - 0
Babylon/Shaders/anaglyph.fragment.fx

@@ -0,0 +1,19 @@
+#ifdef GL_ES
+precision mediump float;
+#endif
+
+// Samplers
+varying vec2 vUV;
+uniform sampler2D textureSampler;
+uniform sampler2D leftSampler;
+
+void main(void)
+{
+    vec4 leftFrag = texture2D(leftSampler, vUV);
+    leftFrag = vec4(1.0, leftFrag.g, leftFrag.b, 1.0);
+
+	vec4 rightFrag = texture2D(textureSampler, vUV);
+    rightFrag = vec4(rightFrag.r, 1.0, 1.0, 1.0);
+
+    gl_FragColor = vec4(rightFrag.rgb * leftFrag.rgb, 1.0);
+}

+ 11 - 7
Babylon/Shaders/default.fragment.fx

@@ -32,6 +32,7 @@ uniform vec3 vLightSpecular0;
 #ifdef SHADOW0
 varying vec4 vPositionFromLight0;
 uniform sampler2D shadowSampler0;
+uniform float darkness0;
 #endif
 #ifdef SPOTLIGHT0
 uniform vec4 vLightDirection0;
@@ -48,6 +49,7 @@ uniform vec3 vLightSpecular1;
 #ifdef SHADOW1
 varying vec4 vPositionFromLight1;
 uniform sampler2D shadowSampler1;
+uniform float darkness1;
 #endif
 #ifdef SPOTLIGHT1
 uniform vec4 vLightDirection1;
@@ -64,6 +66,7 @@ uniform vec3 vLightSpecular2;
 #ifdef SHADOW2
 varying vec4 vPositionFromLight2;
 uniform sampler2D shadowSampler2;
+uniform float darkness2;
 #endif
 #ifdef SPOTLIGHT2
 uniform vec4 vLightDirection2;
@@ -80,6 +83,7 @@ uniform vec3 vLightSpecular3;
 #ifdef SHADOW3
 varying vec4 vPositionFromLight3;
 uniform sampler2D shadowSampler3;
+uniform float darkness3;
 #endif
 #ifdef SPOTLIGHT3
 uniform vec4 vLightDirection3;
@@ -178,7 +182,7 @@ float unpackHalf(vec2 color)
 	return color.x + (color.y / 255.0);
 }
 
-float computeShadow(vec4 vPositionFromLight, sampler2D shadowSampler)
+float computeShadow(vec4 vPositionFromLight, sampler2D shadowSampler, float darkness)
 {
 	vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
 	vec2 uv = 0.5 * depth.xy + vec2(0.5, 0.5);
@@ -192,7 +196,7 @@ float computeShadow(vec4 vPositionFromLight, sampler2D shadowSampler)
 
 	if (depth.z > shadow)
 	{
-		return 0.;
+		return darkness;
 	}
 	return 1.;
 }
@@ -332,7 +336,7 @@ lightingInfo computeLighting(vec3 viewDirectionW, vec3 vNormal, vec4 lightData,
 	// Specular
 	vec3 angleW = normalize(viewDirectionW + lightVectorW);
 	float specComp = max(0., dot(vNormal, angleW));
-	specComp = pow(specComp, vSpecularColor.a);
+	specComp = pow(specComp, max(1., vSpecularColor.a));
 
 	result.diffuse = ndl * diffuseColor;
 	result.specular = specComp * specularColor;
@@ -452,7 +456,7 @@ void main(void) {
 #ifdef SHADOWVSM0
 	shadow = computeShadowWithVSM(vPositionFromLight0, shadowSampler0);
 #else
-	shadow = computeShadow(vPositionFromLight0, shadowSampler0);
+	shadow = computeShadow(vPositionFromLight0, shadowSampler0, darkness0);
 #endif
 #else
 	shadow = 1.;
@@ -475,7 +479,7 @@ void main(void) {
 #ifdef SHADOWVSM1
 	shadow = computeShadowWithVSM(vPositionFromLight1, shadowSampler1);
 #else
-	shadow = computeShadow(vPositionFromLight1, shadowSampler1);
+	shadow = computeShadow(vPositionFromLight1, shadowSampler1, darkness1);
 #endif
 #else
 	shadow = 1.;
@@ -498,7 +502,7 @@ void main(void) {
 #ifdef SHADOWVSM2
 	shadow = computeShadowWithVSM(vPositionFromLight2, shadowSampler2);
 #else
-	shadow = computeShadow(vPositionFromLight2, shadowSampler2);
+	shadow = computeShadow(vPositionFromLight2, shadowSampler2, darkness2);
 #endif	
 #else
 	shadow = 1.;
@@ -521,7 +525,7 @@ void main(void) {
 #ifdef SHADOWVSM3
 	shadow = computeShadowWithVSM(vPositionFromLight3, shadowSampler3);
 #else
-	shadow = computeShadow(vPositionFromLight3, shadowSampler3);
+	shadow = computeShadow(vPositionFromLight3, shadowSampler3, darkness3);
 #endif	
 #else
 	shadow = 1.;

+ 135 - 0
Babylon/Tools/babylon.andOrNotEvaluator.js

@@ -0,0 +1,135 @@
+"use strict";
+
+var BABYLON = BABYLON || {};
+
+(function () {
+    BABYLON.AndOrNotEvaluator = BABYLON.AndOrNotEvaluator || {};
+
+    BABYLON.AndOrNotEvaluator.Eval = function (query, evaluateCallback) {
+        if (!query.match(/\([^\(\)]*\)/g)) {
+            query = BABYLON.AndOrNotEvaluator._HandleParenthesisContent(query, evaluateCallback);
+        }
+        else {
+            query = query.replace(/\([^\(\)]*\)/g, function (r) {
+                // remove parenthesis
+                r = r.slice(1, r.length - 1);
+                return BABYLON.AndOrNotEvaluator._HandleParenthesisContent(r, evaluateCallback);
+            });
+        }
+
+        if (query === "true") {
+            return true;
+        }
+
+        if (query === "false") {
+            return false;
+        }
+
+        return BABYLON.AndOrNotEvaluator.Eval(query, evaluateCallback);
+    };
+
+    BABYLON.AndOrNotEvaluator._HandleParenthesisContent = function (parenthesisContent, evaluateCallback) {
+        evaluateCallback = evaluateCallback || function (r) {
+            /*switch(r)
+            {
+                case "true":
+                    return true;
+                case "false":
+                case "0":
+                case "":
+                case "undefined":
+                case "null":
+                default:
+                    return false;
+            }*/
+            return r === "true" ? true : false;
+        };
+
+        var result;
+        var or = parenthesisContent.split("||");
+
+        for (var i in or) {
+            var ori = BABYLON.AndOrNotEvaluator._SimplifyNegation(or[i].trim());
+            var and = ori.split("&&");
+
+            if (and.length > 1) {
+                for (var j = 0; j < and.length; ++j) {
+                    var andj = BABYLON.AndOrNotEvaluator._SimplifyNegation(and[j].trim());
+                    if (andj !== "true" && andj !== "false") {
+                        if (andj[0] === "!") {
+                            result = andj.substring(1);
+                            if (evaluateCallback) {
+                                result = evaluateCallback(result);
+                            }
+                            result = !result;
+                        }
+                        else {
+                            result = andj;
+                            if (evaluateCallback) {
+                                result = evaluateCallback(result);
+                            }
+                        }
+                    }
+                    else {
+                        result = andj === "true" ? true : false;
+                    }
+                    if (!result) { // no need to continue since 'false && ... && ...' will always return false
+                        ori = "false";
+                        break;
+                    }
+                }
+            }
+
+            if (result || ori === "true") { // no need to continue since 'true || ... || ...' will always return true
+                result = true;
+                break;
+            }
+
+            // result equals false (or undefined)
+
+            if (ori !== "true" && ori !== "false") {
+                if (ori[0] === "!") {
+                    result = ori.substring(1);
+                    if (evaluateCallback) {
+                        result = evaluateCallback(result);
+                    }
+                    result = !result;
+                }
+                else {
+                    result = ori;
+                    if (evaluateCallback) {
+                        result = evaluateCallback(result);
+                    }
+                }
+            }
+            else {
+                result = ori === "true" ? true : false;
+            }
+        }
+
+        // the whole parenthesis scope is replaced by 'true' or 'false'
+        return result ? "true" : "false";
+    };
+
+    BABYLON.AndOrNotEvaluator._SimplifyNegation = function (booleanString) {
+        booleanString = booleanString.replace(/^[\s!]+/, function (r) {
+            // remove whitespaces
+            r = r.replace(/[\s]/g, function (r) {
+                return "";
+            });
+            return r.length % 2 ? "!" : "";
+        });
+
+        booleanString = booleanString.trim();
+
+        if (booleanString === "!true") {
+            booleanString = "false";
+        }
+        else if (booleanString === "!false") {
+            booleanString = "true";
+        }
+
+        return booleanString;
+    };
+
+})();

+ 5 - 0
Babylon/Tools/babylon.sceneSerializer.js

@@ -8,6 +8,7 @@ var BABYLON = BABYLON || {};
         var serializationObject = {};
         serializationObject.name = light.name;
         serializationObject.id = light.id;
+        serializationObject.tags = light._tags;
 
         if (light instanceof BABYLON.PointLight) {
             serializationObject.type = 0;
@@ -39,6 +40,7 @@ var BABYLON = BABYLON || {};
     var serializeCamera = function (camera) {
         var serializationObject = {};
         serializationObject.name = camera.name;
+        serializationObject.tags = camera._tags;
         serializationObject.id = camera.id;
         serializationObject.position = camera.position.asArray();
 
@@ -125,6 +127,7 @@ var BABYLON = BABYLON || {};
 
         serializationObject.name = material.name;
         serializationObject.id = material.id;
+        serializationObject.tags = material._tags;
 
         serializationObject.materials = [];
 
@@ -155,6 +158,7 @@ var BABYLON = BABYLON || {};
         serializationObject.alpha = material.alpha;
 
         serializationObject.id = material.id;
+        serializationObject.tags = material._tags;
         serializationObject.backFaceCulling = material.backFaceCulling;
 
         if (material.diffuseTexture) {
@@ -349,6 +353,7 @@ var BABYLON = BABYLON || {};
 
         serializationObject.name = mesh.name;
         serializationObject.id = mesh.id;
+        serializationObject.tags = mesh._tags;
 
         serializationObject.position = mesh.position.asArray();
 

+ 101 - 0
Babylon/Tools/babylon.tags.js

@@ -0,0 +1,101 @@
+"use strict";
+
+var BABYLON = BABYLON || {};
+
+(function () {
+    BABYLON.Tags = BABYLON.Tags || {};
+
+    BABYLON.Tags.EnableFor = function (obj) {
+        obj._tags = obj._tags || {};
+
+        obj.hasTags = function () {
+            return BABYLON.Tags.HasTags(obj);
+        };
+
+        obj.addTags = function (tagsString) {
+            return BABYLON.Tags.AddTagsTo(obj, tagsString);
+        };
+
+        obj.removeTags = function (tagsString) {
+            return BABYLON.Tags.RemoveTagsFrom(obj, tagsString);
+        };
+
+        obj.matchesTagsQuery = function (tagsQuery) {
+            return BABYLON.Tags.MatchesQuery(obj, tagsQuery);
+        };
+    };
+
+    BABYLON.Tags.DisableFor = function (obj) {
+        delete obj._tags;
+        delete obj.hasTags;
+        delete obj.addTags;
+        delete obj.removeTags;
+        delete obj.matchesTagsQuery;
+    };
+
+    BABYLON.Tags.HasTags = function (obj) {
+        if (!obj._tags) {
+            return false;
+        }
+        return !BABYLON.Tools.IsEmpty(obj._tags);
+    };
+
+    // the tags 'true' and 'false' are reserved and cannot be used as tags
+    // a tag cannot start with '||', '&&', and '!'
+    // it cannot contain whitespaces
+    BABYLON.Tags.AddTagsTo = function (obj, tagsString) {
+        if (!tagsString) {
+            return;
+        }
+
+        var tags = tagsString.split(" ");
+        for (var t in tags) {
+            BABYLON.Tags._AddTagTo(obj, tags[t]);
+        }
+    };
+
+    BABYLON.Tags._AddTagTo = function (obj, tag) {
+        tag = tag.trim();
+
+        if (tag === "" || tag === "true" || tag === "false") {
+            return;
+        }
+
+        if (tag.match(/[\s]/) || tag.match(/^([!]|([|]|[&]){2})/)) {
+            return;
+        }
+
+        BABYLON.Tags.EnableFor(obj);
+        obj._tags[tag] = true;
+    };
+
+    BABYLON.Tags.RemoveTagsFrom = function (obj, tagsString) {
+        if (!BABYLON.Tags.HasTags(obj)) {
+            return;
+        }
+        var tags = tagsString.split(" ");
+        for (var t in tags) {
+            BABYLON.Tags._RemoveTagFrom(obj, tags[t]);
+        }
+    };
+    
+
+    BABYLON.Tags._RemoveTagFrom = function (obj, tag) {
+        delete obj._tags[tag];
+    };
+
+    BABYLON.Tags.MatchesQuery = function (obj, tagsQuery) {
+        if (tagsQuery === undefined) {
+            return true;
+        }
+
+        if (tagsQuery === "") {
+            return BABYLON.Tags.HasTags(obj);
+        }
+
+        return BABYLON.AndOrNotEvaluator.Eval(tagsQuery, function (r) {
+            return BABYLON.Tags.HasTags(obj) && obj._tags[r];
+        });
+    };
+
+})();

+ 5 - 0
Babylon/Tools/babylon.tools.dds.js

@@ -56,6 +56,7 @@ var BABYLON = BABYLON || {};
     }
 
     var FOURCC_DXT1 = FourCCToInt32("DXT1");
+    var FOURCC_DXT3 = FourCCToInt32("DXT3");
     var FOURCC_DXT5 = FourCCToInt32("DXT5");
 
     var headerLengthInt = 31; // The header length in 32 bit ints
@@ -111,6 +112,10 @@ var BABYLON = BABYLON || {};
                 blockBytes = 8;
                 internalFormat = ext.COMPRESSED_RGBA_S3TC_DXT1_EXT;
                 break;
+            case FOURCC_DXT3:
+                blockBytes = 16;
+                internalFormat = ext.COMPRESSED_RGBA_S3TC_DXT3_EXT;
+                break;
             case FOURCC_DXT5:
                 blockBytes = 16;
                 internalFormat = ext.COMPRESSED_RGBA_S3TC_DXT5_EXT;

+ 7 - 0
Babylon/Tools/babylon.tools.js

@@ -349,6 +349,13 @@ var BABYLON = BABYLON || {};
         }
     };
 
+    BABYLON.Tools.IsEmpty = function (obj) {
+        for (var i in obj) {
+            return false;
+        }
+        return true;
+    };
+
     // FPS
     var fpsRange = 60;
     var previousFramesDuration = [];

+ 1 - 1
Babylon/babylon.node.js

@@ -52,7 +52,7 @@ var BABYLON = BABYLON || {};
     };
 
     BABYLON.Node.prototype.isSynchronizedWithParent = function() {
-        return this.parent ? !this.parent._currentRenderId === this._currentRenderId : true;
+        return this.parent ? this.parent._currentRenderId === this._currentRenderId : true;
     };
 
     BABYLON.Node.prototype.isSynchronized = function (updateCache) {

+ 59 - 11
Babylon/babylon.scene.js

@@ -608,7 +608,7 @@ var BABYLON = BABYLON || {};
         this._particlesDuration += new Date() - beforeParticlesDate;
     };
 
-    BABYLON.Scene.prototype._renderForCamera = function (camera, mustClearDepth) {
+    BABYLON.Scene.prototype._renderForCamera = function (camera) {
         var engine = this._engine;
 
         this.activeCamera = camera;
@@ -619,11 +619,6 @@ var BABYLON = BABYLON || {};
         // Viewport
         engine.setViewport(this.activeCamera.viewport);
 
-        // Clear
-        if (mustClearDepth) {
-            this._engine.clear(this.clearColor, false, true);
-        }
-
         // Camera
         this._renderId++;
         this.setTransformMatrix(this.activeCamera.getViewMatrix(), this.activeCamera.getProjectionMatrix());
@@ -701,7 +696,7 @@ var BABYLON = BABYLON || {};
         this._renderDuration += new Date() - beforeRenderDate;
 
         // Finalize frame
-        this.postProcessManager._finalizeFrame();
+        this.postProcessManager._finalizeFrame(camera.isIntermediate);
 
         // Update camera
         this.activeCamera._updateFromScene();
@@ -710,6 +705,24 @@ var BABYLON = BABYLON || {};
         this._renderTargets.reset();
     };
 
+    BABYLON.Scene.prototype._processSubCameras = function (camera) {
+        if (camera.subCameras.length == 0) {
+            this._renderForCamera(camera);
+            return;
+        }
+
+        // Sub-cameras
+        for (var index = 0; index < camera.subCameras.length; index++) {
+            this._renderForCamera(camera.subCameras[index]);
+        }
+
+        this.activeCamera = camera;
+        this.setTransformMatrix(this.activeCamera.getViewMatrix(), this.activeCamera.getProjectionMatrix());
+
+        // Update camera
+        this.activeCamera._updateFromScene();
+    };
+
     BABYLON.Scene.prototype.render = function () {
         var startDate = new Date();
         this._particlesDuration = 0;
@@ -747,7 +760,7 @@ var BABYLON = BABYLON || {};
             var light = this.lights[lightIndex];
             var shadowGenerator = light.getShadowGenerator();
 
-            if (light.isEnabled() && shadowGenerator) {
+            if (light.isEnabled() && shadowGenerator && shadowGenerator.getShadowMap()._scene.textures.indexOf(shadowGenerator.getShadowMap()) !== -1) {
                 this._renderTargets.push(shadowGenerator.getShadowMap());
             }
         }
@@ -757,10 +770,10 @@ var BABYLON = BABYLON || {};
             var currentRenderId = this._renderId;
             for (var cameraIndex = 0; cameraIndex < this.activeCameras.length; cameraIndex++) {
                 this._renderId = currentRenderId;
-                this._renderForCamera(this.activeCameras[cameraIndex], cameraIndex != 0);
+                this._processSubCameras(this.activeCameras[cameraIndex]);
             }
         } else {
-            this._renderForCamera(this.activeCamera);
+            this._processSubCameras(this.activeCamera);
         }
 
         // After render
@@ -1070,9 +1083,44 @@ var BABYLON = BABYLON || {};
         }
     };
 
+    // Tags
+    BABYLON.Scene.prototype._getByTags = function(list, tagsQuery) {
+        if (tagsQuery === undefined) {
+            // returns the complete list (could be done with BABYLON.Tags.MatchesQuery but no need to have a for-loop here)
+            return list;
+        }
+
+        var listByTags = [];
+
+        for (var i in list) {
+            var item = list[i];
+            if (BABYLON.Tags.MatchesQuery(item, tagsQuery)) {
+                listByTags.push(item);
+            }
+        }
+
+        return listByTags;
+    };
+
+    BABYLON.Scene.prototype.getMeshesByTags = function (tagsQuery) {
+        return this._getByTags(this.meshes, tagsQuery);
+    };
+
+    BABYLON.Scene.prototype.getCamerasByTags = function (tagsQuery) {
+        return this._getByTags(this.cameras, tagsQuery);
+    };
+
+    BABYLON.Scene.prototype.getLightsByTags = function (tagsQuery) {
+        return this._getByTags(this.lights, tagsQuery);
+    };
+
+    BABYLON.Scene.prototype.getMaterialByTags = function (tagsQuery) {
+        return this._getByTags(this.materials, tagsQuery).concat(this._getByTags(this.multiMaterials, tagsQuery));
+    };
+
     // Statics
     BABYLON.Scene.FOGMODE_NONE = 0;
     BABYLON.Scene.FOGMODE_EXP = 1;
     BABYLON.Scene.FOGMODE_EXP2 = 2;
     BABYLON.Scene.FOGMODE_LINEAR = 3;
-})();
+})();

+ 4 - 0
Tools/BuildOurOwnBabylonJS/BuildOurOwnBabylonJS/babylonJS.xml

@@ -15,6 +15,7 @@
   <script src="Babylon/Collisions/babylon.pickingInfo.js"></script>
   <script src="Babylon/LensFlare/babylon.lensFlareSystem.js"></script>
   <script src="Babylon/LensFlare/babylon.lensFlare.js"></script>
+  <script src="Babylon/PostProcess/babylon.anaglyphPostProcess.js"></script>
   <script src="Babylon/PostProcess/RenderPipeline/babylon.renderPass.js"></script>
   <script src="Babylon/PostProcess/RenderPipeline/babylon.renderEffect.js"></script>
   <script src="Babylon/PostProcess/RenderPipeline/babylon.renderPipeline.js"></script>
@@ -61,6 +62,7 @@
   <script src="Babylon/Mesh/babylon.mesh.vertexData.js"></script>
   <script src="Babylon/Mesh/babylon.vertexBuffer.js"></script>
   <script src="Babylon/babylon.scene.js"></script>
+  <script src="Babylon/Cameras/babylon.anaglyphCamera.js"></script>
   <script src="Babylon/Cameras/babylon.arcRotateCamera.js"></script>
   <script src="Babylon/Cameras/babylon.deviceOrientationCamera.js"></script>
   <script src="Babylon/Cameras/babylon.touchCamera.js"></script>
@@ -79,6 +81,8 @@
   <script src="Babylon/babylon.engine.js"></script>
   <script src="Babylon/Math/babylon.axis.js"></script>
   <script src="Babylon/Math/babylon.math.js"></script>
+  <script src="Babylon/Tools/babylon.tags.js"></script>
+  <script src="Babylon/Tools/babylon.andOrNotEvaluator.js"></script>
   <script src="Babylon/Tools/babylon.tools.js"></script>
   <script src="Babylon/babylon.node.js"></script>
 </files>

File diff suppressed because it is too large
+ 2 - 2
Tools/BuildOurOwnBabylonJS/BuildOurOwnBabylonJS/ourOwnBabylon.js