Преглед на файлове

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

jbousquie преди 9 години
родител
ревизия
8f9a3bb26e
променени са 50 файла, в които са добавени 1951 реда и са изтрити 1221 реда
  1. 19 19
      dist/preview release/babylon.core.js
  2. 882 862
      dist/preview release/babylon.d.ts
  3. 28 28
      dist/preview release/babylon.js
  4. 183 41
      dist/preview release/babylon.max.js
  5. 28 28
      dist/preview release/babylon.noworker.js
  6. 15 8
      materialsLibrary/dist/babylon.waterMaterial.js
  7. 30 0
      materialsLibrary/materials/fire/readme.md
  8. 13 8
      materialsLibrary/materials/water/babylon.waterMaterial.ts
  9. 2 0
      materialsLibrary/materials/water/readme.md
  10. 110 15
      materialsLibrary/materials/water/water.fragment.fx
  11. 15 14
      materialsLibrary/materials/water/water.vertex.fx
  12. 2 0
      materialsLibrary/test/index.html
  13. 1 0
      src/Audio/babylon.sound.js
  14. 1 0
      src/Audio/babylon.sound.ts
  15. 8 1
      src/Lights/Shadows/babylon.shadowGenerator.js
  16. 7 1
      src/Lights/Shadows/babylon.shadowGenerator.ts
  17. 20 0
      src/Loading/Plugins/babylon.babylonFileLoader.js
  18. 24 0
      src/Loading/Plugins/babylon.babylonFileLoader.ts
  19. 12 0
      src/Materials/babylon.effect.js
  20. 18 0
      src/Materials/babylon.effect.ts
  21. 7 7
      src/Materials/babylon.material.js
  22. 8 10
      src/Materials/babylon.material.ts
  23. 7 8
      src/Materials/babylon.pbrMaterial.js
  24. 7 8
      src/Materials/babylon.pbrMaterial.ts
  25. 2 3
      src/Materials/babylon.shaderMaterial.js
  26. 2 3
      src/Materials/babylon.shaderMaterial.ts
  27. 9 7
      src/Materials/babylon.standardMaterial.js
  28. 9 7
      src/Materials/babylon.standardMaterial.ts
  29. 5 0
      src/Mesh/babylon.abstractMesh.ts
  30. 17 3
      src/Mesh/babylon.mesh.js
  31. 18 4
      src/Mesh/babylon.mesh.ts
  32. 53 7
      src/Mesh/babylon.mesh.vertexData.js
  33. 65 9
      src/Mesh/babylon.mesh.vertexData.ts
  34. 2 2
      src/Mesh/babylon.meshBuilder.ts
  35. 18 0
      src/Mesh/babylon.vertexBuffer.js
  36. 12 0
      src/Mesh/babylon.vertexBuffer.ts
  37. 8 1
      src/Particles/babylon.solidParticleSystem.ts
  38. 4 1
      src/PostProcess/babylon.volumetricLightScatteringPostProcess.js
  39. 4 1
      src/PostProcess/babylon.volumetricLightScatteringPostProcess.ts
  40. 8 1
      src/Rendering/babylon.depthRenderer.js
  41. 7 1
      src/Rendering/babylon.depthRenderer.ts
  42. 8 1
      src/Rendering/babylon.outlineRenderer.js
  43. 7 1
      src/Rendering/babylon.outlineRenderer.ts
  44. 43 21
      src/Shaders/default.vertex.fx
  45. 40 15
      src/Shaders/depth.vertex.fx
  46. 41 24
      src/Shaders/legacydefault.vertex.fx
  47. 38 15
      src/Shaders/outline.vertex.fx
  48. 43 25
      src/Shaders/pbr.vertex.fx
  49. 37 11
      src/Shaders/shadowMap.vertex.fx
  50. 4 0
      src/babylon.mixins.ts

Файловите разлики са ограничени, защото са твърде много
+ 19 - 19
dist/preview release/babylon.core.js


Файловите разлики са ограничени, защото са твърде много
+ 882 - 862
dist/preview release/babylon.d.ts


Файловите разлики са ограничени, защото са твърде много
+ 28 - 28
dist/preview release/babylon.js


Файловите разлики са ограничени, защото са твърде много
+ 183 - 41
dist/preview release/babylon.max.js


Файловите разлики са ограничени, защото са твърде много
+ 28 - 28
dist/preview release/babylon.noworker.js


Файловите разлики са ограничени, защото са твърде много
+ 15 - 8
materialsLibrary/dist/babylon.waterMaterial.js


+ 30 - 0
materialsLibrary/materials/fire/readme.md

@@ -0,0 +1,30 @@
+# Fire material
+
+## [Playground example](http://www.babylonjs-playground.com/#21IIM9)
+
+## Using the fire material
+
+The fire material works with 3 textures:
+- The diffuse texture (fire texture)
+- The distortion texture (to create perturbations on diffuse texture)
+- The opacity texture (black and white)
+
+**Note:** *The fire material doesn't work with lighting. So, shadow maps are also disabled.*
+
+```
+var fireMaterial = new BABYLON.FireMaterial("fireMaterial", scene);
+fireMaterial.diffuseTexture = new BABYLON.Texture("diffuse.png", scene);
+fireMaterial.distortionTexture = new BABYLON.Texture("distortion.png", scene);
+fireMaterial.opacityTexture = new BABYLON.Texture("opacity.png", scene);
+
+var plane = BABYLON.Mesh.CreatePlane("fireplane", 1.0, scene);
+plane.material = fire;
+```
+
+The speed of fire flames can be customized like:
+
+```
+fireMaterial.speed = 5.0; // Default is 1.0
+```
+
+

+ 13 - 8
materialsLibrary/materials/water/babylon.waterMaterial.ts

@@ -23,10 +23,14 @@ module BABYLON {
         public HEMILIGHT1 = false;
         public HEMILIGHT2 = false;
         public HEMILIGHT3 = false;
-        public POINTDIRLIGHT0 = false;
-        public POINTDIRLIGHT1 = false;
-        public POINTDIRLIGHT2 = false;
-        public POINTDIRLIGHT3 = false;
+        public DIRLIGHT0 = false;
+        public DIRLIGHT1 = false;
+        public DIRLIGHT2 = false;
+        public DIRLIGHT3 = false;
+        public POINTLIGHT0 = false;
+        public POINTLIGHT1 = false;
+        public POINTLIGHT2 = false;
+        public POINTLIGHT3 = false;        
         public SHADOW0 = false;
         public SHADOW1 = false;
         public SHADOW2 = false;
@@ -127,7 +131,7 @@ module BABYLON {
             return this._refractionRTT;
         }
         
-        public get reflectioNTexture(): RenderTargetTexture {
+        public get reflectionTexture(): RenderTargetTexture {
             return this._reflectionRTT;
         }
 		
@@ -276,8 +280,10 @@ module BABYLON {
                         type = "SPOTLIGHT" + lightIndex;
                     } else if (light instanceof HemisphericLight) {
                         type = "HEMILIGHT" + lightIndex;
+                    } else if (light instanceof PointLight) {
+                        type = "POINTLIGHT" + lightIndex;
                     } else {
-                        type = "POINTDIRLIGHT" + lightIndex;
+                        type = "DIRLIGHT" + lightIndex;
                     }
 
                     this._defines[type] = true;
@@ -586,9 +592,8 @@ module BABYLON {
 			var clipPlane = null;
 			var savedViewMatrix;
 			var mirrorMatrix = Matrix.Zero();
-			
+            
 			this._refractionRTT.onBeforeRender = () => {
-                
                 if (this._mesh) {
                     isVisible = this._mesh.isVisible;
                     this._mesh.isVisible = false;

+ 2 - 0
materialsLibrary/materials/water/readme.md

@@ -1,5 +1,7 @@
 # Water material
 
+## [Playground example](http://www.babylonjs-playground.com/#1SLLOJ#6)
+
 ## Using the water material
 
 The water material needs at least only a bump texture to render properly.

+ 110 - 15
materialsLibrary/materials/water/water.fragment.fx

@@ -20,8 +20,12 @@ varying vec4 vColor;
 uniform vec4 vLightData0;
 uniform vec4 vLightDiffuse0;
 #ifdef SHADOW0
+#if defined(SPOTLIGHT0) || defined(DIRLIGHT0)
 varying vec4 vPositionFromLight0;
 uniform sampler2D shadowSampler0;
+#else
+uniform samplerCube shadowSampler0;
+#endif
 uniform vec3 shadowsInfo0;
 #endif
 #ifdef SPOTLIGHT0
@@ -36,8 +40,12 @@ uniform vec3 vLightGround0;
 uniform vec4 vLightData1;
 uniform vec4 vLightDiffuse1;
 #ifdef SHADOW1
+#if defined(SPOTLIGHT1) || defined(DIRLIGHT1)
 varying vec4 vPositionFromLight1;
 uniform sampler2D shadowSampler1;
+#else
+uniform samplerCube shadowSampler1;
+#endif
 uniform vec3 shadowsInfo1;
 #endif
 #ifdef SPOTLIGHT1
@@ -52,8 +60,12 @@ uniform vec3 vLightGround1;
 uniform vec4 vLightData2;
 uniform vec4 vLightDiffuse2;
 #ifdef SHADOW2
+#if defined(SPOTLIGHT2) || defined(DIRLIGHT2)
 varying vec4 vPositionFromLight2;
 uniform sampler2D shadowSampler2;
+#else
+uniform samplerCube shadowSampler2;
+#endif
 uniform vec3 shadowsInfo2;
 #endif
 #ifdef SPOTLIGHT2
@@ -68,8 +80,12 @@ uniform vec3 vLightGround2;
 uniform vec4 vLightData3;
 uniform vec4 vLightDiffuse3;
 #ifdef SHADOW3
+#if defined(SPOTLIGHT3) || defined(DIRLIGHT3)
 varying vec4 vPositionFromLight3;
 uniform sampler2D shadowSampler3;
+#else
+uniform samplerCube shadowSampler3;
+#endif
 uniform vec3 shadowsInfo3;
 #endif
 #ifdef SPOTLIGHT3
@@ -98,11 +114,12 @@ uniform vec3 cameraPosition;
 uniform vec4 waterColor;
 uniform float colorBlendFactor;
 
+uniform float bumpHeight;
+
 // Water varyings
 varying vec3 vRefractionMapTexCoord;
 varying vec3 vReflectionMapTexCoord;
 varying vec3 vPosition;
-varying float vWaveHeight;
 
 // Shadows
 #ifdef SHADOWS
@@ -113,11 +130,55 @@ float unpack(vec4 color)
 	return dot(color, bit_shift);
 }
 
-float unpackHalf(vec2 color)
+#if defined(POINTLIGHT0) || defined(POINTLIGHT1) || defined(POINTLIGHT2) || defined(POINTLIGHT3)
+float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float darkness, float bias)
 {
-	return color.x + (color.y / 255.0);
+	vec3 directionToLight = vPositionW - lightPosition;
+	float depth = length(directionToLight);
+
+	depth = clamp(depth, 0., 1.);
+
+	directionToLight.y = 1.0 - directionToLight.y;
+
+	float shadow = unpack(textureCube(shadowSampler, directionToLight)) + bias;
+
+	if (depth > shadow)
+	{
+		return darkness;
+	}
+	return 1.0;
+}
+
+float computeShadowWithPCFCube(vec3 lightPosition, samplerCube shadowSampler, float bias, float darkness)
+{
+	vec3 directionToLight = vPositionW - lightPosition;
+	float depth = length(directionToLight);
+
+	depth = clamp(depth, 0., 1.);
+
+	directionToLight.y = 1.0 - directionToLight.y;
+
+	float visibility = 1.;
+
+	vec3 poissonDisk[4];
+	poissonDisk[0] = vec3(-0.094201624, 0.04, -0.039906216);
+	poissonDisk[1] = vec3(0.094558609, -0.04, -0.076890725);
+	poissonDisk[2] = vec3(-0.094184101, 0.01, -0.092938870);
+	poissonDisk[3] = vec3(0.034495938, -0.01, 0.029387760);
+
+	// Poisson Sampling
+	float biasedDepth = depth - bias;
+
+	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[0])) < biasedDepth) visibility -= 0.25;
+	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[1])) < biasedDepth) visibility -= 0.25;
+	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[2])) < biasedDepth) visibility -= 0.25;
+	if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[3])) < biasedDepth) visibility -= 0.25;
+
+	return  min(1.0, visibility + darkness);
 }
