Browse Source

Mergable: Added VertexAnimatedMesh.

Mikael Emtinger 14 năm trước cách đây
mục cha
commit
29d45e6da5

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 270 - 258
build/Three.js


+ 1 - 0
src/core/Geometry.js

@@ -14,6 +14,7 @@ THREE.Geometry = function () {
 	this.uvs = [];
 	this.uvs = [];
 	this.uvs2 = [];
 	this.uvs2 = [];
 	this.colors = [];
 	this.colors = [];
+	this.vertexKeys = [];
 
 
 	this.skinWeights = [];
 	this.skinWeights = [];
 	this.skinIndices = [];
 	this.skinIndices = [];

+ 49 - 6
src/extras/io/Loader.js

@@ -804,17 +804,58 @@ THREE.Loader.prototype = {
 			
 			
 			function init_vertices() {
 			function init_vertices() {
 
 
-				var i, l, x, y, z, r, g, b;
+				var i, l, v, vl, x, y, z, r, g, b, srcVertices, dstVertices;
 
 
-				for( i = 0, l = data.vertices.length; i < l; i += 3 ) {
+				// normal vertices
 
 
-					x = data.vertices[ i     ];
-					y = data.vertices[ i + 1 ];
-					z = data.vertices[ i + 2 ];
+				if( data.vertices !== undefined ) {
+
+					for( i = 0, l = data.vertices.length; i < l; i += 3 ) {
+	
+						x = data.vertices[ i     ];
+						y = data.vertices[ i + 1 ];
+						z = data.vertices[ i + 2 ];
+	
+						THREE.Loader.prototype.v( scope, x, y, z );
+	
+					}
+
+				// vertex animation 
+
+				} else {
+					
+					for( i = 0, l = data.vertexKeys.length; i < l; i++ ) {
+						
+						scope.vertexKeys[ i ] = {};
+						scope.vertexKeys[ i ].time = data.vertexKeys[ i ].t;
+						scope.vertexKeys[ i ].vertices = [];
+						
+						dstVertices = scope.vertexKeys[ i ].vertices;
+						srcVertices = data.vertexKeys[ i ].v;
 
 
-					THREE.Loader.prototype.v( scope, x, y, z );
 
 
+						// also add first frame to .vertices (so many things depends on vertices.length)
+
+						if( i === 0 ) {
+							
+							for( v = 0, vl = srcVertices.length; v < vl; v += 3 ) {
+	
+								scope.vertices.push( new THREE.Vertex( new THREE.Vector3( srcVertices[ v ], srcVertices[ v + 1 ], srcVertices[ v + 2 ] ) ) );
+	
+							}
+							
+						}
+						
+						for( v = 0, vl = srcVertices.length; v < vl; v += 3 ) {
+
+							dstVertices.push( new THREE.Vertex( new THREE.Vector3( srcVertices[ v ], srcVertices[ v + 1 ], srcVertices[ v + 2 ] ) ) );
+
+						}
+						
+					} 
+					
 				}
 				}
+
 				
 				
 				if ( data.colors ) {
 				if ( data.colors ) {
 					
 					
@@ -1080,6 +1121,8 @@ THREE.Loader.prototype = {
 
 
 	},
 	},
 
 
+
+
 	vc: function( scope, r, g, b ) {
 	vc: function( scope, r, g, b ) {
 
 
 		var color = new THREE.Color( 0xffffff );
 		var color = new THREE.Color( 0xffffff );

+ 2 - 0
src/materials/MeshBasicMaterial.js

@@ -54,6 +54,7 @@ THREE.MeshBasicMaterial = function ( parameters ) {
 
 
 	this.vertexColors = false;
 	this.vertexColors = false;
 	this.skinning = false;
 	this.skinning = false;
+	this.vertexAnimated = false;
 
 
 	if ( parameters ) {
 	if ( parameters ) {
 
 
@@ -81,6 +82,7 @@ THREE.MeshBasicMaterial = function ( parameters ) {
 
 
 		if ( parameters.vertexColors !== undefined ) this.vertexColors = parameters.vertexColors;
 		if ( parameters.vertexColors !== undefined ) this.vertexColors = parameters.vertexColors;
 		if ( parameters.skinning !== undefined ) this.skinning = parameters.skinning;
 		if ( parameters.skinning !== undefined ) this.skinning = parameters.skinning;
+		if ( parameters.vertexAnimated !== undefined ) this.vertexAnimated = parameters.vertexAnimated;
 
 
 	}
 	}
 
 

+ 2 - 0
src/materials/MeshLambertMaterial.js

@@ -54,6 +54,7 @@ THREE.MeshLambertMaterial = function ( parameters ) {
 
 
 	this.vertexColors = false;
 	this.vertexColors = false;
 	this.skinning = false;
 	this.skinning = false;
+	this.vertexAnimated = false;
 
 
 	if ( parameters ) {
 	if ( parameters ) {
 
 
@@ -81,6 +82,7 @@ THREE.MeshLambertMaterial = function ( parameters ) {
 
 
 		if ( parameters.vertexColors !== undefined ) this.vertexColors = parameters.vertexColors;
 		if ( parameters.vertexColors !== undefined ) this.vertexColors = parameters.vertexColors;
 		if ( parameters.skinning !== undefined ) this.skinning = parameters.skinning;
 		if ( parameters.skinning !== undefined ) this.skinning = parameters.skinning;
+		if ( parameters.vertexAnimated !== undefined ) this.vertexAnimated = parameters.vertexAnimated;
 
 
 	}
 	}
 
 

+ 2 - 0
src/materials/MeshPhongMaterial.js

@@ -62,6 +62,7 @@ THREE.MeshPhongMaterial = function ( parameters ) {
 
 
 	this.vertexColors = false;
 	this.vertexColors = false;
 	this.skinning = false;
 	this.skinning = false;
+	this.vertexAnimated = false;
 
 
 	if ( parameters ) {
 	if ( parameters ) {
 
 
@@ -93,6 +94,7 @@ THREE.MeshPhongMaterial = function ( parameters ) {
 
 
 		if ( parameters.vertexColors !== undefined ) this.vertexColors = parameters.vertexColors;
 		if ( parameters.vertexColors !== undefined ) this.vertexColors = parameters.vertexColors;
 		if ( parameters.skinning !== undefined ) this.skinning = parameters.skinning;
 		if ( parameters.skinning !== undefined ) this.skinning = parameters.skinning;
+		if ( parameters.vertexAnimated !== undefined ) this.vertexAnimated = parameters.vertexAnimated;
 
 
 	}
 	}
 
 

+ 2 - 0
src/materials/MeshShaderMaterial.js

@@ -40,6 +40,7 @@ THREE.MeshShaderMaterial = function ( parameters ) {
 
 
 	this.vertexColors = false; // must set this if shader wants to use "color" attribute stream
 	this.vertexColors = false; // must set this if shader wants to use "color" attribute stream
 	this.skinning = false;	// must set this is shader wants to use skinning attribute streams
 	this.skinning = false;	// must set this is shader wants to use skinning attribute streams
+	this.vertexAnimated = false;
 
 
 	if ( parameters ) {
 	if ( parameters ) {
 
 
@@ -61,6 +62,7 @@ THREE.MeshShaderMaterial = function ( parameters ) {
 
 
 		if ( parameters.vertexColors !== undefined ) this.vertexColors = parameters.vertexColors;
 		if ( parameters.vertexColors !== undefined ) this.vertexColors = parameters.vertexColors;
 		if ( parameters.skinning !== undefined ) this.skinning = parameters.skinning;
 		if ( parameters.skinning !== undefined ) this.skinning = parameters.skinning;
+		if ( parameters.vertexAnimated !== undefined ) this.vertexAnimated = parameters.vertexAnimated;
 
 
 	}
 	}
 
 

+ 86 - 0
src/objects/VertexAnimatedMesh.js

@@ -0,0 +1,86 @@
+/**
+ * @author Mikael Emtinger
+ */
+
+THREE.VertexAnimatedMesh = function( geometry, materials ) {
+
+	THREE.Mesh.call( this, geometry, materials );
+	
+	this.time = 0;
+	this.keyInterpolation = 0.5;
+	this.keyA = 0;
+	this.keyB = 1;
+	this.length = geometry.vertexKeys[ geometry.vertexKeys.length - 1 ].time;
+	this.isPlaying = false;
+	
+	this.animationHandlerAPI = {};
+	this.animationHandlerAPI.that = this;
+	this.animationHandlerAPI.update = this.updateTime;			// this is to not override Object3D.update
+}
+
+
+THREE.VertexAnimatedMesh.prototype = new THREE.Mesh();
+THREE.VertexAnimatedMesh.prototype.constructor = THREE.VertexAnimatedMesh;
+
+
+/*
+ * Update time (called through this.animationHandlerAPI by AnimationHandler.updste)
+ */
+
+THREE.VertexAnimatedMesh.prototype.updateTime = function( deltaTimeMS ) {
+
+	// update time
+
+	var that = this.that;
+
+	that.time = ( that.time + deltaTimeMS ) % that.length;
+	that.time = Math.max( 0, that.time );
+	
+	
+	// find keys and calculate interpolation
+	
+	var k = 0,
+		keys = that.geometry.vertexKeys,
+		kl = keys.length;
+		
+	while( keys[ k ].time <= that.time && k < kl ) {
+		
+		k++;
+	}
+	
+	if( k !== kl ) {
+		
+		that.keyA = k - 1;
+		that.keyB = k;
+		that.keyInterpolation = ( that.time - keys[ that.keyA ].time ) / ( keys[ that.keyB ].time - keys[ that.keyA ].time );
+	
+	} else {
+		
+		that.keyA = 0;
+		that.keyB = 1;
+		that.keyInterpolation = 0;
+	}
+}
+
+
+/*
+ * Play
+ */
+
+THREE.VertexAnimatedMesh.prototype.play = function( startTimeMS ) {
+	
+	this.time = Math.max( 0, startTimeMS % this.length );
+	
+	THREE.AnimationHandler.addToUpdate( this.animationHandlerAPI );	
+}
+
+
+/*
+ * Stop
+ */
+
+THREE.VertexAnimatedMesh.prototype.stop = function() {
+	
+	this.time = 0;
+	THREE.AnimationHandler.removeFromUpdate( this.animationHandlerAPI );
+}

+ 180 - 10
src/renderers/WebGLRenderer.js

@@ -267,6 +267,19 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 		geometryGroup.__webGLFaceBuffer = _gl.createBuffer();
 		geometryGroup.__webGLFaceBuffer = _gl.createBuffer();
 		geometryGroup.__webGLLineBuffer = _gl.createBuffer();
 		geometryGroup.__webGLLineBuffer = _gl.createBuffer();
+		
+		
+		if( geometryGroup.numberVertexKeys ) {
+			
+			var k, kl;
+			geometryGroup.__webGLVertexKeysBuffers = []; 
+			
+			for( k = 0, kl = geometryGroup.numberVertexKeys; k < kl; k++ ) {
+				
+				geometryGroup.__webGLVertexKeysBuffers.push( _gl.createBuffer());	
+			}
+
+		}
 
 
 	};
 	};
 
 
@@ -354,6 +367,19 @@ THREE.WebGLRenderer = function ( parameters ) {
 		geometryGroup.__webGLFaceCount = ntris * 3;
 		geometryGroup.__webGLFaceCount = ntris * 3;
 		geometryGroup.__webGLLineCount = nlines * 2;
 		geometryGroup.__webGLLineCount = nlines * 2;
 
 
+		if( geometryGroup.numberVertexKeys ) {
+			
+			var k, kl;
+			geometryGroup.__vertexKeysArrays = []; 
+			
+			for( k = 0, kl = geometryGroup.numberVertexKeys; k < kl; k++ ) {
+				
+				geometryGroup.__vertexKeysArrays.push( new Float32Array( nvertices * 3 ));	
+			}
+
+		}
+
+
 	};
 	};
 
 
 	function setMeshBuffers ( geometryGroup, object, hint ) {
 	function setMeshBuffers ( geometryGroup, object, hint ) {
@@ -367,10 +393,12 @@ THREE.WebGLRenderer = function ( parameters ) {
 			sb1, sb2, sb3, sb4,
 			sb1, sb2, sb3, sb4,
 			m, ml, i,
 			m, ml, i,
 			vn, uvi, uv2i,
 			vn, uvi, uv2i,
+			vk, vkl, vka,
 
 
 		vertexIndex = 0,
 		vertexIndex = 0,
 
 
 		offset = 0,
 		offset = 0,
+		offsetVertexKey = 0,
 		offset_uv = 0,
 		offset_uv = 0,
 		offset_uv2 = 0,
 		offset_uv2 = 0,
 		offset_face = 0,
 		offset_face = 0,
@@ -381,6 +409,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 		offset_skin = 0,
 		offset_skin = 0,
 
 
 		vertexArray = geometryGroup.__vertexArray,
 		vertexArray = geometryGroup.__vertexArray,
+		vertexKeysArrays = geometryGroup.__vertexKeysArrays,
 		uvArray = geometryGroup.__uvArray,
 		uvArray = geometryGroup.__uvArray,
 		uv2Array = geometryGroup.__uv2Array,
 		uv2Array = geometryGroup.__uv2Array,
 		normalArray = geometryGroup.__normalArray,
 		normalArray = geometryGroup.__normalArray,
@@ -400,6 +429,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 		geometry = object.geometry, // this is shared for all chunks
 		geometry = object.geometry, // this is shared for all chunks
 
 
 		dirtyVertices = geometry.__dirtyVertices,
 		dirtyVertices = geometry.__dirtyVertices,
+		dirtyVertexKeys = geometry.__dirtyVertexKeys,
 		dirtyElements = geometry.__dirtyElements,
 		dirtyElements = geometry.__dirtyElements,
 		dirtyUvs = geometry.__dirtyUvs,
 		dirtyUvs = geometry.__dirtyUvs,
 		dirtyNormals = geometry.__dirtyNormals,
 		dirtyNormals = geometry.__dirtyNormals,
@@ -407,6 +437,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 		dirtyColors = geometry.__dirtyColors,
 		dirtyColors = geometry.__dirtyColors,
 
 
 		vertices = geometry.vertices,
 		vertices = geometry.vertices,
+		vertexKeys = geometry.vertexKeys,
 		chunk_faces = geometryGroup.faces,
 		chunk_faces = geometryGroup.faces,
 		obj_faces = geometry.faces,
 		obj_faces = geometry.faces,
 		obj_uvs = geometry.uvs,
 		obj_uvs = geometry.uvs,
@@ -452,6 +483,33 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 				}
 				}
 
 
+				if ( dirtyVertexKeys ) {
+					
+					for( vk = 0, vkl = vertexKeys.length; vk < vkl; vk++ ) {
+						
+						v1 = vertexKeys[ vk ].vertices[ face.a ].position;
+						v2 = vertexKeys[ vk ].vertices[ face.b ].position;
+						v3 = vertexKeys[ vk ].vertices[ face.c ].position;
+
+						vka = vertexKeysArrays[ vk ];
+	
+						vka[ offsetVertexKey + 0 ] = v1.x;
+						vka[ offsetVertexKey + 1 ] = v1.y;
+						vka[ offsetVertexKey + 2 ] = v1.z;
+	
+						vka[ offsetVertexKey + 3 ] = v2.x;
+						vka[ offsetVertexKey + 4 ] = v2.y;
+						vka[ offsetVertexKey + 5 ] = v2.z;
+	
+						vka[ offsetVertexKey + 6 ] = v3.x;
+						vka[ offsetVertexKey + 7 ] = v3.y;
+						vka[ offsetVertexKey + 8 ] = v3.z;
+					}
+
+					offsetVertexKey += 9;
+					
+				}
+
 				if ( obj_skinWeights.length ) {
 				if ( obj_skinWeights.length ) {
 
 
 					// weights
 					// weights
@@ -704,6 +762,38 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 				}
 				}
 
 
+				if ( dirtyVertexKeys ) {
+					
+					for( vk = 0, vkl = vertexKeys.length; vk < vkl; vk++ ) {
+						
+						v1 = vertexKeys[ vk ].vertices[ face.a ].position;
+						v2 = vertexKeys[ vk ].vertices[ face.b ].position;
+						v3 = vertexKeys[ vk ].vertices[ face.c ].position;
+						v4 = vertexKeys[ vk ].vertices[ face.d ].position;
+	
+						vka = vertexKeysArrays[ vk ];
+	
+						vka[ offsetVertexKey + 0 ] = v1.x;
+						vka[ offsetVertexKey + 1 ] = v1.y;
+						vka[ offsetVertexKey + 2 ] = v1.z;
+	
+						vka[ offsetVertexKey + 3 ] = v2.x;
+						vka[ offsetVertexKey + 4 ] = v2.y;
+						vka[ offsetVertexKey + 5 ] = v2.z;
+	
+						vka[ offsetVertexKey + 6 ] = v3.x;
+						vka[ offsetVertexKey + 7 ] = v3.y;
+						vka[ offsetVertexKey + 8 ] = v3.z;
+	
+						vka[ offsetVertexKey + 9 ] = v4.x;
+						vka[ offsetVertexKey + 10 ] = v4.y;
+						vka[ offsetVertexKey + 11 ] = v4.z;
+					}
+
+					offsetVertexKey += 12;
+					
+				}
+
 				if ( obj_skinWeights.length ) {
 				if ( obj_skinWeights.length ) {
 
 
 					// weights
 					// weights
@@ -979,6 +1069,16 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 		}
 		}
 
 
+		if ( dirtyVertexKeys ) {
+			
+			for( vk = 0, vkl = vertexKeys.length; vk < vkl; vk++ ) {
+		
+				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexKeysBuffers[ vk ] );
+				_gl.bufferData( _gl.ARRAY_BUFFER, vertexKeysArrays[ vk ], hint );
+				
+			}
+		}
+
 		if ( dirtyColors && obj_colors.length ) {
 		if ( dirtyColors && obj_colors.length ) {
 
 
 			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLColorBuffer );
 			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLColorBuffer );
@@ -1389,13 +1489,14 @@ THREE.WebGLRenderer = function ( parameters ) {
 		
 		
 		parameters = { fog: fog, map: material.map, envMap: material.envMap, lightMap: material.lightMap, vertexColors: material.vertexColors,
 		parameters = { fog: fog, map: material.map, envMap: material.envMap, lightMap: material.lightMap, vertexColors: material.vertexColors,
 					   skinning: material.skinning,
 					   skinning: material.skinning,
+					   vertexAnimated: material.vertexAnimated,
 					   maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
 					   maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
 					   maxBones: maxBones };
 					   maxBones: maxBones };
 
 
 		material.program = buildProgram( material.fragmentShader, material.vertexShader, parameters );
 		material.program = buildProgram( material.fragmentShader, material.vertexShader, parameters );
 
 
 		identifiers = [ 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
 		identifiers = [ 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition',
-						'cameraInverseMatrix', 'boneGlobalMatrices'
+						'cameraInverseMatrix', 'boneGlobalMatrices', 'positionInterpolation'
 						];
 						];
 
 
 		for( u in material.uniforms ) {
 		for( u in material.uniforms ) {
@@ -1405,7 +1506,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 		}
 		}
 
 
 		cacheUniformLocations( material.program, identifiers );
 		cacheUniformLocations( material.program, identifiers );
-		cacheAttributeLocations( material.program, [ "position", "normal", "uv", "uv2", "tangent", "color",
+		cacheAttributeLocations( material.program, [ "position", "positionNextKey", "normal", "uv", "uv2", "tangent", "color",
 													 "skinVertexA", "skinVertexB", "skinIndex", "skinWeight" ] );
 													 "skinVertexA", "skinVertexB", "skinIndex", "skinWeight" ] );
 
 
 		var attributes = material.program.attributes;
 		var attributes = material.program.attributes;
@@ -1426,6 +1527,13 @@ THREE.WebGLRenderer = function ( parameters ) {
 			_gl.enableVertexAttribArray( attributes.skinWeight );
 			_gl.enableVertexAttribArray( attributes.skinWeight );
 
 
 		}
 		}
+		
+		if ( material.vertexAnimated &&
+			 attributes.positionNextKey >= 0 ) {
+
+			_gl.enableVertexAttribArray( attributes.positionNextKey );
+			 	
+		}
 
 
 	};
 	};
 
 
@@ -1540,6 +1648,11 @@ THREE.WebGLRenderer = function ( parameters ) {
 			loadUniformsSkinning( p_uniforms, object );
 			loadUniformsSkinning( p_uniforms, object );
 
 
 		}
 		}
+		
+		if ( material.vertexAnimated ) {
+			
+			loadUniformsVertexAnimated( p_uniforms, object );
+		}
 
 
 		return program;
 		return program;
 
 
@@ -1555,8 +1668,20 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 		// vertices
 		// vertices
 
 
-		_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer );
-		_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
+		if ( !material.vertexAnimated ) {
+			
+			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer );
+			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
+			
+		} else {
+			
+			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexKeysBuffers[ object.keyA ] );
+			_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
+			
+			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexKeysBuffers[ object.keyB ] );
+			_gl.vertexAttribPointer( attributes.positionNextKey, 3, _gl.FLOAT, false, 0, 0 );
+		}
+
 
 
 		// colors
 		// colors
 
 
@@ -2201,6 +2326,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 					initMeshBuffers( geometryGroup, object );
 					initMeshBuffers( geometryGroup, object );
 
 
 					geometry.__dirtyVertices = true;
 					geometry.__dirtyVertices = true;
+					geometry.__dirtyVertexKeys = true;
 					geometry.__dirtyElements = true;
 					geometry.__dirtyElements = true;
 					geometry.__dirtyUvs = true;
 					geometry.__dirtyUvs = true;
 					geometry.__dirtyNormals = true;
 					geometry.__dirtyNormals = true;
@@ -2287,7 +2413,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 				geometryGroup = geometry.geometryGroups[ g ];
 				geometryGroup = geometry.geometryGroups[ g ];
 
 
-				if ( geometry.__dirtyVertices || geometry.__dirtyElements ||
+				if ( geometry.__dirtyVertices || geometry.__dirtyVertexKeys || geometry.__dirtyElements ||
 					geometry.__dirtyUvs || geometry.__dirtyNormals ||
 					geometry.__dirtyUvs || geometry.__dirtyNormals ||
 					geometry.__dirtyColors || geometry.__dirtyTangents ) {
 					geometry.__dirtyColors || geometry.__dirtyTangents ) {
 
 
@@ -2298,6 +2424,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 			}
 			}
 
 
 			geometry.__dirtyVertices = false;
 			geometry.__dirtyVertices = false;
+			geometry.__dirtyVertexKeys = false;
 			geometry.__dirtyElements = false;
 			geometry.__dirtyElements = false;
 			geometry.__dirtyUvs = false;
 			geometry.__dirtyUvs = false;
 			geometry.__dirtyNormals = false;
 			geometry.__dirtyNormals = false;
@@ -2379,6 +2506,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 		// in its separate VBO
 		// in its separate VBO
 
 
 		var i, l, f, fl, face, material, materials, vertices, mhash, ghash, hash_map = {};
 		var i, l, f, fl, face, material, materials, vertices, mhash, ghash, hash_map = {};
+		var numberVertexKeys = geometry.vertexKeys !== undefined ? geometry.vertexKeys.length : 0;
 
 
 		geometry.geometryGroups = {};
 		geometry.geometryGroups = {};
 
 
@@ -2421,7 +2549,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 			if ( geometry.geometryGroups[ ghash ] == undefined ) {
 			if ( geometry.geometryGroups[ ghash ] == undefined ) {
 
 
-				geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0 };
+				geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numberVertexKeys': numberVertexKeys };
 
 
 			}
 			}
 
 
@@ -2434,7 +2562,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 				if ( geometry.geometryGroups[ ghash ] == undefined ) {
 				if ( geometry.geometryGroups[ ghash ] == undefined ) {
 
 
-					geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0 };
+					geometry.geometryGroups[ ghash ] = { 'faces': [], 'materials': materials, 'vertices': 0, 'numberVertexKeys': numberVertexKeys };
 
 
 				}
 				}
 
 
@@ -2587,6 +2715,8 @@ THREE.WebGLRenderer = function ( parameters ) {
 			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
 			parameters.lightMap ? "#define USE_LIGHTMAP" : "",
 			parameters.vertexColors ? "#define USE_COLOR" : "",
 			parameters.vertexColors ? "#define USE_COLOR" : "",
 			parameters.skinning ? "#define USE_SKINNING" : "",
 			parameters.skinning ? "#define USE_SKINNING" : "",
+			parameters.vertexAnimated ? "#define USE_VERTEXANIMATION" : "",
+
 
 
 			"uniform mat4 objectMatrix;",
 			"uniform mat4 objectMatrix;",
 			"uniform mat4 modelViewMatrix;",
 			"uniform mat4 modelViewMatrix;",
@@ -2598,6 +2728,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 			"uniform mat4 cameraInverseMatrix;",
 			"uniform mat4 cameraInverseMatrix;",
 
 
 			"attribute vec3 position;",
 			"attribute vec3 position;",
+			"attribute vec3 positionNextKey;",
 			"attribute vec3 normal;",
 			"attribute vec3 normal;",
 			"attribute vec3 color;",
 			"attribute vec3 color;",
 			"attribute vec2 uv;",
 			"attribute vec2 uv;",
@@ -2641,6 +2772,11 @@ THREE.WebGLRenderer = function ( parameters ) {
 		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
 		_gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices );
 
 
 	};
 	};
+	
+	function loadUniformsVertexAnimated ( uniforms, object ) {
+		
+		_gl.uniform1f( uniforms.positionInterpolation, object.keyInterpolation );
+	}
 
 
 	function loadUniformsMatrices ( uniforms, object ) {
 	function loadUniformsMatrices ( uniforms, object ) {
 
 
@@ -3633,7 +3769,33 @@ THREE.Snippets = {
 
 
 	"#endif"
 	"#endif"
 
 
-	].join("\n")
+	].join("\n"),
+	
+	// vertex animation
+
+	vertexanimated_pars_vertex: [
+
+	"#ifdef USE_VERTEXANIMATION",
+
+		"uniform float positionInterpolation;",
+
+	"#endif"
+
+	].join("\n"),
+
+	vertexanimated_vertex: [
+
+	"#ifdef USE_VERTEXANIMATION",
+
+		"gl_Position  = projectionMatrix * modelViewMatrix * vec4( mix( position, positionNextKey, positionInterpolation ), 1.0 );",
+
+	"#else",
+
+		"gl_Position = projectionMatrix * mvPosition;",
+
+	"#endif"
+
+	].join("\n")	
 
 
 };
 };
 
 
@@ -3656,7 +3818,9 @@ THREE.UniformsLib = {
 	"fogDensity": { type: "f", value: 0.00025 },
 	"fogDensity": { type: "f", value: 0.00025 },
 	"fogNear"	: { type: "f", value: 1 },
 	"fogNear"	: { type: "f", value: 1 },
 	"fogFar"	: { type: "f", value: 2000 },
 	"fogFar"	: { type: "f", value: 2000 },
-	"fogColor"	: { type: "c", value: new THREE.Color( 0xffffff ) }
+	"fogColor"	: { type: "c", value: new THREE.Color( 0xffffff ) },
+	
+	"positionInterpolation" : { type: "f", value: 0 }
 
 
 	},
 	},
 
 
