/**
 * @author bhouston / http://exocortex.com
 */

THREE.Ray = function ( origin, direction ) {


	if ( origin === undefined && direction === undefined ) {

		this.origin = new THREE.Vector3();
		this.direction = new THREE.Vector3( 0, 0, 0 );

	} else {

		this.origin = origin.clone();
		this.direction = direction.clone();

	}

};

THREE.Ray.prototype = {

	constructor: THREE.Ray,

	set: function ( origin, direction ) {

		this.origin.copy( origin );
		this.direction.copy( direction );

		return this;

	},

	copy: function ( ray ) {

		this.origin.copy( ray.origin );
		this.direction.copy( ray.direction );

		return this;

	},

	at: function( t ) {

		return this.direction.clone().multiplyScalar( t ).addSelf( this.origin );

	},

	recastSelf: function ( t ) {

		this.origin = this.at( t );

		return this;

	},

	recast: function ( t ) {

		return this.clone().recastSelf( t );

	},

	flip: function () {

		this.direction.negate();

		return this;
	},

	closestPointToPoint: function ( point ) {

		var result = point.clone().subSelf( this.origin );
		var directionDistance = result.dot( this.direction );

		return result.copy( this.direction ).multiplyScalar( directionDistance ).addSelf( this.origin );

	},

	distanceToPoint: function ( point ) {

		// NOTE: this creates a THREE.VEctor3 internally via closestPointToPoint
		// that is never returned, can be further GC optimized

		return this.closestPointToPoint( point ).distanceTo( point );

	},

	/*
	// Commented out because this does not handle the case of non-intersecting
	// perpendicular lines
	closestPointToRay: function ( ray ) {

		// Assumes the lines are normalized
		// based on algorithm in ILM's Imath Plane class.

	    THREE.Ray.__v1.copy( this.origin ).subSelf( ray.origin );
	    var c = this.direction.dot( THREE.Ray.__v1 );
	    var a = ray.direction.dot( this.direction );
	    var f = ray.direction.dot( THREE.Ray.__v1 );
	    var num = c - a * f;
	    var denom = a*a - 1;

	    var absDenom = ( ( denom >= 0 ) ? denom: -denom );

	    if ( absDenom < 1 )
	    {
			var absNum = ( ( num >= 0 ) ? num: -num );

			if (absNum >= absDenom * Number.MAX_VALUE ) {

				// Unsure if this is the correct method to handle this case.
				return this.origin.clone();

		    }
	    }

	    return this.direction.clone().multiplyScalar( num / denom ).addSelf( this.origin );

	},
	*/

	/*
	// Commented out because this does not handle the case of non-intersecting
	// perpendicular lines
	distanceToRay: function ( ray ) {		

		THREE.Ray.__v1.copy( this.direction ).crossSelf( ray.direction );
		THREE.Ray.__v2.copy( ray.origin ).subSelf( this.origin );


		var d = THREE.Ray.__v1.dot( THREE.Ray.__v2 );
		if( d >= 0 ) {

			return d;

		} else {

			// Unsure if this is the correct method to handle this case.
			return -1;

		}
	},*/

	isIntersectionPlane: function ( plane ) {

		// check if the line and plane are non-perpendicular, if they
		// eventually they will intersect.
		var denominator = plane.normal.dot( this.direction );
		if ( denominator != 0 ) {

			return true;

		}
		
		// line is coplanar, return origin
		if( plane.distanceToPoint( this.origin ) == 0 ) {

			return true;

		}

		return false;

	},

	intersectPlane: function ( plane ) {

		var denominator = plane.normal.dot( this.direction );
		if ( denominator == 0 ) {

			// line is coplanar, return origin
			if( plane.distanceToPoint( this.origin ) == 0 ) {

				return this.origin.clone();

			}

			// Unsure if this is the correct method to handle this case.
			return undefined;

		}

		var t = - ( ( this.origin.dot( plane.normal ) ) + plane.constant ) / denominator;

		return this.at( t );

	},

	equals: function ( ray ) {

		return ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );

	},

	clone: function () {

		return new THREE.Ray().copy( this );

	}

};

THREE.Ray.__v1 = new THREE.Vector3();
THREE.Ray.__v2 = new THREE.Vector3();
@@ -97,21 +97,21 @@
 %0A%0A%0A%09
-if ( 
+this.
 origin =
 == u
@@ -110,37 +110,19 @@
 in =
-== undefined && directio
+ origi
 n 
+!
 ==
-=
  und
@@ -128,36 +128,34 @@
 defined 
-) %7B%0A%0A%09%09this.origin =
+? origin.clone() :
  new THR
@@ -164,25 +164,24 @@
 .Vector3();%0A
-%09
 %09this.direct
@@ -190,123 +190,74 @@
 n = 
-new THREE.Vector3( 0, 0, 0 );%0A%0A%09%7D else %7B%0A%0A%09%09this.origin = origin.clone();%0A%09%09this.direction = direction.clone();%0A%0A%09%7D
+direction !== undefined ? direction.clone() : new THREE.Vector3();
 %0A%0A%7D;
@@ -2997,18 +2997,16 @@
 e;%0A%0A%09%09%7D%0A
-%09%09
 %0A%09%09// li

simplify Ray constructor based on @mrdoob's feedback here: https://github.com/mrdoob/three.js/pull/2734#commitcomment-2244506