+#endif
 
+#if defined(SPOTLIGHT0) || defined(SPOTLIGHT1) || defined(SPOTLIGHT2) || defined(SPOTLIGHT3) ||  defined(DIRLIGHT0) || defined(DIRLIGHT1) || defined(DIRLIGHT2) || defined(DIRLIGHT3)
 float computeShadow(vec4 vPositionFromLight, sampler2D shadowSampler, float darkness, float bias)
 {
 	vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
@@ -169,6 +230,11 @@ float computeShadowWithPCF(vec4 vPositionFromLight, sampler2D shadowSampler, flo
 }
 
 // Thanks to http://devmaster.net/
+float unpackHalf(vec2 color)
+{
+	return color.x + (color.y / 255.0);
+}
+
 float linstep(float low, float high, float v) {
 	return clamp((v - low) / (high - low), 0.0, 1.0);
 }
@@ -200,6 +266,7 @@ float computeShadowWithVSM(vec4 vPositionFromLight, sampler2D shadowSampler, flo
 	return min(1.0, 1.0 - ChebychevInequality(moments, depth.z, bias) + darkness);
 }
 #endif
+#endif
 
 #ifdef CLIPPLANE
 varying float fClipDistance;
@@ -343,7 +410,7 @@ void main(void) {
 
 #ifdef REFLECTION
 	// Water
-	vec2 perturbation = vWaveHeight * (baseColor.rg - 0.5);
+	vec2 perturbation = bumpHeight * (baseColor.rg - 0.5);
 	
 	vec2 projectedRefractionTexCoords = clamp(vRefractionMapTexCoord.xy / vRefractionMapTexCoord.z + perturbation, 0.0, 1.0);
 	vec4 refractiveColor = texture2D(refractionSampler, projectedRefractionTexCoords);
@@ -368,7 +435,7 @@ void main(void) {
 	vec3 normalW = vec3(1.0, 1.0, 1.0);
 #endif
 
-	// Lighting
+		// Lighting
 	vec3 diffuseBase = vec3(0., 0., 0.);
 	float shadow = 1.;
 
@@ -379,7 +446,7 @@ void main(void) {
 #ifdef HEMILIGHT0
 	lightingInfo info = computeHemisphericLighting(viewDirectionW, normalW, vLightData0, vLightDiffuse0.rgb, vLightGround0);
 #endif
-#ifdef POINTDIRLIGHT0
+#if defined(POINTLIGHT0) || defined(DIRLIGHT0)
 	lightingInfo info = computeLighting(viewDirectionW, normalW, vLightData0, vLightDiffuse0.rgb, vLightDiffuse0.a);
 #endif
 #ifdef SHADOW0
@@ -387,9 +454,17 @@ void main(void) {
 	shadow = computeShadowWithVSM(vPositionFromLight0, shadowSampler0, shadowsInfo0.z, shadowsInfo0.x);
 #else
 #ifdef SHADOWPCF0
+	#if defined(POINTLIGHT0)
+	shadow = computeShadowWithPCFCube(vLightData0.xyz, shadowSampler0, shadowsInfo0.z, shadowsInfo0.x);
+	#else
 	shadow = computeShadowWithPCF(vPositionFromLight0, shadowSampler0, shadowsInfo0.y, shadowsInfo0.z, shadowsInfo0.x);
+	#endif
 #else
+	#if defined(POINTLIGHT0)
+	shadow = computeShadowCube(vLightData0.xyz, shadowSampler0, shadowsInfo0.x, shadowsInfo0.z);
+	#else
 	shadow = computeShadow(vPositionFromLight0, shadowSampler0, shadowsInfo0.x, shadowsInfo0.z);
+	#endif
 #endif
 #endif
 #else
@@ -399,14 +474,13 @@ void main(void) {
 #endif
 
 #ifdef LIGHT1
-
 #ifdef SPOTLIGHT1
 	info = computeSpotLighting(viewDirectionW, normalW, vLightData1, vLightDirection1, vLightDiffuse1.rgb, vLightDiffuse1.a);
 #endif
 #ifdef HEMILIGHT1
-	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData1, vLightDiffuse1.rgb, vLightGround1);
+	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData1, vLightDiffuse1.rgb, vLightGround1.a);
 #endif
-#ifdef POINTDIRLIGHT1
+#if defined(POINTLIGHT1) || defined(DIRLIGHT1)
 	info = computeLighting(viewDirectionW, normalW, vLightData1, vLightDiffuse1.rgb, vLightDiffuse1.a);
 #endif
 #ifdef SHADOW1
@@ -414,16 +488,23 @@ void main(void) {
 	shadow = computeShadowWithVSM(vPositionFromLight1, shadowSampler1, shadowsInfo1.z, shadowsInfo1.x);
 #else
 #ifdef SHADOWPCF1
+#if defined(POINTLIGHT1)
+	shadow = computeShadowWithPCFCube(vLightData1.xyz, shadowSampler1, shadowsInfo1.z, shadowsInfo1.x);
+#else
 	shadow = computeShadowWithPCF(vPositionFromLight1, shadowSampler1, shadowsInfo1.y, shadowsInfo1.z, shadowsInfo1.x);
+#endif
 #else
+	#if defined(POINTLIGHT1)
+	shadow = computeShadowCube(vLightData1.xyz, shadowSampler1, shadowsInfo1.x, shadowsInfo1.z);
+	#else
 	shadow = computeShadow(vPositionFromLight1, shadowSampler1, shadowsInfo1.x, shadowsInfo1.z);
+	#endif
 #endif
 #endif
 #else
 	shadow = 1.;
 #endif
 	diffuseBase += info.diffuse * shadow;
-
 #endif
 
 #ifdef LIGHT2
@@ -433,7 +514,7 @@ void main(void) {
 #ifdef HEMILIGHT2
 	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData2, vLightDiffuse2.rgb, vLightGround2);
 #endif
-#ifdef POINTDIRLIGHT2
+#if defined(POINTLIGHT2) || defined(DIRLIGHT2)
 	info = computeLighting(viewDirectionW, normalW, vLightData2, vLightDiffuse2.rgb, vLightDiffuse2.a);
 #endif
 #ifdef SHADOW2
@@ -441,37 +522,51 @@ void main(void) {
 	shadow = computeShadowWithVSM(vPositionFromLight2, shadowSampler2, shadowsInfo2.z, shadowsInfo2.x);
 #else
 #ifdef SHADOWPCF2
+#if defined(POINTLIGHT2)
+	shadow = computeShadowWithPCFCube(vLightData2.xyz, shadowSampler2, shadowsInfo2.z, shadowsInfo2.x);
+#else
 	shadow = computeShadowWithPCF(vPositionFromLight2, shadowSampler2, shadowsInfo2.y, shadowsInfo2.z, shadowsInfo2.x);
+#endif
 #else
+	#if defined(POINTLIGHT2)
+	shadow = computeShadowCube(vLightData2.xyz, shadowSampler2, shadowsInfo2.x, shadowsInfo2.z);
+	#else
 	shadow = computeShadow(vPositionFromLight2, shadowSampler2, shadowsInfo2.x, shadowsInfo2.z);
+	#endif
 #endif	
 #endif	
 #else
 	shadow = 1.;
 #endif
 	diffuseBase += info.diffuse * shadow;
-
 #endif
 
 #ifdef LIGHT3
-
 #ifdef SPOTLIGHT3
 	info = computeSpotLighting(viewDirectionW, normalW, vLightData3, vLightDirection3, vLightDiffuse3.rgb, vLightDiffuse3.a);
 #endif
 #ifdef HEMILIGHT3
 	info = computeHemisphericLighting(viewDirectionW, normalW, vLightData3, vLightDiffuse3.rgb, vLightGround3);
 #endif
-#ifdef POINTDIRLIGHT3
+#if defined(POINTLIGHT3) || defined(DIRLIGHT3)
 	info = computeLighting(viewDirectionW, normalW, vLightData3, vLightDiffuse3.rgb, vLightDiffuse3.a);
 #endif
 #ifdef SHADOW3
 #ifdef SHADOWVSM3
-	shadow = computeShadowWithVSM(vPositionFromLight3, shadowSampler3, shadowsInfo3.z, shadowsInfo3.x);
+		shadow = computeShadowWithVSM(vPositionFromLight3, shadowSampler3, shadowsInfo3.z, shadowsInfo3.x);
 #else
 #ifdef SHADOWPCF3
+#if defined(POINTLIGHT3)
+	shadow = computeShadowWithPCFCube(vLightData3.xyz, shadowSampler3, shadowsInfo3.z, shadowsInfo3.x);
+#else
 	shadow = computeShadowWithPCF(vPositionFromLight3, shadowSampler3, shadowsInfo3.y, shadowsInfo3.z, shadowsInfo3.x);
+#endif
 #else
+	#if defined(POINTLIGHT3)
+	shadow = computeShadowCube(vLightData3.xyz, shadowSampler3, shadowsInfo3.x, shadowsInfo3.z);
+	#else
 	shadow = computeShadow(vPositionFromLight3, shadowSampler3, shadowsInfo3.x, shadowsInfo3.z);
+	#endif
 #endif	
 #endif	
 #else

+ 15 - 14
materialsLibrary/materials/water/water.vertex.fx

@@ -67,19 +67,19 @@ varying float fFogDistance;
 #endif
 
 #ifdef SHADOWS
-#ifdef LIGHT0
+#if defined(SPOTLIGHT0) || defined(DIRLIGHT0)
 uniform mat4 lightMatrix0;
 varying vec4 vPositionFromLight0;
 #endif
-#ifdef LIGHT1
+#if defined(SPOTLIGHT1) || defined(DIRLIGHT1)
 uniform mat4 lightMatrix1;
 varying vec4 vPositionFromLight1;
 #endif
-#ifdef LIGHT2
+#if defined(SPOTLIGHT2) || defined(DIRLIGHT2)
 uniform mat4 lightMatrix2;
 varying vec4 vPositionFromLight2;
 #endif
-#ifdef LIGHT3
+#if defined(SPOTLIGHT3) || defined(DIRLIGHT3)
 uniform mat4 lightMatrix3;
 varying vec4 vPositionFromLight3;
 #endif
@@ -91,14 +91,12 @@ uniform vec2 windDirection;
 uniform float waveLength;
 uniform float time;
 uniform float windForce;
-uniform float bumpHeight;
 uniform float waveHeight;
 
 // Water varyings
 varying vec3 vPosition;
 varying vec3 vRefractionMapTexCoord;
 varying vec3 vReflectionMapTexCoord;
-varying float vWaveHeight;
 
 void main(void) {
 	mat4 finalWorld;
@@ -161,16 +159,16 @@ void main(void) {
 
 	// Shadows
 #ifdef SHADOWS
-#ifdef LIGHT0
+#if defined(SPOTLIGHT0) || defined(DIRLIGHT0)
 	vPositionFromLight0 = lightMatrix0 * worldPos;
 #endif
-#ifdef LIGHT1
+#if defined(SPOTLIGHT1) || defined(DIRLIGHT1)
 	vPositionFromLight1 = lightMatrix1 * worldPos;
 #endif
-#ifdef LIGHT2
+#if defined(SPOTLIGHT2) || defined(DIRLIGHT2)
 	vPositionFromLight2 = lightMatrix2 * worldPos;
 #endif
-#ifdef LIGHT3
+#if defined(SPOTLIGHT3) || defined(DIRLIGHT3)
 	vPositionFromLight3 = lightMatrix3 * worldPos;
 #endif
 #endif
@@ -186,14 +184,16 @@ void main(void) {
 #endif
 
 	vec3 p = position;
-	p.y += (sin(((p.x / 0.05) + time * 100.0)) * waveHeight * 5.0) + (cos(((p.z / 0.05) + time * 100.0)) * waveHeight * 5.0);
+	float newY = (sin(((p.x / 0.05) + time * windForce) * windDirection.x) * waveHeight * 5.0)
+			   + (cos(((p.z / 0.05) + time * windForce) * windDirection.y) * waveHeight * 5.0);
+	p.y += abs(newY);
 	
 	gl_Position = viewProjection * finalWorld * vec4(p, 1.0);
 
-	worldPos = viewProjection * finalWorld * vec4(position, 1.0);
-
+#ifdef REFLECTION
+	worldPos = viewProjection * finalWorld * vec4(p, 1.0);
+	
 	// Water
-	vWaveHeight = bumpHeight;
 	vPosition = position;
 	
 	vRefractionMapTexCoord.x = 0.5 * (worldPos.w + worldPos.x);
@@ -204,4 +204,5 @@ void main(void) {
 	vReflectionMapTexCoord.x = 0.5 * (worldPos.w + worldPos.x);
 	vReflectionMapTexCoord.y = 0.5 * (worldPos.w + worldPos.y);
 	vReflectionMapTexCoord.z = worldPos.w;
+#endif
 }

+ 2 - 0
materialsLibrary/test/index.html

@@ -161,9 +161,11 @@
 				water.bumpTexture = new BABYLON.Texture("textures/waterbump.png", scene);
 				water.windForce = -45;
 				water.waveHeight = 1.3;
+				water.windDirection = new BABYLON.Vector2(1, 1);
 				water.addToRenderList(skybox);
 				water.addToRenderList(shadowCaster);
 				water.addToRenderList(shadowCaster2);
+				water.addToRenderList(shadowCaster3);
 				
 				var fire = new BABYLON.FireMaterial("fire", scene);
 				fire.diffuseTexture = new BABYLON.Texture("textures/fire/diffuse.png", scene);

+ 1 - 0
src/Audio/babylon.sound.js

@@ -87,6 +87,7 @@ var BABYLON;
                             this._htmlAudioElement.src = urlOrArrayBuffer;
                             this._htmlAudioElement.controls = false;
                             this._htmlAudioElement.loop = this.loop;
+                            this._htmlAudioElement.crossOrigin = "anonymous";
                             this._isReadyToPlay = true;
                             document.body.appendChild(this._htmlAudioElement);
                             // Simulating a ready to play event for consistent behavior with non streamed audio source

+ 1 - 0
src/Audio/babylon.sound.ts

@@ -104,6 +104,7 @@
                             this._htmlAudioElement.src = urlOrArrayBuffer;
                             this._htmlAudioElement.controls = false;
                             this._htmlAudioElement.loop = this.loop;
+                            this._htmlAudioElement.crossOrigin = "anonymous"; 
                             this._isReadyToPlay = true;
                             document.body.appendChild(this._htmlAudioElement);
                             // Simulating a ready to play event for consistent behavior with non streamed audio source

+ 8 - 1
src/Lights/Shadows/babylon.shadowGenerator.js

@@ -244,9 +244,16 @@ var BABYLON;
             if (mesh.useBones && mesh.computeBonesUsingShaders) {
                 attribs.push(BABYLON.VertexBuffer.MatricesIndicesKind);
                 attribs.push(BABYLON.VertexBuffer.MatricesWeightsKind);
-                defines.push("#define BONES");
+                if (mesh.numBoneInfluencers > 4) {
+                    attribs.push(BABYLON.VertexBuffer.MatricesIndicesExtraKind);
+                    attribs.push(BABYLON.VertexBuffer.MatricesWeightsExtraKind);
+                }
+                defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
                 defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
             }
+            else {
+                defines.push("#define NUM_BONE_INFLUENCERS 0");
+            }
             // Instances
             if (useInstances) {
                 defines.push("#define INSTANCES");

+ 7 - 1
src/Lights/Shadows/babylon.shadowGenerator.ts

@@ -268,8 +268,14 @@
             if (mesh.useBones && mesh.computeBonesUsingShaders) {
                 attribs.push(VertexBuffer.MatricesIndicesKind);
                 attribs.push(VertexBuffer.MatricesWeightsKind);
-                defines.push("#define BONES");
+                if (mesh.numBoneInfluencers > 4) {
+                    attribs.push(VertexBuffer.MatricesIndicesExtraKind);
+                    attribs.push(VertexBuffer.MatricesWeightsExtraKind);
+                }
+                defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
                 defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
+            } else {
+                defines.push("#define NUM_BONE_INFLUENCERS 0");
             }
 
             // Instances

+ 20 - 0
src/Loading/Plugins/babylon.babylonFileLoader.js

@@ -1084,9 +1084,29 @@ var BABYLON;
                         mesh.setVerticesData(BABYLON.VertexBuffer.MatricesIndicesKind, parsedGeometry.matricesIndices, false);
                     }
                 }
+                if (parsedGeometry.matricesIndicesExtra) {
+                    if (!parsedGeometry.matricesIndicesExtra._isExpanded) {
+                        var floatIndices = [];
+                        for (var i = 0; i < parsedGeometry.matricesIndicesExtra.length; i++) {
+                            var matricesIndex = parsedGeometry.matricesIndicesExtra[i];
+                            floatIndices.push(matricesIndex & 0x000000FF);
+                            floatIndices.push((matricesIndex & 0x0000FF00) >> 8);
+                            floatIndices.push((matricesIndex & 0x00FF0000) >> 16);
+                            floatIndices.push(matricesIndex >> 24);
+                        }
+                        mesh.setVerticesData(BABYLON.VertexBuffer.MatricesIndicesExtraKind, floatIndices, false);
+                    }
+                    else {
+                        delete parsedGeometry.matricesIndices._isExpanded;
+                        mesh.setVerticesData(BABYLON.VertexBuffer.MatricesIndicesExtraKind, parsedGeometry.matricesIndicesExtra, false);
+                    }
+                }
                 if (parsedGeometry.matricesWeights) {
                     mesh.setVerticesData(BABYLON.VertexBuffer.MatricesWeightsKind, parsedGeometry.matricesWeights, false);
                 }
+                if (parsedGeometry.matricesWeightsExtra) {
+                    mesh.setVerticesData(BABYLON.VertexBuffer.MatricesWeightsExtraKind, parsedGeometry.matricesWeightsExtra, false);
+                }
                 mesh.setIndices(parsedGeometry.indices);
             }
             // SubMeshes

+ 24 - 0
src/Loading/Plugins/babylon.babylonFileLoader.ts

@@ -1338,10 +1338,34 @@
                 }
             }
 
+            if (parsedGeometry.matricesIndicesExtra) {
+                if (!parsedGeometry.matricesIndicesExtra._isExpanded) {
+                    var floatIndices = [];
+
+                    for (var i = 0; i < parsedGeometry.matricesIndicesExtra.length; i++) {
+                        var matricesIndex = parsedGeometry.matricesIndicesExtra[i];
+
+                        floatIndices.push(matricesIndex & 0x000000FF);
+                        floatIndices.push((matricesIndex & 0x0000FF00) >> 8);
+                        floatIndices.push((matricesIndex & 0x00FF0000) >> 16);
+                        floatIndices.push(matricesIndex >> 24);
+                    }
+
+                    mesh.setVerticesData(BABYLON.VertexBuffer.MatricesIndicesExtraKind, floatIndices, false);
+                } else {
+                    delete parsedGeometry.matricesIndices._isExpanded;
+                    mesh.setVerticesData(BABYLON.VertexBuffer.MatricesIndicesExtraKind, parsedGeometry.matricesIndicesExtra, false);
+                }
+            }
+
             if (parsedGeometry.matricesWeights) {
                 mesh.setVerticesData(BABYLON.VertexBuffer.MatricesWeightsKind, parsedGeometry.matricesWeights, false);
             }
 
+            if (parsedGeometry.matricesWeightsExtra) {
+                mesh.setVerticesData(BABYLON.VertexBuffer.MatricesWeightsExtraKind, parsedGeometry.matricesWeightsExtra, false);
+            }
+
             mesh.setIndices(parsedGeometry.indices);
         }
 

+ 12 - 0
src/Materials/babylon.effect.js

@@ -18,6 +18,13 @@ var BABYLON;
             }
             this._defines[rank].push(define);
         };
+        EffectFallbacks.prototype.addCPUSkinningFallback = function (rank, mesh) {
+            this._meshRank = rank;
+            this._mesh = mesh;
+            if (rank > this._maxRank) {
+                this._maxRank = rank;
+            }
+        };
         Object.defineProperty(EffectFallbacks.prototype, "isMoreFallbacks", {
             get: function () {
                 return this._currentRank <= this._maxRank;
@@ -30,6 +37,11 @@ var BABYLON;
             for (var index = 0; index < currentFallbacks.length; index++) {
                 currentDefines = currentDefines.replace("#define " + currentFallbacks[index], "");
             }
+            if (this._mesh && this._currentRank === this._meshRank) {
+                this._mesh.computeBonesUsingShaders = false;
+                currentDefines = currentDefines.replace("#define NUM_BONE_INFLUENCERS " + this._mesh.numBoneInfluencers, "#define NUM_BONE_INFLUENCERS 0");
+                BABYLON.Tools.Log("Falling back to CPU skinning for " + this._mesh.name);
+            }
             this._currentRank++;
             return currentDefines;
         };

+ 18 - 0
src/Materials/babylon.effect.ts

@@ -5,6 +5,9 @@
         private _currentRank = 32;
         private _maxRank = -1;
 
+        private _mesh : AbstractMesh;
+        private _meshRank : number;
+
         public addFallback(rank: number, define: string): void {
             if (!this._defines[rank]) {
                 if (rank < this._currentRank) {
@@ -21,6 +24,15 @@
             this._defines[rank].push(define);
         }
 
+            public addCPUSkinningFallback(rank: number, mesh : BABYLON.AbstractMesh){
+                this._meshRank = rank;
+                this._mesh = mesh;
+    
+                if (rank > this._maxRank) {
+                    this._maxRank = rank;
+                }
+            }
+
         public get isMoreFallbacks(): boolean {
             return this._currentRank <= this._maxRank;
         }
@@ -33,6 +45,12 @@
                 currentDefines = currentDefines.replace("#define " + currentFallbacks[index], "");
             }
 
+            if (this._mesh && this._currentRank === this._meshRank){
+                this._mesh.computeBonesUsingShaders = false;
+                currentDefines = currentDefines.replace("#define NUM_BONE_INFLUENCERS " + this._mesh.numBoneInfluencers, "#define NUM_BONE_INFLUENCERS 0");
+                Tools.Log("Falling back to CPU skinning for " + this._mesh.name);
+            }
+
             this._currentRank++;
 
             return currentDefines;

+ 7 - 7
src/Materials/babylon.material.js

@@ -21,22 +21,22 @@ var BABYLON;
         MaterialDefines.prototype.reset = function () {
             for (var index = 0; index < this._keys.length; index++) {
                 var prop = this._keys[index];
-                if (prop === "BonesPerMesh") {
+                if (typeof (this[prop]) === "number") {
                     this[prop] = 0;
-                    continue;
                 }
-                this[prop] = false;
+                else {
+                    this[prop] = false;
+                }
             }
         };
         MaterialDefines.prototype.toString = function () {
             var result = "";
             for (var index = 0; index < this._keys.length; index++) {
                 var prop = this._keys[index];
-                if (prop === "BonesPerMesh" && this[prop] > 0) {
-                    result += "#define BonesPerMesh " + this[prop] + "\n";
-                    continue;
+                if (typeof (this[prop]) === "number") {
+                    result += "#define " + prop + " " + this[prop] + "\n";
                 }
-                if (this[prop]) {
+                else if (this[prop]) {
                     result += "#define " + prop + "\n";
                 }
             }

+ 8 - 10
src/Materials/babylon.material.ts

@@ -26,12 +26,12 @@
             for (var index = 0; index < this._keys.length; index++) {
                 var prop = this._keys[index];
 
-                if (prop === "BonesPerMesh") {
+                if (typeof(this[prop]) === "number") {
                     this[prop] = 0;
-                    continue;
+                
+                }else { 
+                    this[prop] = false; 
                 }
-
-                this[prop] = false;
             }
         }
 
@@ -40,12 +40,10 @@
             for (var index = 0; index < this._keys.length; index++) {
                 var prop = this._keys[index];
 
-                if (prop === "BonesPerMesh" && this[prop] > 0) {
-                    result += "#define BonesPerMesh " + this[prop] + "\n";
-                    continue;
-                }
-
-                if (this[prop]) {
+                if (typeof(this[prop]) === "number") {
+                    result += "#define "  + prop + " " + this[prop] + "\n";
+                
+                }else if (this[prop]) {
                     result += "#define " + prop + "\n";
                 }
             }

+ 7 - 8
src/Materials/babylon.pbrMaterial.js

@@ -19,8 +19,7 @@ var BABYLON;
             this.UV2 = false;
             this.VERTEXCOLOR = false;
             this.VERTEXALPHA = false;
-            this.BONES = false;
-            this.BONES4 = false;
+            this.NUM_BONE_INFLUENCERS = 0;
             this.BonesPerMesh = 0;
             this.INSTANCES = false;
             this.POINTSIZE = false;
@@ -106,9 +105,8 @@ var BABYLON;
                     }
                 }
                 if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.BONES = true;
+                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
                     this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                    this._defines.BONES4 = true;
                 }
                 // Instances
                 if (useInstances) {
@@ -124,9 +122,6 @@ var BABYLON;
                 if (this._defines.FOG) {
                     fallbacks.addFallback(1, "FOG");
                 }
-                if (this._defines.BONES4) {
-                    fallbacks.addFallback(0, "BONES4");
-                }
                 //Attributes
                 var attribs = [BABYLON.VertexBuffer.PositionKind];
                 if (this._defines.NORMAL) {
@@ -141,9 +136,13 @@ var BABYLON;
                 if (this._defines.VERTEXCOLOR) {
                     attribs.push(BABYLON.VertexBuffer.ColorKind);
                 }
-                if (this._defines.BONES) {
+                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
                     attribs.push(BABYLON.VertexBuffer.MatricesIndicesKind);
                     attribs.push(BABYLON.VertexBuffer.MatricesWeightsKind);
+                    if (this._defines.NUM_BONE_INFLUENCERS > 4) {
+                        attribs.push(BABYLON.VertexBuffer.MatricesIndicesExtraKind);
+                        attribs.push(BABYLON.VertexBuffer.MatricesWeightsExtraKind);
+                    }
                 }
                 if (this._defines.INSTANCES) {
                     attribs.push("world0");

+ 7 - 8
src/Materials/babylon.pbrMaterial.ts

@@ -11,8 +11,7 @@
         public UV2 = false;
         public VERTEXCOLOR = false;
         public VERTEXALPHA = false;
-        public BONES = false;
-        public BONES4 = false;
+        public NUM_BONE_INFLUENCERS = 0;
         public BonesPerMesh = 0;
         public INSTANCES = false;
         public POINTSIZE = false;
@@ -121,9 +120,8 @@
                     }
                 }
                 if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.BONES = true;
+                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
                     this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                    this._defines.BONES4 = true;
                 }
 
                 // Instances
@@ -144,9 +142,6 @@
                     fallbacks.addFallback(1, "FOG");
                 }             
 
-                if (this._defines.BONES4) {
-                    fallbacks.addFallback(0, "BONES4");
-                }
 
                 //Attributes
                 var attribs = [VertexBuffer.PositionKind];
@@ -167,9 +162,13 @@
                     attribs.push(VertexBuffer.ColorKind);
                 }
 
-                if (this._defines.BONES) {
+                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
                     attribs.push(VertexBuffer.MatricesIndicesKind);
                     attribs.push(VertexBuffer.MatricesWeightsKind);
+                    if (this._defines.NUM_BONE_INFLUENCERS > 4) {
+                        attribs.push(VertexBuffer.MatricesIndicesExtraKind);
+                        attribs.push(VertexBuffer.MatricesWeightsExtraKind);
+                    }
                 }
 
                 if (this._defines.INSTANCES) {

+ 2 - 3
src/Materials/babylon.shaderMaterial.js

@@ -117,10 +117,9 @@ var BABYLON;
             }
             // Bones
             if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
-                defines.push("#define BONES");
+                defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
                 defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
-                defines.push("#define BONES4");
-                fallbacks.addFallback(0, "BONES4");
+                fallbacks.addCPUSkinningFallback(0, mesh);
             }
             // Alpha test
             if (engine.getAlphaTesting()) {

+ 2 - 3
src/Materials/babylon.shaderMaterial.ts

@@ -146,10 +146,9 @@
 
             // Bones
             if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
-                defines.push("#define BONES");
+                defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
                 defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
-                defines.push("#define BONES4");
-                fallbacks.addFallback(0, "BONES4");
+                fallbacks.addCPUSkinningFallback(0, mesh);
             }
 
             // Alpha test

+ 9 - 7
src/Materials/babylon.standardMaterial.js

@@ -84,8 +84,7 @@ var BABYLON;
             this.UV2 = false;
             this.VERTEXCOLOR = false;
             this.VERTEXALPHA = false;
-            this.BONES = false;
-            this.BONES4 = false;
+            this.NUM_BONE_INFLUENCERS = 0;
             this.BonesPerMesh = 0;
             this.INSTANCES = false;
             this.GLOSSINESS = false;
@@ -489,9 +488,8 @@ var BABYLON;
                     }
                 }
                 if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.BONES = true;
+                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
                     this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                    this._defines.BONES4 = true;
                 }
                 // Instances
                 if (useInstances) {
@@ -554,8 +552,8 @@ var BABYLON;
                 if (this._defines.FRESNEL) {
                     fallbacks.addFallback(4, "FRESNEL");
                 }
-                if (this._defines.BONES4) {
-                    fallbacks.addFallback(0, "BONES4");
+                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
+                    fallbacks.addCPUSkinningFallback(0, mesh);
                 }
                 //Attributes
                 var attribs = [BABYLON.VertexBuffer.PositionKind];
@@ -571,9 +569,13 @@ var BABYLON;
                 if (this._defines.VERTEXCOLOR) {
                     attribs.push(BABYLON.VertexBuffer.ColorKind);
                 }
-                if (this._defines.BONES) {
+                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
                     attribs.push(BABYLON.VertexBuffer.MatricesIndicesKind);
                     attribs.push(BABYLON.VertexBuffer.MatricesWeightsKind);
+                    if (this._defines.NUM_BONE_INFLUENCERS > 4) {
+                        attribs.push(BABYLON.VertexBuffer.MatricesIndicesExtraKind);
+                        attribs.push(BABYLON.VertexBuffer.MatricesWeightsExtraKind);
+                    }
                 }
                 if (this._defines.INSTANCES) {
                     attribs.push("world0");

+ 9 - 7
src/Materials/babylon.standardMaterial.ts

@@ -76,8 +76,7 @@
         public UV2 = false;
         public VERTEXCOLOR = false;
         public VERTEXALPHA = false;
-        public BONES = false;
-        public BONES4 = false;
+        public NUM_BONE_INFLUENCERS = 0;
         public BonesPerMesh = 0;
         public INSTANCES = false;
         public GLOSSINESS = false;
@@ -565,9 +564,8 @@
                     }
                 }
                 if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._defines.BONES = true;
+                    this._defines.NUM_BONE_INFLUENCERS = mesh.numBoneInfluencers;
                     this._defines.BonesPerMesh = (mesh.skeleton.bones.length + 1);
-                    this._defines.BONES4 = true;
                 }
 
                 // Instances