@@ -3794,6 +3958,7 @@ THREE.ShaderLib = {
 			THREE.Snippets[ "envmap_pars_vertex" ],
 			THREE.Snippets[ "envmap_pars_vertex" ],
 			THREE.Snippets[ "color_pars_vertex" ],
 			THREE.Snippets[ "color_pars_vertex" ],
 			THREE.Snippets[ "skinning_pars_vertex" ],
 			THREE.Snippets[ "skinning_pars_vertex" ],
+			THREE.Snippets[ "vertexanimated_pars_vertex" ],
 
 
 			"void main() {",
 			"void main() {",
 
 
@@ -3804,6 +3969,7 @@ THREE.ShaderLib = {
 				THREE.Snippets[ "envmap_vertex" ],
 				THREE.Snippets[ "envmap_vertex" ],
 				THREE.Snippets[ "color_vertex" ],
 				THREE.Snippets[ "color_vertex" ],
 				THREE.Snippets[ "skinning_vertex" ],
 				THREE.Snippets[ "skinning_vertex" ],
+				THREE.Snippets[ "vertexanimated_vertex" ],
 
 
 			"}"
 			"}"
 
 
@@ -3854,9 +4020,10 @@ THREE.ShaderLib = {
 			THREE.Snippets[ "lights_pars_vertex" ],
 			THREE.Snippets[ "lights_pars_vertex" ],
 			THREE.Snippets[ "color_pars_vertex" ],
 			THREE.Snippets[ "color_pars_vertex" ],
 			THREE.Snippets[ "skinning_pars_vertex" ],
 			THREE.Snippets[ "skinning_pars_vertex" ],
+			THREE.Snippets[ "vertexanimated_pars_vertex" ],
 
 
 			"void main() {",
 			"void main() {",
-
+				
 				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
 				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
 
 
 				THREE.Snippets[ "map_vertex" ],
 				THREE.Snippets[ "map_vertex" ],
@@ -3868,6 +4035,7 @@ THREE.ShaderLib = {
 
 
 				THREE.Snippets[ "lights_vertex" ],
 				THREE.Snippets[ "lights_vertex" ],
 				THREE.Snippets[ "skinning_vertex" ],
 				THREE.Snippets[ "skinning_vertex" ],
+				THREE.Snippets[ "vertexanimated_vertex" ],
 
 
 			"}"
 			"}"
 
 
@@ -3934,6 +4102,7 @@ THREE.ShaderLib = {
 			THREE.Snippets[ "lights_pars_vertex" ],
 			THREE.Snippets[ "lights_pars_vertex" ],
 			THREE.Snippets[ "color_pars_vertex" ],
 			THREE.Snippets[ "color_pars_vertex" ],
 			THREE.Snippets[ "skinning_pars_vertex" ],
 			THREE.Snippets[ "skinning_pars_vertex" ],
+			THREE.Snippets[ "vertexanimated_pars_vertex" ],
 
 
 			"void main() {",
 			"void main() {",
 
 
@@ -3955,6 +4124,7 @@ THREE.ShaderLib = {
 
 
 				THREE.Snippets[ "lights_vertex" ],
 				THREE.Snippets[ "lights_vertex" ],
 				THREE.Snippets[ "skinning_vertex" ],
 				THREE.Snippets[ "skinning_vertex" ],
+				THREE.Snippets[ "vertexanimated_vertex" ],
 
 
 			"}"
 			"}"
 
 

+ 1 - 0
utils/build.py

@@ -62,6 +62,7 @@ COMMON_FILES = [
 'objects/Ribbon.js',
 'objects/Ribbon.js',
 'objects/Sound.js',
 'objects/Sound.js',
 'objects/LOD.js',
 'objects/LOD.js',
+'objects/VertexAnimatedMesh.js',
 'scenes/Scene.js',
 'scenes/Scene.js',
 'scenes/Fog.js',
 'scenes/Fog.js',
 'scenes/FogExp2.js',
 'scenes/FogExp2.js',

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác