瀏覽代碼

Merge remote-tracking branch 'BabylonJS/master'

MackeyK24 8 年之前
父節點
當前提交
e10788f5f7

文件差異過大導致無法顯示
+ 29 - 29
dist/preview release/babylon.core.js


文件差異過大導致無法顯示
+ 1388 - 1371
dist/preview release/babylon.d.ts


文件差異過大導致無法顯示
+ 39 - 38
dist/preview release/babylon.js


文件差異過大導致無法顯示
+ 113 - 16
dist/preview release/babylon.max.js


文件差異過大導致無法顯示
+ 1388 - 1371
dist/preview release/babylon.module.d.ts


文件差異過大導致無法顯示
+ 39 - 38
dist/preview release/babylon.noworker.js


文件差異過大導致無法顯示
+ 3 - 3
dist/preview release/inspector/babylon.inspector.bundle.js


文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/inspector/babylon.inspector.min.js


+ 2 - 1
dist/preview release/what's new.md

@@ -16,6 +16,7 @@
  - All deprecated functions and properties were removed ([deltakosh](https://github.com/deltakosh))
  - All deprecated functions and properties were removed ([deltakosh](https://github.com/deltakosh))
 
 
 ### Updates
 ### Updates
+- Improved FXAA post-process ([deltakosh](https://github.com/deltakosh))
 - Added `Light.customProjectionMatrixBuilder` to allow developers to define their own projection matrix for shadows ([deltakosh](https://github.com/deltakosh))
 - Added `Light.customProjectionMatrixBuilder` to allow developers to define their own projection matrix for shadows ([deltakosh](https://github.com/deltakosh))
 - Added `set()` function to all basic types ([deltakosh](https://github.com/deltakosh))
 - Added `set()` function to all basic types ([deltakosh](https://github.com/deltakosh))
 - Added `HDRCubeTextureAssetTask` to AssetManager ([deltakosh](https://github.com/deltakosh))
 - Added `HDRCubeTextureAssetTask` to AssetManager ([deltakosh](https://github.com/deltakosh))
@@ -38,7 +39,7 @@
 - Added `POINTERTAP` and `POINTERDOUBLETAP` PointerEventTypes to register new Observer mask. (Demo here)[http://www.babylonjs-playground.com/?30] ([yuccai](https://github.com/yuccai))
 - Added `POINTERTAP` and `POINTERDOUBLETAP` PointerEventTypes to register new Observer mask. (Demo here)[http://www.babylonjs-playground.com/?30] ([yuccai](https://github.com/yuccai))
 - Added OnDoublePickTrigger for ActionManager ([yuccai](https://github.com/yuccai))
 - Added OnDoublePickTrigger for ActionManager ([yuccai](https://github.com/yuccai))
 - Added Scene.DoubleClickDelay to set the timing within a double click event like PointerEventTypes.POINTERDOUBLETAP or ActionManager.OnDoublePickTrigger has to be processed ([yuccai](https://github.com/yuccai))
 - Added Scene.DoubleClickDelay to set the timing within a double click event like PointerEventTypes.POINTERDOUBLETAP or ActionManager.OnDoublePickTrigger has to be processed ([yuccai](https://github.com/yuccai))
-- New material: ShadowOnlyMaterial to display shadows on transparent surfaces ([deltakosh](https://github.com/deltakosh)) 
+- New material: `ShadowOnlyMaterial` to display shadows on transparent surfaces ([deltakosh](https://github.com/deltakosh)) 
 - Added `VertexBuffer.TangentKind` to specify tangents in place of shader-calculated tangents ([dewadswo](https://github.com/dewadswo), [bghgary](https://github.com/bghgary))
 - Added `VertexBuffer.TangentKind` to specify tangents in place of shader-calculated tangents ([dewadswo](https://github.com/dewadswo), [bghgary](https://github.com/bghgary))
  
  
 ### Bug fixes
 ### Bug fixes

+ 33 - 23
src/Bones/babylon.boneIKController.ts

@@ -1,6 +1,10 @@
 module BABYLON {
 module BABYLON {
     export class BoneIKController {
     export class BoneIKController {
 
 
+        private static _tmpVecs: Vector3[] = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];
+        private static _tmpQuat = Quaternion.Identity();
+        private static _tmpMats: Matrix[] = [Matrix.Identity(), Matrix.Identity()];
+        
         public targetMesh: AbstractMesh;
         public targetMesh: AbstractMesh;
         public poleTargetMesh: AbstractMesh;
         public poleTargetMesh: AbstractMesh;
         public poleTargetBone: Bone;
         public poleTargetBone: Bone;
@@ -22,15 +26,6 @@ module BABYLON {
         private _maxAngle = Math.PI;
         private _maxAngle = Math.PI;
         private _maxReach: number;
         private _maxReach: number;
 
 
-        private _tmpVec1 = Vector3.Zero();
-        private _tmpVec2 = Vector3.Zero();
-        private _tmpVec3 = Vector3.Zero();
-        private _tmpVec4 = Vector3.Zero();
-        private _tmpVec5 = Vector3.Zero();
-        private _tmpMat1 = Matrix.Identity();
-        private _tmpMat2 = Matrix.Identity();
-        private _tmpQuat1 = Quaternion.Identity();
-
         private _rightHandedSystem = false;
         private _rightHandedSystem = false;
 
 
         private _bendAxis = Vector3.Right();
         private _bendAxis = Vector3.Right();
@@ -50,7 +45,18 @@ module BABYLON {
 
 
         }
         }
 
 
-        constructor(mesh: AbstractMesh, bone: Bone, options?: { targetMesh?: AbstractMesh, poleTargetMesh?: AbstractMesh, poleTargetBone?: Bone, poleTargetLocalOffset?:Vector3, poleAngle?: number, bendAxis?: Vector3, maxAngle?:number, slerpAmount?:number }){
+        constructor(mesh: AbstractMesh, 
+                    bone: Bone, 
+                    options?: { 
+                        targetMesh?: AbstractMesh, 
+                        poleTargetMesh?: AbstractMesh, 
+                        poleTargetBone?: Bone, 
+                        poleTargetLocalOffset?:Vector3, 
+                        poleAngle?: number, 
+                        bendAxis?: Vector3, 
+                        maxAngle?:number, 
+                        slerpAmount?:number 
+                    }){
 
 
             this._bone2 = bone;
             this._bone2 = bone;
             this._bone1 = bone.getParent();
             this._bone1 = bone.getParent();
@@ -160,14 +166,14 @@ module BABYLON {
 
 
         }
         }
 
 
-        public update (): void {
+        public update(): void {
 	
 	
             var bone1 = this._bone1;
             var bone1 = this._bone1;
             var target = this.targetPosition;
             var target = this.targetPosition;
             var poleTarget = this.poleTargetPosition;
             var poleTarget = this.poleTargetPosition;
 
 
-            var mat1 = this._tmpMat1;
-            var mat2 = this._tmpMat2;
+            var mat1 = BoneIKController._tmpMats[0];
+            var mat2 = BoneIKController._tmpMats[1];
 
 
             if(this.targetMesh){
             if(this.targetMesh){
                 target.copyFrom(this.targetMesh.getAbsolutePosition());
                 target.copyFrom(this.targetMesh.getAbsolutePosition());
@@ -179,11 +185,13 @@ module BABYLON {
                 Vector3.TransformCoordinatesToRef(this.poleTargetLocalOffset, this.poleTargetMesh.getWorldMatrix(), poleTarget);
                 Vector3.TransformCoordinatesToRef(this.poleTargetLocalOffset, this.poleTargetMesh.getWorldMatrix(), poleTarget);
             }
             }
 
 
-            var bonePos = this._tmpVec1;
-            var zaxis = this._tmpVec2;
-            var xaxis = this._tmpVec3;
-            var yaxis = this._tmpVec4;
-            var upAxis = this._tmpVec5;
+            var bonePos = BoneIKController._tmpVecs[0];
+            var zaxis = BoneIKController._tmpVecs[1];
+            var xaxis = BoneIKController._tmpVecs[2];
+            var yaxis = BoneIKController._tmpVecs[3];
+            var upAxis = BoneIKController._tmpVecs[4];
+
+            var _tmpQuat = BoneIKController._tmpQuat;
             
             
             bone1.getAbsolutePositionToRef(this.mesh, bonePos);
             bone1.getAbsolutePositionToRef(this.mesh, bonePos);
 
 
@@ -249,10 +257,12 @@ module BABYLON {
 
 
             } else {
             } else {
 
 
-                this._tmpVec1.copyFrom(this._bendAxis);
-                this._tmpVec1.x *= -1;
+                var _tmpVec = BoneIKController._tmpVecs[5];
+
+                _tmpVec.copyFrom(this._bendAxis);
+                _tmpVec.x *= -1;
 
 
-                Matrix.RotationAxisToRef(this._tmpVec1, -angB, mat2);
+                Matrix.RotationAxisToRef(_tmpVec, -angB, mat2);
                 mat2.multiplyToRef(mat1, mat1);
                 mat2.multiplyToRef(mat1, mat1);
                 
                 
             }
             }
@@ -266,8 +276,8 @@ module BABYLON {
                 if(!this._slerping){
                 if(!this._slerping){
                     Quaternion.FromRotationMatrixToRef(this._bone1Mat, this._bone1Quat);
                     Quaternion.FromRotationMatrixToRef(this._bone1Mat, this._bone1Quat);
                 }
                 }
-                Quaternion.FromRotationMatrixToRef(mat1, this._tmpQuat1);
-                Quaternion.SlerpToRef(this._bone1Quat, this._tmpQuat1, this.slerpAmount, this._bone1Quat);
+                Quaternion.FromRotationMatrixToRef(mat1, _tmpQuat);
+                Quaternion.SlerpToRef(this._bone1Quat, _tmpQuat, this.slerpAmount, this._bone1Quat);
                 angC = this._bone2Ang * (1.0 - this.slerpAmount) + angC * this.slerpAmount;
                 angC = this._bone2Ang * (1.0 - this.slerpAmount) + angC * this.slerpAmount;
                 this._bone1.setRotationQuaternion(this._bone1Quat, Space.WORLD, this.mesh);
                 this._bone1.setRotationQuaternion(this._bone1Quat, Space.WORLD, this.mesh);
                 this._slerping = true;
                 this._slerping = true;

+ 1 - 1
src/PostProcess/babylon.fxaaPostProcess.ts

@@ -4,7 +4,7 @@
         public texelHeight: number;
         public texelHeight: number;
 
 
         constructor(name: string, options: number | PostProcessOptions, camera: Camera, samplingMode?: number, engine?: Engine, reusable?: boolean) {
         constructor(name: string, options: number | PostProcessOptions, camera: Camera, samplingMode?: number, engine?: Engine, reusable?: boolean) {
-            super(name, "fxaa", ["texelSize"], null, options, camera, samplingMode, engine, reusable);
+            super(name, "fxaa", ["texelSize"], null, options, camera, samplingMode || BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, reusable);
 
 
             this.onSizeChangedObservable.add(() => {
             this.onSizeChangedObservable.add(() => {
                 this.texelWidth = 1.0 / this.width;
                 this.texelWidth = 1.0 / this.width;

+ 230 - 44
src/Shaders/fxaa.fragment.fx

@@ -1,50 +1,236 @@
-#define FXAA_REDUCE_MIN   (1.0/128.0)
-#define FXAA_REDUCE_MUL   (1.0/8.0)
-#define FXAA_SPAN_MAX     8.0
-
-varying vec2 vUV;
+varying vec2 vUV;
 uniform sampler2D textureSampler;
 uniform sampler2D textureSampler;
 uniform vec2 texelSize;
 uniform vec2 texelSize;
 
 
+const float fxaaQualitySubpix = 1.0;
+const float fxaaQualityEdgeThreshold = 0.166;
+const float fxaaQualityEdgeThresholdMin = 0.0833;
+const vec3 kLumaCoefficients = vec3(0.2126, 0.7152, 0.0722);
+
+#define FxaaLuma(rgba) dot(rgba.rgb, kLumaCoefficients)
+
 void main(){
 void main(){
-	vec2 localTexelSize = texelSize;
-	vec4 rgbNW = texture2D(textureSampler, (vUV + vec2(-1.0, -1.0) * localTexelSize));
-	vec4 rgbNE = texture2D(textureSampler, (vUV + vec2(1.0, -1.0) * localTexelSize));
-	vec4 rgbSW = texture2D(textureSampler, (vUV + vec2(-1.0, 1.0) * localTexelSize));
-	vec4 rgbSE = texture2D(textureSampler, (vUV + vec2(1.0, 1.0) * localTexelSize));
-	vec4 rgbM = texture2D(textureSampler, vUV);
-	vec4 luma = vec4(0.299, 0.587, 0.114, 1.0);
-	float lumaNW = dot(rgbNW, luma);
-	float lumaNE = dot(rgbNE, luma);
-	float lumaSW = dot(rgbSW, luma);
-	float lumaSE = dot(rgbSE, luma);
-	float lumaM = dot(rgbM, luma);
-	float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
-	float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
-
-	vec2 dir = vec2(-((lumaNW + lumaNE) - (lumaSW + lumaSE)), ((lumaNW + lumaSW) - (lumaNE + lumaSE)));
-
-	float dirReduce = max(
-		(lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL),
-		FXAA_REDUCE_MIN);
-
-	float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
-	dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
-		max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
-		dir * rcpDirMin)) * localTexelSize;
-
-	vec4 rgbA = 0.5 * (
-		texture2D(textureSampler, vUV + dir * (1.0 / 3.0 - 0.5)) +
-		texture2D(textureSampler, vUV + dir * (2.0 / 3.0 - 0.5)));
-
-	vec4 rgbB = rgbA * 0.5 + 0.25 * (
-		texture2D(textureSampler, vUV + dir *  -0.5) +
-		texture2D(textureSampler, vUV + dir * 0.5));
-	float lumaB = dot(rgbB, luma);
-	if ((lumaB < lumaMin) || (lumaB > lumaMax)) {
-		gl_FragColor = rgbA;
-	}
-	else {
-		gl_FragColor = rgbB;
+	vec2 sampleCoordS = vUV + vec2( 0.0, 1.0) * texelSize;
+	vec2 sampleCoordE = vUV + vec2( 1.0, 0.0) * texelSize;
+	vec2 sampleCoordN = vUV + vec2( 0.0,-1.0) * texelSize;
+	vec2 sampleCoordW = vUV + vec2(-1.0, 0.0) * texelSize;
+
+	vec2 sampleCoordNW = vUV + vec2(-1.0,-1.0) * texelSize;
+	vec2 sampleCoordSE = vUV + vec2( 1.0, 1.0) * texelSize;
+	vec2 sampleCoordNE = vUV + vec2( 1.0,-1.0) * texelSize;
+	vec2 sampleCoordSW = vUV + vec2(-1.0, 1.0) * texelSize;
+
+	vec2 posM;
+
+	posM.x = vUV.x;
+	posM.y = vUV.y;
+
+	vec4 rgbyM = texture2D(textureSampler, vUV, 0.0);
+	float lumaM = FxaaLuma(rgbyM);
+	float lumaS = FxaaLuma(texture2D(textureSampler, sampleCoordS, 0.0));
+	float lumaE = FxaaLuma(texture2D(textureSampler, sampleCoordE, 0.0));
+	float lumaN = FxaaLuma(texture2D(textureSampler, sampleCoordN, 0.0));
+	float lumaW = FxaaLuma(texture2D(textureSampler, sampleCoordW, 0.0));
+	float maxSM = max(lumaS, lumaM);
+	float minSM = min(lumaS, lumaM);
+	float maxESM = max(lumaE, maxSM);
+	float minESM = min(lumaE, minSM);
+	float maxWN = max(lumaN, lumaW);
+	float minWN = min(lumaN, lumaW);
+	float rangeMax = max(maxWN, maxESM);
+	float rangeMin = min(minWN, minESM);
+	float rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold;
+	float range = rangeMax - rangeMin;
+	float rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled);
+
+	if(range < rangeMaxClamped) 
+	{
+		gl_FragColor = rgbyM;
+		return;
+	}
+
+	float lumaNW = FxaaLuma(texture2D(textureSampler, sampleCoordNW, 0.0));
+	float lumaSE = FxaaLuma(texture2D(textureSampler, sampleCoordSE, 0.0));
+	float lumaNE = FxaaLuma(texture2D(textureSampler, sampleCoordNE, 0.0));
+	float lumaSW = FxaaLuma(texture2D(textureSampler, sampleCoordSW, 0.0));
+	float lumaNS = lumaN + lumaS;
+	float lumaWE = lumaW + lumaE;
+	float subpixRcpRange = 1.0 / range;
+	float subpixNSWE = lumaNS + lumaWE;
+	float edgeHorz1 = (-2.0 * lumaM) + lumaNS;
+	float edgeVert1 = (-2.0 * lumaM) + lumaWE;
+	float lumaNESE = lumaNE + lumaSE;
+	float lumaNWNE = lumaNW + lumaNE;
+	float edgeHorz2 = (-2.0 * lumaE) + lumaNESE;
+	float edgeVert2 = (-2.0 * lumaN) + lumaNWNE;
+	float lumaNWSW = lumaNW + lumaSW;
+	float lumaSWSE = lumaSW + lumaSE;
+	float edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2);
+	float edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2);
+	float edgeHorz3 = (-2.0 * lumaW) + lumaNWSW;
+	float edgeVert3 = (-2.0 * lumaS) + lumaSWSE;
+	float edgeHorz = abs(edgeHorz3) + edgeHorz4;
+	float edgeVert = abs(edgeVert3) + edgeVert4;
+	float subpixNWSWNESE = lumaNWSW + lumaNESE;
+	float lengthSign = texelSize.x;
+	bool horzSpan = edgeHorz >= edgeVert;
+	float subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;
+
+	if (!horzSpan)
+	{
+		lumaN = lumaW;
+	}
+
+	if (!horzSpan) 
+	{
+		lumaS = lumaE;
+	}
+
+	if (horzSpan) 
+	{
+		lengthSign = texelSize.y;
 	}
 	}
+
+	float subpixB = (subpixA * (1.0 / 12.0)) - lumaM;
+	float gradientN = lumaN - lumaM;
+	float gradientS = lumaS - lumaM;
+	float lumaNN = lumaN + lumaM;
+	float lumaSS = lumaS + lumaM;
+	bool pairN = abs(gradientN) >= abs(gradientS);
+	float gradient = max(abs(gradientN), abs(gradientS));
+
+	if (pairN)
+	{
+		lengthSign = -lengthSign;
+	}
+
+	float subpixC = clamp(abs(subpixB) * subpixRcpRange, 0.0, 1.0);
+	vec2 posB;
+
+	posB.x = posM.x;
+	posB.y = posM.y;
+
+	vec2 offNP;
+
+	offNP.x = (!horzSpan) ? 0.0 : texelSize.x;
+	offNP.y = (horzSpan) ? 0.0 : texelSize.y;
+
+	if (!horzSpan) 
+	{
+		posB.x += lengthSign * 0.5;
+	}
+
+	if (horzSpan)
+	{
+		posB.y += lengthSign * 0.5;
+	}
+
+	vec2 posN;
+
+	posN.x = posB.x - offNP.x * 1.5;
+	posN.y = posB.y - offNP.y * 1.5;
+
+	vec2 posP;
+
+	posP.x = posB.x + offNP.x * 1.5;
+	posP.y = posB.y + offNP.y * 1.5;
+
+	float subpixD = ((-2.0) * subpixC) + 3.0;
+	float lumaEndN = FxaaLuma(texture2D(textureSampler, posN, 0.0));
+	float subpixE = subpixC * subpixC;
+	float lumaEndP = FxaaLuma(texture2D(textureSampler, posP, 0.0));
+
+	if (!pairN) 
+	{
+		lumaNN = lumaSS;
+	}
+
+	float gradientScaled = gradient * 1.0 / 4.0;
+	float lumaMM = lumaM - lumaNN * 0.5;
+	float subpixF = subpixD * subpixE;
+	bool lumaMLTZero = lumaMM < 0.0;
+
+	lumaEndN -= lumaNN * 0.5;
+	lumaEndP -= lumaNN * 0.5;
+
+	bool doneN = abs(lumaEndN) >= gradientScaled;
+	bool doneP = abs(lumaEndP) >= gradientScaled;
+
+	if (!doneN) 
+	{
+		posN.x -= offNP.x * 3.0;
+	}
+
+	if (!doneN) 
+	{
+		posN.y -= offNP.y * 3.0;
+	}
+
+	bool doneNP = (!doneN) || (!doneP);
+
+	if (!doneP) 
+	{
+		posP.x += offNP.x * 3.0;
+	}
+
+	if (!doneP)
+	{
+		posP.y += offNP.y * 3.0;
+	}
+
+	if (doneNP)
+	{
+		if (!doneN) lumaEndN = FxaaLuma(texture2D(textureSampler, posN.xy, 0.0));
+		if (!doneP) lumaEndP = FxaaLuma(texture2D(textureSampler, posP.xy, 0.0));
+		if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+		if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+	
+		doneN = abs(lumaEndN) >= gradientScaled;
+		doneP = abs(lumaEndP) >= gradientScaled;
+	
+		if (!doneN) posN.x -= offNP.x * 12.0;
+		if (!doneN) posN.y -= offNP.y * 12.0;
+	
+		doneNP = (!doneN) || (!doneP);
+	
+		if (!doneP) posP.x += offNP.x * 12.0;
+		if (!doneP) posP.y += offNP.y * 12.0;
+	}
+
+	float dstN = posM.x - posN.x;
+	float dstP = posP.x - posM.x;
+
+	if (!horzSpan)
+	{
+		dstN = posM.y - posN.y;
+	}
+	if (!horzSpan) 
+	{
+		dstP = posP.y - posM.y;
+	}
+
+	bool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;
+	float spanLength = (dstP + dstN);
+	bool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;
+	float spanLengthRcp = 1.0 / spanLength;
+	bool directionN = dstN < dstP;
+	float dst = min(dstN, dstP);
+	bool goodSpan = directionN ? goodSpanN : goodSpanP;
+	float subpixG = subpixF * subpixF;
+	float pixelOffset = (dst * (-spanLengthRcp)) + 0.5;
+	float subpixH = subpixG * fxaaQualitySubpix;
+	float pixelOffsetGood = goodSpan ? pixelOffset : 0.0;
+	float pixelOffsetSubpix = max(pixelOffsetGood, subpixH);
+
+	if (!horzSpan)
+	{
+		posM.x += pixelOffsetSubpix * lengthSign;
+	}
+
+	if (horzSpan)
+	{
+		posM.y += pixelOffsetSubpix * lengthSign;
+	}
+
+	gl_FragColor = texture2D(textureSampler, posM, 0.0);
 }
 }

+ 14 - 4
src/Tools/babylon.extendedGamepad.ts

@@ -345,7 +345,7 @@ module BABYLON {
     }
     }
 
 
     export class ViveController extends WebVRController {
     export class ViveController extends WebVRController {
-
+        private _defaultModel: BABYLON.AbstractMesh;
 
 
         constructor(vrGamepad) {
         constructor(vrGamepad) {
             super(vrGamepad);
             super(vrGamepad);
@@ -365,9 +365,8 @@ module BABYLON {
                 - trigger
                 - trigger
                 - LED
                 - LED
                 */
                 */
-
-                var mesh = newMeshes[1];
-                this.attachToMesh(mesh);
+                this._defaultModel = newMeshes[1];
+                this.attachToMesh(this._defaultModel);
             });
             });
         }
         }
 
 
@@ -398,12 +397,23 @@ module BABYLON {
                     this.onPadStateChangedObservable.notifyObservers(notifyObject);
                     this.onPadStateChangedObservable.notifyObservers(notifyObject);
                     return;
                     return;
                 case 1: // index trigger
                 case 1: // index trigger
+                    if (this._defaultModel) {
+                        (<AbstractMesh>(this._defaultModel.getChildren()[6])).rotation.x = -notifyObject.value * 0.15;
+                    }
                     this.onTriggerStateChangedObservable.notifyObservers(notifyObject);
                     this.onTriggerStateChangedObservable.notifyObservers(notifyObject);
                     return;
                     return;
                 case 2:  // left AND right button
                 case 2:  // left AND right button
                     this.onMainButtonStateChangedObservable.notifyObservers(notifyObject);
                     this.onMainButtonStateChangedObservable.notifyObservers(notifyObject);
                     return;
                     return;
                 case 3:
                 case 3:
+                    if (this._defaultModel) {
+                        if (notifyObject.value === 1) {
+                            (<AbstractMesh>(this._defaultModel.getChildren()[2])).position.y = -0.001;
+                        }
+                        else {
+                            (<AbstractMesh>(this._defaultModel.getChildren()[2])).position.y = 0;
+                        }
+                    }
                     this.onSecondaryButtonStateChangedObservable.notifyObservers(notifyObject);
                     this.onSecondaryButtonStateChangedObservable.notifyObservers(notifyObject);
                     return;
                     return;
             }
             }