@@ -650,8 +648,8 @@
                     fallbacks.addFallback(4, "FRESNEL");
                 }
 
-                if (this._defines.BONES4) {
-                    fallbacks.addFallback(0, "BONES4");
+                if (this._defines.NUM_BONE_INFLUENCERS > 0){
+                    fallbacks.addCPUSkinningFallback(0, mesh);    
                 }
 
                 //Attributes
@@ -673,9 +671,13 @@
                     attribs.push(VertexBuffer.ColorKind);
                 }
 
-                if (this._defines.BONES) {
+                if (this._defines.NUM_BONE_INFLUENCERS > 0) {
                     attribs.push(VertexBuffer.MatricesIndicesKind);
                     attribs.push(VertexBuffer.MatricesWeightsKind);
+                    if (this._defines.NUM_BONE_INFLUENCERS > 4) {
+                        attribs.push(VertexBuffer.MatricesIndicesExtraKind);
+                        attribs.push(VertexBuffer.MatricesWeightsExtraKind);
+                    }
                 }
 
                 if (this._defines.INSTANCES) {

+ 5 - 0
src/Mesh/babylon.abstractMesh.ts

@@ -84,6 +84,7 @@
         private _diffPositionForCollisions = new Vector3(0, 0, 0);
         private _newPositionForCollisions = new Vector3(0, 0, 0);
         public onCollide: (collidedMesh: AbstractMesh) => void;
+        public onCollisionPositionChange: (newPosition: Vector3) => void;
 
         // Attach to bone
         private _meshToBoneReferal: AbstractMesh;
@@ -803,6 +804,10 @@
             if (this.onCollide && collidedMesh) {
                 this.onCollide(collidedMesh);
             }
+            
+            if(this.onCollisionPositionChange) {
+                this.onCollisionPositionChange(this.position);
+            }
         }
 
         // Submeshes octree

+ 17 - 3
src/Mesh/babylon.mesh.js

@@ -1333,13 +1333,17 @@ var BABYLON;
             }
             var matricesIndicesData = this.getVerticesData(BABYLON.VertexBuffer.MatricesIndicesKind);
             var matricesWeightsData = this.getVerticesData(BABYLON.VertexBuffer.MatricesWeightsKind);
+            var needExtras = this.numBoneInfluencers > 4;
+            var matricesIndicesExtraData = needExtras ? this.getVerticesData(BABYLON.VertexBuffer.MatricesIndicesExtraKind) : null;
+            var matricesWeightsExtraData = needExtras ? this.getVerticesData(BABYLON.VertexBuffer.MatricesWeightsExtraKind) : null;
             var skeletonMatrices = skeleton.getTransformMatrices();
             var tempVector3 = BABYLON.Vector3.Zero();
             var finalMatrix = new BABYLON.Matrix();
             var tempMatrix = new BABYLON.Matrix();
             var matWeightIdx = 0;
-            for (var index = 0; index < positionsData.length; index += 3) {
-                for (var inf = 0; inf < this.numBoneInfluencers; inf++) {
+            var inf;
+            for (var index = 0; index < positionsData.length; index += 3, matWeightIdx += 4) {
+                for (inf = 0; inf < 4; inf++) {
                     var weight = matricesWeightsData[matWeightIdx + inf];
                     if (weight > 0) {
                         BABYLON.Matrix.FromFloat32ArrayToRefScaled(skeletonMatrices, matricesIndicesData[matWeightIdx + inf] * 16, weight, tempMatrix);
@@ -1348,7 +1352,17 @@ var BABYLON;
                     else
                         break;
                 }
-                matWeightIdx += this.numBoneInfluencers;
+                if (needExtras) {
+                    for (inf = 0; inf < 4; inf++) {
+                        var weight = matricesWeightsExtraData[matWeightIdx + inf];
+                        if (weight > 0) {
+                            BABYLON.Matrix.FromFloat32ArrayToRefScaled(skeletonMatrices, matricesIndicesExtraData[matWeightIdx + inf] * 16, weight, tempMatrix);
+                            finalMatrix.addToSelf(tempMatrix);
+                        }
+                        else
+                            break;
+                    }
+                }
                 BABYLON.Vector3.TransformCoordinatesFromFloatsToRef(this._sourcePositions[index], this._sourcePositions[index + 1], this._sourcePositions[index + 2], finalMatrix, tempVector3);
                 tempVector3.toArray(positionsData, index);
                 BABYLON.Vector3.TransformNormalFromFloatsToRef(this._sourceNormals[index], this._sourceNormals[index + 1], this._sourceNormals[index + 2], finalMatrix, tempVector3);

+ 18 - 4
src/Mesh/babylon.mesh.ts

@@ -1560,6 +1560,10 @@
             var matricesIndicesData = this.getVerticesData(VertexBuffer.MatricesIndicesKind);
             var matricesWeightsData = this.getVerticesData(VertexBuffer.MatricesWeightsKind);
 
+            var needExtras = this.numBoneInfluencers > 4;
+            var matricesIndicesExtraData = needExtras ? this.getVerticesData(VertexBuffer.MatricesIndicesExtraKind) : null;
+            var matricesWeightsExtraData = needExtras ? this.getVerticesData(VertexBuffer.MatricesWeightsExtraKind) : null;
+
             var skeletonMatrices = skeleton.getTransformMatrices();
 
             var tempVector3 = Vector3.Zero();
@@ -1567,8 +1571,9 @@
             var tempMatrix = new Matrix();
 
             var matWeightIdx = 0;
-            for (var index = 0; index < positionsData.length; index += 3) {
-                for (var inf = 0; inf < this.numBoneInfluencers; inf++) {
+            var inf : number;
+            for (var index = 0; index < positionsData.length; index += 3, matWeightIdx += 4) {
+                for (inf = 0; inf < 4; inf++) {
                     var weight = matricesWeightsData[matWeightIdx + inf];
                     if (weight > 0) {
                         Matrix.FromFloat32ArrayToRefScaled(skeletonMatrices, matricesIndicesData[matWeightIdx + inf] * 16, weight, tempMatrix);
@@ -1576,8 +1581,17 @@
 
                     } else break;
                 }
-                matWeightIdx += this.numBoneInfluencers;
-
+                if (needExtras) {
+                    for (inf = 0; inf < 4; inf++) {
+                        var weight = matricesWeightsExtraData[matWeightIdx + inf];
+                        if (weight > 0) {
+                            Matrix.FromFloat32ArrayToRefScaled(skeletonMatrices, matricesIndicesExtraData[matWeightIdx + inf] * 16, weight, tempMatrix);
+                            finalMatrix.addToSelf(tempMatrix);
+
+                        } else break;           
+                    }
+                }
+                
                 Vector3.TransformCoordinatesFromFloatsToRef(this._sourcePositions[index], this._sourcePositions[index + 1], this._sourcePositions[index + 2], finalMatrix, tempVector3);
                 tempVector3.toArray(positionsData, index);
 

+ 53 - 7
src/Mesh/babylon.mesh.vertexData.js

@@ -38,6 +38,12 @@ var BABYLON;
                 case BABYLON.VertexBuffer.MatricesWeightsKind:
                     this.matricesWeights = data;
                     break;
+                case BABYLON.VertexBuffer.MatricesIndicesExtraKind:
+                    this.matricesIndicesExtra = data;
+                    break;
+                case BABYLON.VertexBuffer.MatricesWeightsExtraKind:
+                    this.matricesWeightsExtra = data;
+                    break;
             }
         };
         VertexData.prototype.applyToMesh = function (mesh, updatable) {
@@ -86,6 +92,12 @@ var BABYLON;
             if (this.matricesWeights) {
                 meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.MatricesWeightsKind, this.matricesWeights, updatable);
             }
+            if (this.matricesIndicesExtra) {
+                meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.MatricesIndicesExtraKind, this.matricesIndicesExtra, updatable);
+            }
+            if (this.matricesWeightsExtra) {
+                meshOrGeometry.setVerticesData(BABYLON.VertexBuffer.MatricesWeightsExtraKind, this.matricesWeightsExtra, updatable);
+            }
             if (this.indices) {
                 meshOrGeometry.setIndices(this.indices);
             }
@@ -124,6 +136,12 @@ var BABYLON;
             if (this.matricesWeights) {
                 meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.MatricesWeightsKind, this.matricesWeights, updateExtends, makeItUnique);
             }
+            if (this.matricesIndicesExtra) {
+                meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.MatricesIndicesExtraKind, this.matricesIndicesExtra, updateExtends, makeItUnique);
+            }
+            if (this.matricesWeightsExtra) {
+                meshOrGeometry.updateVerticesData(BABYLON.VertexBuffer.MatricesWeightsExtraKind, this.matricesWeightsExtra, updateExtends, makeItUnique);
+            }
             if (this.indices) {
                 meshOrGeometry.setIndices(this.indices);
             }
@@ -243,6 +261,22 @@ var BABYLON;
                     this.matricesWeights.push(other.matricesWeights[index]);
                 }
             }
+            if (other.matricesIndicesExtra) {
+                if (!this.matricesIndicesExtra) {
+                    this.matricesIndicesExtra = [];
+                }
+                for (index = 0; index < other.matricesIndicesExtra.length; index++) {
+                    this.matricesIndicesExtra.push(other.matricesIndicesExtra[index]);
+                }
+            }
+            if (other.matricesWeightsExtra) {
+                if (!this.matricesWeightsExtra) {
+                    this.matricesWeightsExtra = [];
+                }
+                for (index = 0; index < other.matricesWeightsExtra.length; index++) {
+                    this.matricesWeightsExtra.push(other.matricesWeightsExtra[index]);
+                }
+            }
             if (other.colors) {
                 if (!this.colors) {
                     this.colors = [];
@@ -294,6 +328,12 @@ var BABYLON;
             if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsKind)) {
                 result.matricesWeights = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.MatricesWeightsKind, copyWhenShared);
             }
+            if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesIndicesExtraKind)) {
+                result.matricesIndicesExtra = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.MatricesIndicesExtraKind, copyWhenShared);
+            }
+            if (meshOrGeometry.isVerticesDataPresent(BABYLON.VertexBuffer.MatricesWeightsExtraKind)) {
+                result.matricesWeightsExtra = meshOrGeometry.getVerticesData(BABYLON.VertexBuffer.MatricesWeightsExtraKind, copyWhenShared);
+            }
             result.indices = meshOrGeometry.getIndices(copyWhenShared);
             return result;
         };
