Browse Source

Merge pull request #2066 from BeardedGnome/morph-target

Adding support to Babylon.JS for morph targets
David Catuhe 8 years ago
parent
commit
4fdb6fa330

+ 1 - 1
serializers/src/OBJ/babylon.objSerializer.ts

@@ -28,7 +28,7 @@ module BABYLON {
                 if (materials) {
                     output.push("usemtl " + mesh[j].material.id);
                 }
-                var g = mesh[j].Geometry;
+                var g = mesh[j].geometry;
                 var trunkVerts = g.getVerticesData('position');
                 var trunkNormals = g.getVerticesData('normal');
                 var trunkUV = g.getVerticesData('uv');

+ 7 - 0
src/Materials/babylon.materialHelper.ts

@@ -72,10 +72,12 @@
             if (useMorphTargets) {
                 if ((<any>mesh).morphTargetManager) {
                     var manager = (<Mesh>mesh).morphTargetManager;
+                    defines["MORPHTARGETS_TANGENT"] = manager.supportsTangents && defines["TANGENT"];
                     defines["MORPHTARGETS_NORMAL"] = manager.supportsNormals && defines["NORMAL"] ;
                     defines["MORPHTARGETS"] = (manager.numInfluencers > 0);
                     defines["NUM_MORPH_INFLUENCERS"] = manager.numInfluencers;
                 } else {
+                    defines["MORPHTARGETS_TANGENT"] = false;
                     defines["MORPHTARGETS_NORMAL"] = false;
                     defines["MORPHTARGETS"] = false;
                     defines["NUM_MORPH_INFLUENCERS"] = 0;
@@ -266,6 +268,7 @@
                 var maxAttributesCount = Engine.LastCreatedEngine.getCaps().maxVertexAttribs;
                 var manager = (<Mesh>mesh).morphTargetManager;
                 var normal = manager.supportsNormals && defines["NORMAL"];
+                var tangent = manager.supportsTangents && defines["TANGENT"];
                 for (var index = 0; index < influencers; index++) {
                     attribs.push(VertexBuffer.PositionKind + index);
 
@@ -273,6 +276,10 @@
                         attribs.push(VertexBuffer.NormalKind + index);
                     }
 
+                    if (tangent) {
+                        attribs.push(VertexBuffer.TangentKind + index);
+                    }
+
                     if (attribs.length > maxAttributesCount) {
                         Tools.Error("Cannot add more vertex attributes for mesh " + mesh.name);
                     }

+ 2 - 0
src/Materials/babylon.pbrMaterial.ts

@@ -79,6 +79,7 @@
 
         public MORPHTARGETS = false;
         public MORPHTARGETS_NORMAL = false;
+        public MORPHTARGETS_TANGENT = false;
         public NUM_MORPH_INFLUENCERS = 0;
 
         constructor() {
@@ -1033,6 +1034,7 @@
 
                if ((<any>mesh).morphTargetManager) {
                     var manager = (<Mesh>mesh).morphTargetManager;
+                    this._defines.MORPHTARGETS_TANGENT = manager.supportsTangents && this._defines.TANGENT;
                     this._defines.MORPHTARGETS_NORMAL = manager.supportsNormals && this._defines.NORMAL;
                     this._defines.MORPHTARGETS = (manager.numInfluencers > 0);
                     this._defines.NUM_MORPH_INFLUENCERS = manager.numInfluencers;

+ 1 - 0
src/Materials/babylon.standardMaterial.ts

@@ -61,6 +61,7 @@ module BABYLON {
         public CAMERACOLORCURVES = false;
         public MORPHTARGETS = false;
         public MORPHTARGETS_NORMAL = false;
+        public MORPHTARGETS_TANGENT = false;
         public NUM_MORPH_INFLUENCERS = 0;
 
         constructor() {

+ 7 - 0
src/Mesh/babylon.mesh.ts

@@ -2021,6 +2021,9 @@
                     if (morphTarget.hasNormals) {
                         this.geometry.setVerticesData(VertexBuffer.NormalKind + index, morphTarget.getNormals(), false, 3);
                     }
+                    if (morphTarget.hasTangents) {
+                        this.geometry.setVerticesData(VertexBuffer.TangentKind + index, morphTarget.getTangents(), false, 3);
+                    }
                 }
             } else {
                 var index = 0;
@@ -2034,6 +2037,10 @@
                     {
                         this.geometry.removeVerticesData(VertexBuffer.NormalKind + index);
                     }
+                    if (this.geometry.isVerticesDataPresent(VertexBuffer.TangentKind + index))
+                    {
+                        this.geometry.removeVerticesData(VertexBuffer.TangentKind + index);
+                    }
                     index++;
                 }    
             }

+ 22 - 0
src/Morph/babylon.morphTarget.ts

@@ -2,6 +2,7 @@ module BABYLON {
     export class MorphTarget {
         private _positions: Float32Array;
         private _normals: Float32Array;
+        private _tangents: Float32Array;
         private _influence: number;
 
         public onInfluenceChanged = new Observable<boolean>();
@@ -31,6 +32,10 @@ module BABYLON {
             return this._normals !== undefined;
         }
 
+        public get hasTangents(): boolean {
+            return this._tangents !== undefined;
+        }
+
         public setPositions(data: Float32Array | number[]) {
             this._positions = new Float32Array(data);
         }
@@ -47,6 +52,14 @@ module BABYLON {
             return this._normals;
         }
 
+        public setTangents(data: Float32Array | number[]) {
+            this._tangents = new Float32Array(data);
+        }
+
+        public getTangents(): Float32Array {
+            return this._tangents;
+        }
+
         /**
          * Serializes the current target into a Serialization object.  
          * Returns the serialized object.  
@@ -61,6 +74,9 @@ module BABYLON {
             if (this.hasNormals) {
                 serializationObject.normals = Array.prototype.slice.call(this.getNormals());
             }
+            if (this.hasTangents) {
+                serializationObject.tangents = Array.prototype.slice.call(this.getTangents());
+            }
 
             return serializationObject;
         }
@@ -74,6 +90,9 @@ module BABYLON {
             if (serializationObject.normals) {
                 result.setNormals(serializationObject.normals);
             }
+            if (serializationObject.tangents) {
+                result.setTangents(serializationObject.tangents);
+            }
 
             return result;
         }
@@ -90,6 +109,9 @@ module BABYLON {
             if (mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {
                 result.setNormals(mesh.getVerticesData(VertexBuffer.NormalKind));
             }
+            if (mesh.isVerticesDataPresent(VertexBuffer.TangentKind)) {
+                result.setTangents(mesh.getVerticesData(VertexBuffer.TangentKind));
+            }
 
             return result;
         }

+ 7 - 0
src/Morph/babylon.morphTargetManager.ts

@@ -6,6 +6,7 @@ module BABYLON {
         private _scene: Scene;
         private _influences: Float32Array;
         private _supportsNormals = false;
+        private _supportsTangents = false;
         private _vertexCount = 0;
         private _uniqueId = 0;
 
@@ -33,6 +34,10 @@ module BABYLON {
             return this._supportsNormals;
         }
 
+        public get supportsTangents(): boolean {
+            return this._supportsTangents;
+        }
+
         public get numInfluencers(): number {
             return this._activeTargets.length;
         }
@@ -96,12 +101,14 @@ module BABYLON {
             this._activeTargets.reset();
             var tempInfluences = [];
             this._supportsNormals = true;
+            this._supportsTangents = true;
             for (var target of this._targets) {
                 if (target.influence > 0) {
                     this._activeTargets.push(target);
                     tempInfluences.push(target.influence);
 
                     this._supportsNormals = this._supportsNormals && target.hasNormals;
+                    this._supportsTangents = this._supportsTangents && target.hasTangents;
 
                     if (this._vertexCount === 0) {
                         this._vertexCount = target.getPositions().length / 3;

+ 3 - 3
src/Shaders/ShadersInclude/bumpVertex.fx

@@ -1,8 +1,8 @@
 #if defined(BUMP) || defined(PARALLAX)
 	#if defined(TANGENT) && defined(NORMAL)
-		vec3 normalW = normalize(vec3(finalWorld * vec4(normal, 0.0)));
-		vec3 tangentW = normalize(vec3(finalWorld * vec4(tangent.xyz, 0.0)));
-		vec3 bitangentW = cross(normalW, tangentW) * tangent.w;
+		vec3 normalW = normalize(vec3(finalWorld * vec4(normalUpdated, 0.0)));
+		vec3 tangentW = normalize(vec3(finalWorld * vec4(tangentUpdated.xyz, 0.0)));
+		vec3 bitangentW = cross(normalW, tangentW) * tangentUpdated.w;
 		vTBN = mat3(tangentW, bitangentW, normalW);
 	#endif
 #endif

+ 5 - 1
src/Shaders/ShadersInclude/morphTargetsVertex.fx

@@ -3,5 +3,9 @@
 	
 	#ifdef MORPHTARGETS_NORMAL
 	normalUpdated += (normal{X} - normal) * morphTargetInfluences[{X}];
-	#endif	
+	#endif
+
+	#ifdef MORPHTARGETS_TANGENT
+	tangentUpdated.xyz += (tangent{X} - tangent.xyz) * morphTargetInfluences[{X}];
+	#endif
 #endif

+ 4 - 0
src/Shaders/ShadersInclude/morphTargetsVertexDeclaration.fx

@@ -4,4 +4,8 @@
 	#ifdef MORPHTARGETS_NORMAL
 	attribute vec3 normal{X};
 	#endif
+
+	#ifdef MORPHTARGETS_TANGENT
+	attribute vec3 tangent{X};
+	#endif
 #endif

+ 3 - 0
src/Shaders/default.vertex.fx

@@ -86,6 +86,9 @@ void main(void) {
 #ifdef NORMAL	
 	vec3 normalUpdated = normal;
 #endif
+#ifdef TANGENT
+	vec4 tangentUpdated = tangent;
+#endif
 
 #include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]
 

+ 4 - 1
src/Shaders/pbr.vertex.fx

@@ -87,9 +87,12 @@ varying vec3 vDirectionW;
 
 void main(void) {
 	vec3 positionUpdated = position;
-#ifdef NORMAL	
+#ifdef NORMAL
 	vec3 normalUpdated = normal;
 #endif
+#ifdef TANGENT
+    vec4 tangentUpdated = tangent;
+#endif
 
 #include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]