text: /**
   * Spline from Tween.js, slightly optimized (and trashed)
   * http://sole.github.com/tween.js/examples/05_spline.html
   *
   * @author mrdoob / http://mrdoob.com/
   * @author alteredq / http://alteredqualia.com/
   */
  
  THREE.Spline = function ( points ) {
  
  	this.points = points;
  
  	var c = [], v3 = { x: 0, y: 0, z: 0 },
  	point, intPoint, weight, w2, w3,
  	pa, pb, pc, pd;
  
  	this.initFromArray = function( a ) {
  
  		this.points = [];
  
  		for ( var i = 0; i < a.length; i++ ) {
  
  			this.points[ i ] = { x: a[ i ][ 0 ], y: a[ i ][ 1 ], z: a[ i ][ 2 ] };
  
  		}
  
  	};
  
  	this.getPoint = function ( k ) {
  
  		point = ( this.points.length - 1 ) * k;
  		intPoint = Math.floor( point );
  		weight = point - intPoint;
  
  		c[ 0 ] = intPoint == 0 ? intPoint : intPoint - 1;
  		c[ 1 ] = intPoint;
  		c[ 2 ] = intPoint > this.points.length - 2 ? intPoint : intPoint + 1;
  		c[ 3 ] = intPoint > this.points.length - 3 ? intPoint : intPoint + 2;
  
  		pa = this.points[ c[ 0 ] ];
  		pb = this.points[ c[ 1 ] ];
  		pc = this.points[ c[ 2 ] ];
  		pd = this.points[ c[ 3 ] ];
  
  		w2 = weight * weight;
  		w3 = weight * w2;
  
  		v3.x = interpolate( pa.x, pb.x, pc.x, pd.x, weight, w2, w3 );
  		v3.y = interpolate( pa.y, pb.y, pc.y, pd.y, weight, w2, w3 );
  		v3.z = interpolate( pa.z, pb.z, pc.z, pd.z, weight, w2, w3 );
  
  		return v3;
  
  	};
  
  	this.getControlPointsArray = function () {
  
  		var i, p, l = this.points.length,
  			coords = [];
  
  		for ( i = 0; i < l; i ++ ) {
  
  			p = this.points[ i ];
  			coords[ i ] = [ p.x, p.y, p.z ];
  
  		}
  
  		return coords;
  
  	};
  
  	// approximate length by summing linear segments
  
  	this.getLength = function ( nSubDivisions ) {
  
  		var i, index, nSamples,
  			point = 0, intPoint = 0, oldIntPoint = 0,
  			oldPosition = new THREE.Vector3(),
  			tmpVec = new THREE.Vector3(),
  			chunkLengths = [],
  			totalLength = 0;
  
  		// first point has 0 length
  
  		chunkLengths[ 0 ] = 0;
  
  		if ( !nSubDivisions ) nSubDivisions = 100;
  
  		nSamples = this.points.length * nSubDivisions;
  
  		oldPosition.copy( this.points[ 0 ] );
  
  		for ( i = 1; i < nSamples; i ++ ) {
  
  			index = i / nSamples;
  
  			position = this.getPoint( index );
  			tmpVec.copy( position );
  
  			totalLength += tmpVec.distanceTo( oldPosition );
  
  			oldPosition.copy( position );
  
  			point = ( this.points.length - 1 ) * index;
  			intPoint = Math.floor( point );
  
  			if ( intPoint != oldIntPoint ) {
  
  				chunkLengths[ intPoint ] = totalLength;
  				oldIntPoint = intPoint;
  
  			}
  
  		}
  
  		// last point ends with total length
  
  		chunkLengths[ chunkLengths.length ] = totalLength;
  
  		return { chunks: chunkLengths, total: totalLength };
  
  	};
  
  	this.reparametrizeByArcLength = function ( samplingCoef ) {
  
  		var i, j,
  			index, indexCurrent, indexNext,
  			linearDistance, realDistance,
  			sampling,
  			newpoints = [],
  			tmpVec = new THREE.Vector3(),
  			sl = this.getLength();
  
  		newpoints.push( tmpVec.copy( this.points[ 0 ] ).clone() );
  
  		for ( i = 1; i < this.points.length; i++ ) {
  
  			//tmpVec.copy( this.points[ i - 1 ] );
  			//linearDistance = tmpVec.distanceTo( this.points[ i ] );
  
  			realDistance = sl.chunks[ i ] - sl.chunks[ i - 1 ];
  
  			sampling = Math.ceil( samplingCoef * realDistance / sl.total );
  
  			indexCurrent = ( i - 1 ) / ( this.points.length - 1 );
  			indexNext = i / ( this.points.length - 1 );
  
  			for ( j = 1; j < sampling - 1; j++ ) {
  
  				index = indexCurrent + j * ( 1 / sampling ) * ( indexNext - indexCurrent );
  
  				position = this.getPoint( index );
  				newpoints.push( tmpVec.copy( position ).clone() );
  
  			}
  
  			newpoints.push( tmpVec.copy( this.points[ i ] ).clone() );
  
  		}
  
  		this.points = newpoints;
  
  	};
  
  	// Catmull-Rom
  
  	function interpolate( p0, p1, p2, p3, t, t2, t3 ) {
  
  		var v0 = ( p2 - p0 ) * 0.5,
  			v1 = ( p3 - p1 ) * 0.5;
  
  		return ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1;
  
  	};
  
  };
  