@@ -1095,8 +1135,11 @@ var BABYLON;
         VertexData.CreateIcoSphere = function (options) {
             var sideOrientation = options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
             var radius = options.radius || 1;
-            var flat = options.flat || false;
-            var subdivisions = options.subdivisions || 1;
+            var flat = (options.flat === undefined) ? true : options.flat;
+            var subdivisions = options.subdivisions || 4;
+            var radiusX = options.radiusX || radius;
+            var radiusY = options.radiusY || radius;
+            var radiusZ = options.radiusZ || radius;
             var t = (1 + Math.sqrt(5)) / 2;
             // 12 vertex x,y,z
             var ico_vertices = [
@@ -1245,7 +1288,10 @@ var BABYLON;
                     var pos_x0 = BABYLON.Vector3.Lerp(face_vertex_pos[0], face_vertex_pos[2], i2 / subdivisions);
                     var pos_x1 = BABYLON.Vector3.Lerp(face_vertex_pos[1], face_vertex_pos[2], i2 / subdivisions);
                     var pos_interp = (subdivisions === i2) ? face_vertex_pos[2] : BABYLON.Vector3.Lerp(pos_x0, pos_x1, i1 / (subdivisions - i2));
-                    pos_interp.normalize().scaleInPlace(radius);
+                    pos_interp.normalize();
+                    pos_interp.x *= radiusX;
+                    pos_interp.y *= radiusY;
+                    pos_interp.z *= radiusZ;
                     var vertex_normal;
                     if (flat) {
                         // in flat mode, recalculate normal as face centroid normal
@@ -1338,7 +1384,7 @@ var BABYLON;
             var nbfaces = data.face.length;
             var faceUV = options.faceUV || new Array(nbfaces);
             var faceColors = options.faceColors;
-            var singleFace = options.singleFace;
+            var flat = (options.flat === undefined) ? true : options.flat;
             var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
             var positions = [];
             var indices = [];
@@ -1352,7 +1398,7 @@ var BABYLON;
             var f = 0;
             var u, v, ang, x, y, tmp;
             // default face colors and UV if undefined
-            if (!singleFace) {
+            if (flat) {
                 for (f = 0; f < nbfaces; f++) {
                     if (faceColors && faceColors[f] === undefined) {
                         faceColors[f] = new BABYLON.Color4(1, 1, 1, 1);
@@ -1362,7 +1408,7 @@ var BABYLON;
                     }
                 }
             }
-            if (singleFace) {
+            if (!flat) {
                 for (i = 0; i < data.vertex.length; i++) {
                     positions.push(data.vertex[i][0] * sizeX, data.vertex[i][1] * sizeY, data.vertex[i][2] * sizeZ);
                     uvs.push(0, 0);
@@ -1411,7 +1457,7 @@ var BABYLON;
             vertexData.indices = indices;
             vertexData.normals = normals;
             vertexData.uvs = uvs;
-            if (faceColors && !singleFace) {
+            if (faceColors && flat) {
                 vertexData.colors = colors;
             }
             return vertexData;

+ 65 - 9
src/Mesh/babylon.mesh.vertexData.ts

@@ -20,6 +20,8 @@
         public colors: number[] | Float32Array;
         public matricesIndices: number[] | Float32Array;
         public matricesWeights: number[] | Float32Array;
+        public matricesIndicesExtra: number[] | Float32Array;
+        public matricesWeightsExtra: number[] | Float32Array;
         public indices: number[];
 
         public set(data: number[] | Float32Array, kind: string) {
@@ -57,6 +59,12 @@
                 case VertexBuffer.MatricesWeightsKind:
                     this.matricesWeights = data;
                     break;
+                case VertexBuffer.MatricesIndicesExtraKind:
+                    this.matricesIndicesExtra = data;
+                    break;
+                case VertexBuffer.MatricesWeightsExtraKind:
+                    this.matricesWeightsExtra = data;
+                    break;
             }
         }
 
@@ -121,6 +129,14 @@
                 meshOrGeometry.setVerticesData(VertexBuffer.MatricesWeightsKind, this.matricesWeights, updatable);
             }
 
+            if (this.matricesIndicesExtra) {
+                meshOrGeometry.setVerticesData(VertexBuffer.MatricesIndicesExtraKind, this.matricesIndicesExtra, updatable);
+            }
+
+            if (this.matricesWeightsExtra) {
+                meshOrGeometry.setVerticesData(VertexBuffer.MatricesWeightsExtraKind, this.matricesWeightsExtra, updatable);
+            }
+
             if (this.indices) {
                 meshOrGeometry.setIndices(this.indices);
             }
@@ -171,6 +187,14 @@
                 meshOrGeometry.updateVerticesData(VertexBuffer.MatricesWeightsKind, this.matricesWeights, updateExtends, makeItUnique);
             }
 
+            if (this.matricesIndicesExtra) {
+                meshOrGeometry.updateVerticesData(VertexBuffer.MatricesIndicesExtraKind, this.matricesIndicesExtra, updateExtends, makeItUnique);
+            }
+
+            if (this.matricesWeightsExtra) {
+                meshOrGeometry.updateVerticesData(VertexBuffer.MatricesWeightsExtraKind, this.matricesWeightsExtra, updateExtends, makeItUnique);
+            }
+
             if (this.indices) {
                 meshOrGeometry.setIndices(this.indices);
             }
@@ -310,6 +334,24 @@
                 }
             }
 
+            if (other.matricesIndicesExtra) {
+                if (!this.matricesIndicesExtra) {
+                    this.matricesIndicesExtra = [];
+                }
+                for (index = 0; index < other.matricesIndicesExtra.length; index++) {
+                    (<number[]>this.matricesIndicesExtra).push(other.matricesIndicesExtra[index]);
+                }
+            }
+
+            if (other.matricesWeightsExtra) {
+                if (!this.matricesWeightsExtra) {
+                    this.matricesWeightsExtra = [];
+                }
+                for (index = 0; index < other.matricesWeightsExtra.length; index++) {
+                    (<number[]>this.matricesWeightsExtra).push(other.matricesWeightsExtra[index]);
+                }
+            }
+
             if (other.colors) {
                 if (!this.colors) {
                     this.colors = [];
@@ -376,6 +418,14 @@
                 result.matricesWeights = meshOrGeometry.getVerticesData(VertexBuffer.MatricesWeightsKind, copyWhenShared);
             }
 
+            if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.MatricesIndicesExtraKind)) {
+                result.matricesIndicesExtra = meshOrGeometry.getVerticesData(VertexBuffer.MatricesIndicesExtraKind, copyWhenShared);
+            }
+
+            if (meshOrGeometry.isVerticesDataPresent(VertexBuffer.MatricesWeightsExtraKind)) {
+                result.matricesWeightsExtra = meshOrGeometry.getVerticesData(VertexBuffer.MatricesWeightsExtraKind, copyWhenShared);
+            }
+
             result.indices = meshOrGeometry.getIndices(copyWhenShared);
 
             return result;
@@ -1335,11 +1385,14 @@
             return vertexData;
         }
 
-        public static CreateIcoSphere(options: {radius?: number, flat?: number, subdivisions?: number, sideOrientation?: number}): VertexData {
+        public static CreateIcoSphere(options: {radius?: number, radiusX?: number, radiusY?: number, radiusZ?: number, flat?: number, subdivisions?: number, sideOrientation?: number}): VertexData {
             var sideOrientation = options.sideOrientation || Mesh.DEFAULTSIDE;
             var radius = options.radius || 1;
-            var flat = options.flat || false;
-            var subdivisions = options.subdivisions || 1;
+            var flat = (options.flat === undefined) ? true : options.flat;
+            var subdivisions = options.subdivisions || 4;
+            var radiusX = options.radiusX || radius;
+            var radiusY = options.radiusY || radius;
+            var radiusZ = options.radiusZ || radius;
 
             var t = (1 + Math.sqrt(5)) / 2;
 
@@ -1478,7 +1531,10 @@
                     var pos_x0 = Vector3.Lerp(face_vertex_pos[0], face_vertex_pos[2], i2 / subdivisions);
                     var pos_x1 = Vector3.Lerp(face_vertex_pos[1], face_vertex_pos[2], i2 / subdivisions);
                     var pos_interp = (subdivisions === i2) ? face_vertex_pos[2] : Vector3.Lerp(pos_x0, pos_x1, i1 / (subdivisions - i2));
-                    pos_interp.normalize().scaleInPlace(radius);
+                    pos_interp.normalize();
+                    pos_interp.x *= radiusX;
+                    pos_interp.y *= radiusY;
+                    pos_interp.z *= radiusZ;
 
                     var vertex_normal;
                     if (flat) {
@@ -1537,7 +1593,7 @@
 
 
         // inspired from // http://stemkoski.github.io/Three.js/Polyhedra.html
-        public static CreatePolyhedron(options: { type?: number, size?: number, sizeX?: number, sizeY?: number, sizeZ?: number, custom?: any, faceUV?: Vector4[], faceColors?: Color4[], singleFace?: boolean, sideOrientation?: number }): VertexData {
+        public static CreatePolyhedron(options: { type?: number, size?: number, sizeX?: number, sizeY?: number, sizeZ?: number, custom?: any, faceUV?: Vector4[], faceColors?: Color4[], flat?: boolean, sideOrientation?: number }): VertexData {
             // provided polyhedron types :
             // 0 : Tetrahedron, 1 : Octahedron, 2 : Dodecahedron, 3 : Icosahedron, 4 : Rhombicuboctahedron, 5 : Triangular Prism, 6 : Pentagonal Prism, 7 : Hexagonal Prism, 8 : Square Pyramid (J1)
             // 9 : Pentagonal Pyramid (J2), 10 : Triangular Dipyramid (J12), 11 : Pentagonal Dipyramid (J13), 12 : Elongated Square Dipyramid (J15), 13 : Elongated Pentagonal Dipyramid (J16), 14 : Elongated Pentagonal Cupola (J20)
@@ -1579,7 +1635,7 @@
             var nbfaces = data.face.length;
             var faceUV = options.faceUV || new Array(nbfaces);
             var faceColors = options.faceColors;
-            var singleFace = options.singleFace;
+            var flat = (options.flat === undefined) ? true : options.flat;
             var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || Mesh.DEFAULTSIDE;
 
             var positions = [];
@@ -1596,7 +1652,7 @@
 
 
             // default face colors and UV if undefined
-            if (!singleFace) {
+            if (flat) {
                 for (f = 0; f < nbfaces; f++) {
                     if (faceColors && faceColors[f] === undefined) {
                         faceColors[f] = new Color4(1, 1, 1, 1);
@@ -1607,7 +1663,7 @@
                 }
             }
 
-            if (singleFace) {
+            if (!flat) {
 
                 for (i = 0; i < data.vertex.length; i++) {
                     positions.push(data.vertex[i][0] * sizeX, data.vertex[i][1] * sizeY, data.vertex[i][2] * sizeZ);
@@ -1662,7 +1718,7 @@
             vertexData.indices = indices;
             vertexData.normals = normals;
             vertexData.uvs = uvs;
-            if (faceColors && !singleFace) {
+            if (faceColors && flat) {
                 vertexData.colors = colors;
             }
             return vertexData;

+ 2 - 2
src/Mesh/babylon.meshBuilder.ts

@@ -27,7 +27,7 @@
             return disc;
         }
 
-        public static CreateIcoSphere(name: string, options: { radius?: number, flat?: number, subdivisions?: number, sideOrientation?: number, updatable?: boolean }, scene: Scene): Mesh {
+        public static CreateIcoSphere(name: string, options: { radius?: number, radiusX?: number, radiusY?: number, radiusZ?: number, flat?: number, subdivisions?: number, sideOrientation?: number, updatable?: boolean }, scene: Scene): Mesh {
             var sphere = new Mesh(name, scene);
             var vertexData = VertexData.CreateIcoSphere(options);
 
@@ -496,7 +496,7 @@
             return tube;
         }
 
-        public static CreatePolyhedron(name: string, options: { type?: number, size?: number, sizeX?: number, sizeY?: number, sizeZ?: number, custom?: any, faceUV?: Vector4[], faceColors?: Color4[], singleFace?: boolean, updatable?: boolean, sideOrientation?: number }, scene: Scene): Mesh {
+        public static CreatePolyhedron(name: string, options: { type?: number, size?: number, sizeX?: number, sizeY?: number, sizeZ?: number, custom?: any, faceUV?: Vector4[], faceColors?: Color4[], flat?: boolean, updatable?: boolean, sideOrientation?: number }, scene: Scene): Mesh {
             var polyhedron = new Mesh(name, scene);
 
             var vertexData = VertexData.CreatePolyhedron(options);

+ 18 - 0
src/Mesh/babylon.vertexBuffer.js

@@ -38,9 +38,11 @@ var BABYLON;
                     this._strideSize = 4;
                     break;
                 case VertexBuffer.MatricesIndicesKind:
+                case VertexBuffer.MatricesIndicesExtraKind:
                     this._strideSize = 4;
                     break;
                 case VertexBuffer.MatricesWeightsKind:
+                case VertexBuffer.MatricesWeightsExtraKind:
                     this._strideSize = 4;
                     break;
             }
@@ -174,6 +176,20 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        Object.defineProperty(VertexBuffer, "MatricesIndicesExtraKind", {
+            get: function () {
+                return VertexBuffer._MatricesIndicesExtraKind;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(VertexBuffer, "MatricesWeightsExtraKind", {
+            get: function () {
+                return VertexBuffer._MatricesWeightsExtraKind;
+            },
+            enumerable: true,
+            configurable: true
+        });
         // Enums
         VertexBuffer._PositionKind = "position";
         VertexBuffer._NormalKind = "normal";
@@ -186,6 +202,8 @@ var BABYLON;
         VertexBuffer._ColorKind = "color";
         VertexBuffer._MatricesIndicesKind = "matricesIndices";
         VertexBuffer._MatricesWeightsKind = "matricesWeights";
+        VertexBuffer._MatricesIndicesExtraKind = "matricesIndicesExtra";
+        VertexBuffer._MatricesWeightsExtraKind = "matricesWeightsExtra";
         return VertexBuffer;
     })();
     BABYLON.VertexBuffer = VertexBuffer;

+ 12 - 0
src/Mesh/babylon.vertexBuffer.ts

@@ -51,9 +51,11 @@
                     this._strideSize = 4;
                     break;
                 case VertexBuffer.MatricesIndicesKind:
+                case VertexBuffer.MatricesIndicesExtraKind:
                     this._strideSize = 4;
                     break;
                 case VertexBuffer.MatricesWeightsKind:
+                case VertexBuffer.MatricesWeightsExtraKind:
                     this._strideSize = 4;
                     break;
             }
@@ -134,6 +136,8 @@
         private static _ColorKind = "color";
         private static _MatricesIndicesKind = "matricesIndices";
         private static _MatricesWeightsKind = "matricesWeights";
+        private static _MatricesIndicesExtraKind = "matricesIndicesExtra";
+        private static _MatricesWeightsExtraKind = "matricesWeightsExtra";
 
         public static get PositionKind(): string {
             return VertexBuffer._PositionKind;
@@ -178,5 +182,13 @@
         public static get MatricesWeightsKind(): string {
             return VertexBuffer._MatricesWeightsKind;
         }
+
+        public static get MatricesIndicesExtraKind(): string {
+            return VertexBuffer._MatricesIndicesExtraKind;
+        }
+
+        public static get MatricesWeightsExtraKind(): string {
+            return VertexBuffer._MatricesWeightsExtraKind;
+        }
     }
 } 

+ 8 - 1
src/Particles/babylon.solidParticleSystem.ts

@@ -8,6 +8,7 @@ module BABYLON {
         public counter: number = 0;
         public name: string;
         public mesh: Mesh;
+        public vars: any = {};
         
         // private members
         private _scene: Scene;
@@ -57,6 +58,7 @@ module BABYLON {
         private _cosPitch: number = 0.0;
         private _sinYaw: number = 0.0;
         private _cosYaw: number = 0.0;
+        private _w: number = 0.0;
 
 
         constructor(name: string, scene: Scene, options?: { updatable?: boolean }) {
@@ -398,7 +400,11 @@ module BABYLON {
                     this._vertex.y *= this._particle.scale.y;
                     this._vertex.z *= this._particle.scale.z;
 
-                    Vector3.TransformCoordinatesToRef(this._vertex, this._rotMatrix, this._rotated);
+                    //Vector3.TransformCoordinatesToRef(this._vertex, this._rotMatrix, this._rotated);
+                    this._w = (this._vertex.x * this._rotMatrix.m[3]) + (this._vertex.y * this._rotMatrix.m[7]) + (this._vertex.z * this._rotMatrix.m[11]) + this._rotMatrix.m[15];
+                    this._rotated.x = ( (this._vertex.x * this._rotMatrix.m[0]) + (this._vertex.y * this._rotMatrix.m[4]) + (this._vertex.z * this._rotMatrix.m[8]) + this._rotMatrix.m[12] ) / this._w;
+                    this._rotated.y = ( (this._vertex.x * this._rotMatrix.m[1]) + (this._vertex.y * this._rotMatrix.m[5]) + (this._vertex.z * this._rotMatrix.m[9]) + this._rotMatrix.m[13] ) / this._w;
+                    this._rotated.z = ( (this._vertex.x * this._rotMatrix.m[2]) + (this._vertex.y * this._rotMatrix.m[6]) + (this._vertex.z * this._rotMatrix.m[10]) + this._rotMatrix.m[14] ) / this._w;
 
                     this._positions32[idx] = this._particle.position.x + this._cam_axisX.x * this._rotated.x + this._cam_axisY.x * this._rotated.y + this._cam_axisZ.x * this._rotated.z;
                     this._positions32[idx + 1] = this._particle.position.y + this._cam_axisX.y * this._rotated.x + this._cam_axisY.y * this._rotated.y + this._cam_axisZ.y * this._rotated.z;
@@ -475,6 +481,7 @@ module BABYLON {
         // dispose the SPS
         public dispose(): void {
             this.mesh.dispose();
+            this.vars = null;
             // drop references to internal big arrays for the GC
             this._positions = null;
             this._indices = null;

+ 4 - 1
src/PostProcess/babylon.volumetricLightScatteringPostProcess.js

@@ -130,9 +130,12 @@ var BABYLON;
             if (mesh.useBones && mesh.computeBonesUsingShaders) {
                 attribs.push(BABYLON.VertexBuffer.MatricesIndicesKind);
                 attribs.push(BABYLON.VertexBuffer.MatricesWeightsKind);
-                defines.push("#define BONES");
+                defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
                 defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
             }
+            else {
+                defines.push("#define NUM_BONE_INFLUENCERS 0");
+            }
             // Instances
             if (useInstances) {
                 defines.push("#define INSTANCES");

+ 4 - 1
src/PostProcess/babylon.volumetricLightScatteringPostProcess.ts

@@ -146,9 +146,12 @@
             if (mesh.useBones && mesh.computeBonesUsingShaders) {
                 attribs.push(VertexBuffer.MatricesIndicesKind);
                 attribs.push(VertexBuffer.MatricesWeightsKind);
-                defines.push("#define BONES");
+                defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
                 defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
+            } else {
+                defines.push("#define NUM_BONE_INFLUENCERS 0"); 
             }
+            
 
             // Instances
             if (useInstances) {

+ 8 - 1
src/Rendering/babylon.depthRenderer.js

@@ -86,9 +86,16 @@ var BABYLON;
             if (mesh.useBones && mesh.computeBonesUsingShaders) {
                 attribs.push(BABYLON.VertexBuffer.MatricesIndicesKind);
                 attribs.push(BABYLON.VertexBuffer.MatricesWeightsKind);
-                defines.push("#define BONES");
+                if (mesh.numBoneInfluencers > 4) {
+                    attribs.push(BABYLON.VertexBuffer.MatricesIndicesExtraKind);
+                    attribs.push(BABYLON.VertexBuffer.MatricesWeightsExtraKind);
+                }
+                defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
                 defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
             }
+            else {
+                defines.push("#define NUM_BONE_INFLUENCERS 0");
+            }
             // Instances
             if (useInstances) {
                 defines.push("#define INSTANCES");

+ 7 - 1
src/Rendering/babylon.depthRenderer.ts

@@ -112,8 +112,14 @@
             if (mesh.useBones && mesh.computeBonesUsingShaders) {
                 attribs.push(VertexBuffer.MatricesIndicesKind);
                 attribs.push(VertexBuffer.MatricesWeightsKind);
-                defines.push("#define BONES");
+                if (mesh.numBoneInfluencers > 4) {
+                    attribs.push(VertexBuffer.MatricesIndicesExtraKind);
+                    attribs.push(VertexBuffer.MatricesWeightsExtraKind);
+                }
+                defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
                 defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
+            } else {
+                defines.push("#define NUM_BONE_INFLUENCERS 0");
             }
 
             // Instances

+ 8 - 1
src/Rendering/babylon.outlineRenderer.js

@@ -53,9 +53,16 @@ var BABYLON;
             if (mesh.useBones && mesh.computeBonesUsingShaders) {
                 attribs.push(BABYLON.VertexBuffer.MatricesIndicesKind);
                 attribs.push(BABYLON.VertexBuffer.MatricesWeightsKind);
-                defines.push("#define BONES");
+                if (mesh.numBoneInfluencers > 4) {
+                    attribs.push(BABYLON.VertexBuffer.MatricesIndicesExtraKind);
+                    attribs.push(BABYLON.VertexBuffer.MatricesWeightsExtraKind);
+                }
+                defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
                 defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
             }
+            else {
+                defines.push("#define NUM_BONE_INFLUENCERS 0");
+            }
             // Instances
             if (useInstances) {
                 defines.push("#define INSTANCES");

+ 7 - 1
src/Rendering/babylon.outlineRenderer.ts

@@ -68,8 +68,14 @@
             if (mesh.useBones && mesh.computeBonesUsingShaders) {
                 attribs.push(VertexBuffer.MatricesIndicesKind);
                 attribs.push(VertexBuffer.MatricesWeightsKind);
-                defines.push("#define BONES");
+                if (mesh.numBoneInfluencers > 4) {
+                    attribs.push(VertexBuffer.MatricesIndicesExtraKind);
+                    attribs.push(VertexBuffer.MatricesWeightsExtraKind);
+                }
+                defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
                 defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
+            } else {
+                defines.push("#define NUM_BONE_INFLUENCERS 0");
             }
 
             // Instances

+ 43 - 21
src/Shaders/default.vertex.fx

@@ -14,9 +14,17 @@ attribute vec2 uv2;
 #ifdef VERTEXCOLOR
 attribute vec4 color;
 #endif
-#ifdef BONES
-attribute vec4 matricesIndices;
-attribute vec4 matricesWeights;
+#if NUM_BONE_INFLUENCERS > 0
+
+	// having bone influencers implies you have bones
+	uniform mat4 mBones[BonesPerMesh];
+
+	attribute vec4 matricesIndices;
+	attribute vec4 matricesWeights;
+	#if NUM_BONE_INFLUENCERS > 4
+		attribute vec4 matricesIndicesExtra;
+		attribute vec4 matricesWeightsExtra;
+	#endif
 #endif
 
 // Uniforms
@@ -130,30 +138,44 @@ varying vec3 vDirectionW;
 #endif
 
 void main(void) {
-	mat4 finalWorld;
-
 #ifdef REFLECTIONMAP_SKYBOX
 	vPositionUVW = position;
 #endif 
 
 #ifdef INSTANCES
-	finalWorld = mat4(world0, world1, world2, world3);
+	mat4 finalWorld = mat4(world0, world1, world2, world3);
 #else
-	finalWorld = world;
-#endif
-
-#ifdef BONES
-	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
-	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
-	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
-
-#ifdef BONES4
-	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
-	finalWorld = finalWorld * (m0 + m1 + m2 + m3);
-#else
-	finalWorld = finalWorld * (m0 + m1 + m2);
-#endif 
-
+	mat4 finalWorld = world;
+#endif
+
+#if NUM_BONE_INFLUENCERS > 0
+	mat4 influence;
+	influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
+
+	#if NUM_BONE_INFLUENCERS > 1
+		influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
+	#endif 
+	#if NUM_BONE_INFLUENCERS > 2
+		influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 3
+		influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
+	#endif	
+
+	#if NUM_BONE_INFLUENCERS > 4
+		influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
+	#endif
+	#if NUM_BONE_INFLUENCERS > 5
+		influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 6
+		influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 7
+		influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
+	#endif	
+
+	finalWorld = finalWorld * influence;
 #endif
 	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 

+ 40 - 15
src/Shaders/depth.vertex.fx

@@ -2,9 +2,17 @@
 
 // Attribute
 attribute vec3 position;
-#ifdef BONES
-attribute vec4 matricesIndices;
-attribute vec4 matricesWeights;
+#if NUM_BONE_INFLUENCERS > 0
+
+	// having bone influencers implies you have bones
+	uniform mat4 mBones[BonesPerMesh];
+
+	attribute vec4 matricesIndices;
+	attribute vec4 matricesWeights;
+	#if NUM_BONE_INFLUENCERS > 4
+		attribute vec4 matricesIndicesExtra;
+		attribute vec4 matricesWeightsExtra;
+	#endif
 #endif
 
 // Uniform
@@ -18,9 +26,6 @@ uniform mat4 world;
 #endif
 
 uniform mat4 viewProjection;
-#ifdef BONES
-uniform mat4 mBones[BonesPerMesh];
-#endif
 
 #if defined(ALPHATEST) || defined(NEED_UV)
 varying vec2 vUV;
@@ -41,16 +46,36 @@ void main(void)
 	mat4 finalWorld = world;
 #endif
 
-#ifdef BONES
-	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
-	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
-	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
-	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
-	finalWorld = finalWorld * (m0 + m1 + m2 + m3);
-	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
-#else
-	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
+#if NUM_BONE_INFLUENCERS > 0
+	mat4 influence;
+	influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
+
+	#if NUM_BONE_INFLUENCERS > 1
+		influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 2
+		influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 3
+		influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
+	#endif	
+	
+	#if NUM_BONE_INFLUENCERS > 4
+		influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 5
+		influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 6
+		influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 7
+		influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
+	#endif	
+
+	finalWorld = finalWorld * influence;
 #endif
+	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 
 #if defined(ALPHATEST) || defined(BASIC_RENDER)
 #ifdef UV1

+ 41 - 24
src/Shaders/legacydefault.vertex.fx

@@ -12,9 +12,17 @@ attribute vec2 uv2;
 #ifdef VERTEXCOLOR
 attribute vec4 color;
 #endif
-#ifdef BONES
-attribute vec4 matricesIndices;
-attribute vec4 matricesWeights;
+#if NUM_BONE_INFLUENCERS > 0
+
+	// having bone influencers implies you have bones
+	uniform mat4 mBones[BonesPerMesh];
+
+	attribute vec4 matricesIndices;
+	attribute vec4 matricesWeights;
+	#if NUM_BONE_INFLUENCERS > 4
+		attribute vec4 matricesIndicesExtra;
+		attribute vec4 matricesWeightsExtra;
+	#endif
 #endif
 
 // Uniforms
@@ -58,10 +66,6 @@ uniform vec2 vBumpInfos;
 uniform mat4 bumpMatrix;
 #endif
 
-#ifdef BONES
-uniform mat4 mBones[BonesPerMesh];
-#endif
-
 // Output
 varying vec3 vPositionW;
 varying vec3 vNormalW;
@@ -142,24 +146,37 @@ vec3 computeReflectionCoords(vec4 worldPos, vec3 worldNormal)
 #endif
 
 void main(void) {
-	mat4 finalWorld;
-
-#ifdef BONES
-	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
-	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
-	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
-
-#ifdef BONES4
-	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
-	finalWorld = world * (m0 + m1 + m2 + m3);
-#else
-	finalWorld = world * (m0 + m1 + m2);
-#endif 
-
-#else
-	finalWorld = world;
+	mat4 finalWorld = world;
+
+#if NUM_BONE_INFLUENCERS > 0
+	mat4 influence;
+	influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
+
+	#if NUM_BONE_INFLUENCERS > 1
+		influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
+	#endif 
+	#if NUM_BONE_INFLUENCERS > 2
+		influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 3
+		influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
+	#endif	
+
+	#if NUM_BONE_INFLUENCERS > 4
+		influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
+	#endif
+	#if NUM_BONE_INFLUENCERS > 5
+		influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 6
+		influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 7
+		influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
+	#endif	
+
+	finalWorld = finalWorld * influence;
 #endif
-
 	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 
 	vec4 worldPos = finalWorld * vec4(position, 1.0);

+ 38 - 15
src/Shaders/outline.vertex.fx

@@ -4,9 +4,15 @@
 attribute vec3 position;
 attribute vec3 normal;
 
-#ifdef BONES
+#if NUM_BONE_INFLUENCERS > 0
+uniform mat4 mBones[BonesPerMesh];
+
 attribute vec4 matricesIndices;
 attribute vec4 matricesWeights;
+#if NUM_BONE_INFLUENCERS > 4
+attribute vec4 matricesIndicesExtra;
+attribute vec4 matricesWeightsExtra;
+#endif
 #endif
 
 // Uniform
@@ -22,9 +28,6 @@ uniform mat4 world;
 #endif
 
 uniform mat4 viewProjection;
-#ifdef BONES
-uniform mat4 mBones[BonesPerMesh];
-#endif
 
 #ifdef ALPHATEST
 varying vec2 vUV;
@@ -39,24 +42,44 @@ attribute vec2 uv2;
 
 void main(void)
 {
+	vec3 offsetPosition = position + normal * offset;
+
 #ifdef INSTANCES
 	mat4 finalWorld = mat4(world0, world1, world2, world3);
 #else
 	mat4 finalWorld = world;
 #endif
 
-	vec3 offsetPosition = position + normal * offset;
+#if NUM_BONE_INFLUENCERS > 0
+	mat4 influence;
+	influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
 
-#ifdef BONES
-	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
-	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
-	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
-	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
-	finalWorld = finalWorld * (m0 + m1 + m2 + m3);
-	gl_Position = viewProjection * finalWorld * vec4(offsetPosition, 1.0);
-#else
-	gl_Position = viewProjection * finalWorld * vec4(offsetPosition, 1.0);
+#if NUM_BONE_INFLUENCERS > 1
+	influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
+#endif	
+#if NUM_BONE_INFLUENCERS > 2
+	influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
+#endif	
+#if NUM_BONE_INFLUENCERS > 3
+	influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
+#endif	
+
+#if NUM_BONE_INFLUENCERS > 4
+	influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
+#endif	
+#if NUM_BONE_INFLUENCERS > 5
+	influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
+#endif	
+#if NUM_BONE_INFLUENCERS > 6
+	influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
+#endif	
+#if NUM_BONE_INFLUENCERS > 7
+	influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
+#endif	
+
+	finalWorld = finalWorld * influence;
 #endif
+	gl_Position = viewProjection * finalWorld * vec4(offsetPosition, 1.0);
 
 #ifdef ALPHATEST
 #ifdef UV1
@@ -66,4 +89,4 @@ void main(void)
 	vUV = vec2(diffuseMatrix * vec4(uv2, 1.0, 0.0));
 #endif
 #endif
-}
+}

+ 43 - 25
src/Shaders/pbr.vertex.fx

@@ -14,9 +14,17 @@ attribute vec2 uv2;
 #ifdef VERTEXCOLOR
 attribute vec4 color;
 #endif
-#ifdef BONES
-attribute vec4 matricesIndices;
-attribute vec4 matricesWeights;
+#if NUM_BONE_INFLUENCERS > 0
+
+	// having bone influencers implies you have bones
+	uniform mat4 mBones[BonesPerMesh];
+
+	attribute vec4 matricesIndices;
+	attribute vec4 matricesWeights;
+	#if NUM_BONE_INFLUENCERS > 4
+		attribute vec4 matricesIndicesExtra;
+		attribute vec4 matricesWeightsExtra;
+	#endif
 #endif
 
 // Uniforms
@@ -32,10 +40,6 @@ uniform mat4 world;
 uniform mat4 view;
 uniform mat4 viewProjection;
 
-#ifdef BONES
-uniform mat4 mBones[BonesPerMesh];
-#endif
-
 #ifdef POINTSIZE
 uniform float pointSize;
 #endif
@@ -60,26 +64,40 @@ varying float fFogDistance;
 #endif
 
 void main(void) {
-	mat4 finalWorld;
-
 #ifdef INSTANCES
-	finalWorld = mat4(world0, world1, world2, world3);
+	mat4 finalWorld = mat4(world0, world1, world2, world3);
 #else
-	finalWorld = world;
-#endif
-
-#ifdef BONES
-	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
-	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
-	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
-
-#ifdef BONES4
-	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
-	finalWorld = finalWorld * (m0 + m1 + m2 + m3);
-#else
-	finalWorld = finalWorld * (m0 + m1 + m2);
-#endif 
-
+	mat4 finalWorld = world;
+#endif
+
+#if NUM_BONE_INFLUENCERS > 0
+	mat4 influence;
+	influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
+
+	#if NUM_BONE_INFLUENCERS > 1
+		influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 2
+		influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 3
+		influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
+	#endif	
+	
+	#if NUM_BONE_INFLUENCERS > 4
+		influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 5
+		influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 6
+		influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
+	#endif	
+	#if NUM_BONE_INFLUENCERS > 7
+		influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
+	#endif	
+
+	finalWorld = finalWorld * influence;
 #endif
 	gl_Position = viewProjection * finalWorld * vec4(position, 1.0);
 

+ 37 - 11
src/Shaders/shadowMap.vertex.fx

@@ -2,9 +2,17 @@
 
 // Attribute
 attribute vec3 position;
-#ifdef BONES
+#if NUM_BONE_INFLUENCERS > 0
+
+// having bone influencers implies you have bones
+uniform mat4 mBones[BonesPerMesh];
+
 attribute vec4 matricesIndices;
 attribute vec4 matricesWeights;
+#if NUM_BONE_INFLUENCERS > 4
+attribute vec4 matricesIndicesExtra;
+attribute vec4 matricesWeightsExtra;
+#endif
 #endif
 
 // Uniform
@@ -18,9 +26,6 @@ uniform mat4 world;
 #endif
 
 uniform mat4 viewProjection;
-#ifdef BONES
-uniform mat4 mBones[BonesPerMesh];
-#endif
 
 varying vec4 vPosition;
 
@@ -43,14 +48,35 @@ void main(void)
 	mat4 finalWorld = world;
 #endif
 
-#ifdef BONES
-	mat4 m0 = mBones[int(matricesIndices.x)] * matricesWeights.x;
-	mat4 m1 = mBones[int(matricesIndices.y)] * matricesWeights.y;
-	mat4 m2 = mBones[int(matricesIndices.z)] * matricesWeights.z;
-	mat4 m3 = mBones[int(matricesIndices.w)] * matricesWeights.w;
-	finalWorld = finalWorld * (m0 + m1 + m2 + m3);
-#endif
+#if NUM_BONE_INFLUENCERS > 0
+	mat4 influence;
+	influence = mBones[int(matricesIndices[0])] * matricesWeights[0];
+
+#if NUM_BONE_INFLUENCERS > 1
+	influence += mBones[int(matricesIndices[1])] * matricesWeights[1];
+#endif	
+#if NUM_BONE_INFLUENCERS > 2
+	influence += mBones[int(matricesIndices[2])] * matricesWeights[2];
+#endif	
+#if NUM_BONE_INFLUENCERS > 3
+	influence += mBones[int(matricesIndices[3])] * matricesWeights[3];
+#endif	
 
+#if NUM_BONE_INFLUENCERS > 4
+	influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0];
+#endif	
+#if NUM_BONE_INFLUENCERS > 5
+	influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1];
+#endif	
+#if NUM_BONE_INFLUENCERS > 6
+	influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2];
+#endif	
+#if NUM_BONE_INFLUENCERS > 7
+	influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3];
+#endif	
+
+	finalWorld = finalWorld * influence;
+#endif
 	vPosition = viewProjection * finalWorld * vec4(position, 1.0);
 	gl_Position = vPosition;
 

+ 4 - 0
src/babylon.mixins.ts

@@ -103,4 +103,8 @@ interface Navigator {
 interface Screen {
     orientation: string;
     mozOrientation: string;
+}
+
+interface HTMLMediaElement {
+    crossOrigin: string;
 }