Browse Source

Merge remote-tracking branch 'upstream/dev' into dev

zhaoy 7 years ago
parent
commit
5a72b2685b

+ 1 - 1
.github/ISSUE_TEMPLATE.md

@@ -19,7 +19,7 @@ Please also include a live example if possible. You can start from these templat
 ##### Three.js version
 
 - [ ] Dev
-- [ ] r93
+- [ ] r94
 - [ ] ...
 
 ##### Browser

+ 102 - 14
build/three.js

@@ -185,7 +185,7 @@
 
 	} );
 
-	var REVISION = '94dev';
+	var REVISION = '94';
 	var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };
 	var CullFaceNone = 0;
 	var CullFaceBack = 1;
@@ -2436,19 +2436,21 @@
 
 			}
 
-			var sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );
+			var sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta;
 
-			if ( Math.abs( sinHalfTheta ) < 0.001 ) {
+			if ( sqrSinHalfTheta <= Number.EPSILON ) {
 
-				this._w = 0.5 * ( w + this._w );
-				this._x = 0.5 * ( x + this._x );
-				this._y = 0.5 * ( y + this._y );
-				this._z = 0.5 * ( z + this._z );
+				var s = 1 - t;
+				this._w = s * w + t * this._w;
+				this._x = s * x + t * this._x;
+				this._y = s * y + t * this._y;
+				this._z = s * z + t * this._z;
 
-				return this;
+				return this.normalize();
 
 			}
 
+			var sinHalfTheta = Math.sqrt( sqrSinHalfTheta );
 			var halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );
 			var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,
 				ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;
@@ -24781,18 +24783,80 @@
 		raycast: ( function () {
 
 			var intersectPoint = new Vector3();
-			var worldPosition = new Vector3();
 			var worldScale = new Vector3();
+			var mvPosition = new Vector3();
 
-			return function raycast( raycaster, intersects ) {
+			var alignedPosition = new Vector2();
+			var rotatedPosition = new Vector2();
+			var viewWorldMatrix = new Matrix4();
+
+			var vA = new Vector3();
+			var vB = new Vector3();
+			var vC = new Vector3();
+
+			function transformVertex( vertexPosition, mvPosition, center, scale, sin, cos ) {
 
-				worldPosition.setFromMatrixPosition( this.matrixWorld );
-				raycaster.ray.closestPointToPoint( worldPosition, intersectPoint );
+				// compute position in camera space
+				alignedPosition.subVectors( vertexPosition, center ).addScalar( 0.5 ).multiply( scale );
+
+				// to check if rotation is not zero
+				if ( sin !== undefined ) {
+
+					rotatedPosition.x = ( cos * alignedPosition.x ) - ( sin * alignedPosition.y );
+					rotatedPosition.y = ( sin * alignedPosition.x ) + ( cos * alignedPosition.y );
+
+				} else {
+
+					rotatedPosition.copy( alignedPosition );
+
+				}
+
+
+				vertexPosition.copy( mvPosition );
+				vertexPosition.x += rotatedPosition.x;
+				vertexPosition.y += rotatedPosition.y;
+
+				// transform to world space
+				vertexPosition.applyMatrix4( viewWorldMatrix );
+
+			}
+
+			return function raycast( raycaster, intersects ) {
 
 				worldScale.setFromMatrixScale( this.matrixWorld );
-				var guessSizeSq = worldScale.x * worldScale.y / 4;
+				viewWorldMatrix.getInverse( this.modelViewMatrix ).premultiply( this.matrixWorld );
+				mvPosition.setFromMatrixPosition( this.modelViewMatrix );
+
+				var rotation = this.material.rotation;
+				var sin, cos;
+				if ( rotation !== 0 ) {
+
+					cos = Math.cos( rotation );
+					sin = Math.sin( rotation );
+
+				}
+
+				var center = this.center;
+
+				transformVertex( vA.set( - 0.5, - 0.5, 0 ), mvPosition, center, worldScale, sin, cos );
+				transformVertex( vB.set( 0.5, - 0.5, 0 ), mvPosition, center, worldScale, sin, cos );
+				transformVertex( vC.set( 0.5, 0.5, 0 ), mvPosition, center, worldScale, sin, cos );
 
-				if ( worldPosition.distanceToSquared( intersectPoint ) > guessSizeSq ) return;
+				// check first triangle
+				var intersect = raycaster.ray.intersectTriangle( vA, vB, vC, false, intersectPoint );
+
+				if ( intersect === null ) {
+
+					// check second triangle
+					transformVertex( vB.set( - 0.5, 0.5, 0 ), mvPosition, center, worldScale, sin, cos );
+					intersect = raycaster.ray.intersectTriangle( vA, vC, vB, false, intersectPoint );
+					if ( intersect === null ) {
+
+						return;
+
+					}
+
+				}
 
 				var distance = raycaster.ray.origin.distanceTo( intersectPoint );
 
@@ -39436,6 +39500,8 @@
 
 			}
 
+			return this;
+
 		},
 
 		getFilter: function () {
@@ -39461,6 +39527,8 @@
 			this.gain.connect( this.filter );
 			this.filter.connect( this.context.destination );
 
+			return this;
+
 		},
 
 		getMasterVolume: function () {
@@ -39473,6 +39541,8 @@
 
 			this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 );
 
+			return this;
+
 		},
 
 		updateMatrixWorld: ( function () {
@@ -39866,6 +39936,8 @@
 
 			this.panner.refDistance = value;
 
+			return this;
+
 		},
 
 		getRolloffFactor: function () {
@@ -39878,6 +39950,8 @@
 
 			this.panner.rolloffFactor = value;
 
+			return this;
+
 		},
 
 		getDistanceModel: function () {
@@ -39890,6 +39964,8 @@
 
 			this.panner.distanceModel = value;
 
+			return this;
+
 		},
 
 		getMaxDistance: function () {
@@ -39902,6 +39978,18 @@
 
 			this.panner.maxDistance = value;
 
+			return this;
+
+		},
+
+		setDirectionalCone: function ( coneInnerAngle, coneOuterAngle, coneOuterGain ) {
+
+			this.panner.coneInnerAngle = coneInnerAngle;
+			this.panner.coneOuterAngle = coneOuterAngle;
+			this.panner.coneOuterGain = coneOuterGain;
+
+			return this;
+
 		},
 
 		updateMatrixWorld: ( function () {

File diff suppressed because it is too large
+ 194 - 194
build/three.min.js


+ 102 - 14
build/three.module.js

@@ -179,7 +179,7 @@ Object.assign( EventDispatcher.prototype, {
 
 } );
 
-var REVISION = '94dev';
+var REVISION = '94';
 var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };
 var CullFaceNone = 0;
 var CullFaceBack = 1;
@@ -2430,19 +2430,21 @@ Object.assign( Quaternion.prototype, {
 
 		}
 
-		var sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );
+		var sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta;
 
-		if ( Math.abs( sinHalfTheta ) < 0.001 ) {
+		if ( sqrSinHalfTheta <= Number.EPSILON ) {
 
-			this._w = 0.5 * ( w + this._w );
-			this._x = 0.5 * ( x + this._x );
-			this._y = 0.5 * ( y + this._y );
-			this._z = 0.5 * ( z + this._z );
+			var s = 1 - t;
+			this._w = s * w + t * this._w;
+			this._x = s * x + t * this._x;
+			this._y = s * y + t * this._y;
+			this._z = s * z + t * this._z;
 
-			return this;
+			return this.normalize();
 
 		}
 
+		var sinHalfTheta = Math.sqrt( sqrSinHalfTheta );
 		var halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );
 		var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,
 			ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;
@@ -24775,18 +24777,80 @@ Sprite.prototype = Object.assign( Object.create( Object3D.prototype ), {
 	raycast: ( function () {
 
 		var intersectPoint = new Vector3();
-		var worldPosition = new Vector3();
 		var worldScale = new Vector3();
+		var mvPosition = new Vector3();
 
-		return function raycast( raycaster, intersects ) {
+		var alignedPosition = new Vector2();
+		var rotatedPosition = new Vector2();
+		var viewWorldMatrix = new Matrix4();
+
+		var vA = new Vector3();
+		var vB = new Vector3();
+		var vC = new Vector3();
+
+		function transformVertex( vertexPosition, mvPosition, center, scale, sin, cos ) {
 
-			worldPosition.setFromMatrixPosition( this.matrixWorld );
-			raycaster.ray.closestPointToPoint( worldPosition, intersectPoint );
+			// compute position in camera space
+			alignedPosition.subVectors( vertexPosition, center ).addScalar( 0.5 ).multiply( scale );
+
+			// to check if rotation is not zero
+			if ( sin !== undefined ) {
+
+				rotatedPosition.x = ( cos * alignedPosition.x ) - ( sin * alignedPosition.y );
+				rotatedPosition.y = ( sin * alignedPosition.x ) + ( cos * alignedPosition.y );
+
+			} else {
+
+				rotatedPosition.copy( alignedPosition );
+
+			}
+
+
+			vertexPosition.copy( mvPosition );
+			vertexPosition.x += rotatedPosition.x;
+			vertexPosition.y += rotatedPosition.y;
+
+			// transform to world space
+			vertexPosition.applyMatrix4( viewWorldMatrix );
+
+		}
+
+		return function raycast( raycaster, intersects ) {
 
 			worldScale.setFromMatrixScale( this.matrixWorld );
-			var guessSizeSq = worldScale.x * worldScale.y / 4;
+			viewWorldMatrix.getInverse( this.modelViewMatrix ).premultiply( this.matrixWorld );
+			mvPosition.setFromMatrixPosition( this.modelViewMatrix );
+
+			var rotation = this.material.rotation;
+			var sin, cos;
+			if ( rotation !== 0 ) {
+
+				cos = Math.cos( rotation );
+				sin = Math.sin( rotation );
+
+			}
+
+			var center = this.center;
+
+			transformVertex( vA.set( - 0.5, - 0.5, 0 ), mvPosition, center, worldScale, sin, cos );
+			transformVertex( vB.set( 0.5, - 0.5, 0 ), mvPosition, center, worldScale, sin, cos );
+			transformVertex( vC.set( 0.5, 0.5, 0 ), mvPosition, center, worldScale, sin, cos );
 
-			if ( worldPosition.distanceToSquared( intersectPoint ) > guessSizeSq ) return;
+			// check first triangle
+			var intersect = raycaster.ray.intersectTriangle( vA, vB, vC, false, intersectPoint );
+
+			if ( intersect === null ) {
+
+				// check second triangle
+				transformVertex( vB.set( - 0.5, 0.5, 0 ), mvPosition, center, worldScale, sin, cos );
+				intersect = raycaster.ray.intersectTriangle( vA, vC, vB, false, intersectPoint );
+				if ( intersect === null ) {
+
+					return;
+
+				}
+
+			}
 
 			var distance = raycaster.ray.origin.distanceTo( intersectPoint );
 
@@ -39430,6 +39494,8 @@ AudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 		}
 
+		return this;
+
 	},
 
 	getFilter: function () {
@@ -39455,6 +39521,8 @@ AudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {
 		this.gain.connect( this.filter );
 		this.filter.connect( this.context.destination );
 
+		return this;
+
 	},
 
 	getMasterVolume: function () {
@@ -39467,6 +39535,8 @@ AudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 		this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 );
 
+		return this;
+
 	},
 
 	updateMatrixWorld: ( function () {
@@ -39860,6 +39930,8 @@ PositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {
 
 		this.panner.refDistance = value;
 
+		return this;
+
 	},
 
 	getRolloffFactor: function () {
@@ -39872,6 +39944,8 @@ PositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {
 
 		this.panner.rolloffFactor = value;
 
+		return this;
+
 	},
 
 	getDistanceModel: function () {
@@ -39884,6 +39958,8 @@ PositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {
 
 		this.panner.distanceModel = value;
 
+		return this;
+
 	},
 
 	getMaxDistance: function () {
@@ -39896,6 +39972,18 @@ PositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {
 
 		this.panner.maxDistance = value;
 
+		return this;
+
+	},
+
+	setDirectionalCone: function ( coneInnerAngle, coneOuterAngle, coneOuterGain ) {
+
+		this.panner.coneInnerAngle = coneInnerAngle;
+		this.panner.coneOuterAngle = coneOuterAngle;
+		this.panner.coneOuterGain = coneOuterGain;
+
+		return this;
+
 	},
 
 	updateMatrixWorld: ( function () {

+ 2 - 2
docs/api/deprecated/DeprecatedList.html

@@ -522,9 +522,9 @@
 
 		<h3>[page:WebGLProgram]</h3>
 		<p>
-			WebGLProgram.uniforms is now [page:	WebGLProgram.getUniforms]().<br /><br />
+			WebGLProgram.uniforms is now [page:WebGLProgram.getUniforms]().<br /><br />
 
-			WebGLProgram.attributes is now [page:	WebGLProgram.getAttributes]().
+			WebGLProgram.attributes is now [page:WebGLProgram.getAttributes]().
 		</p>
 
 		<h3>[page:WebGLRenderer]</h3>

+ 6 - 6
docs/examples/loaders/GLTFLoader.html

@@ -12,8 +12,8 @@
 		<h1>[name]</h1>
 
 		<p class="desc"> A loader for <em>glTF 2.0</em> resources. <br /><br />
-		<a href="https://www.khronos.org/gltf">glTF</a> (GL Transmission Format) is an
-		<a href="https://github.com/KhronosGroup/glTF/tree/master/specification/2.0">open format specification</a>
+		[link:https://www.khronos.org/gltf glTF] (GL Transmission Format) is an
+		[link:https://github.com/KhronosGroup/glTF/tree/master/specification/2.0 open format specification]
 		for efficient delivery and loading of 3D content. Assets may be provided either in JSON (.gltf)
 		or binary (.glb) format. External files store textures (.jpg, .png) and additional binary
 		data (.bin). A glTF asset may deliver one or more scenes, including meshes, materials,
@@ -24,7 +24,7 @@
 
 		<p>
 			GLTFLoader supports the following
-			<a target="_blank" href="https://github.com/KhronosGroup/glTF/tree/master/extensions/">glTF 2.0 extensions</a>:
+			[link:https://github.com/KhronosGroup/glTF/tree/master/extensions/ glTF 2.0 extensions]:
 		</p>
 
 		<ul>
@@ -60,7 +60,7 @@
 				gltf.asset; // Object
 
 			},
-			// called when loading is in progresses
+			// called while loading is progressing
 			function ( xhr ) {
 
 				console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
@@ -79,9 +79,9 @@
 
 		<h2>Browser compatibility</h2>
 
-		<p>GLTFLoader relies on ES6 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promises</a>,
+		<p>GLTFLoader relies on ES6 [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise Promises],
 		which are not supported in IE11. To use the loader in IE11, you must
-		<a href="https://github.com/stefanpenner/es6-promise">include a polyfill</a>
+		[link:https://github.com/stefanpenner/es6-promise include a polyfill]
 		providing a Promise replacement.</p>
 
 		<h2>Custom extensions</h2>

+ 6 - 6
docs/list.js

@@ -8,11 +8,11 @@ var list = {
 			"Browser support": "manual/introduction/Browser-support",
 			"WebGL compatibility check": "manual/introduction/WebGL-compatibility-check",
 			"How to run things locally": "manual/introduction/How-to-run-things-locally",
-			"Drawing Lines": "manual/introduction/Drawing-lines",
-			"Creating Text": "manual/introduction/Creating-text",
-			"Loading 3D Models": "manual/introduction/Loading-3D-models",
-			"Migration Guide": "manual/introduction/Migration-guide",
-			"Code Style Guide": "manual/introduction/Code-style-guide",
+			"Drawing lines": "manual/introduction/Drawing-lines",
+			"Creating text": "manual/introduction/Creating-text",
+			"Loading 3D models": "manual/introduction/Loading-3D-models",
+			"Migration guide": "manual/introduction/Migration-guide",
+			"Code style guide": "manual/introduction/Code-style-guide",
 			"FAQ": "manual/introduction/FAQ",
 			"Useful links": "manual/introduction/Useful-links"
 		},
@@ -20,7 +20,7 @@ var list = {
 		"Next Steps": {
 			"How to update things": "manual/introduction/How-to-update-things",
 			"Matrix transformations": "manual/introduction/Matrix-transformations",
-			"Animation System": "manual/introduction/Animation-system"
+			"Animation system": "manual/introduction/Animation-system"
 		},
 
 		"Build Tools": {

+ 1 - 2
docs/manual/introduction/Creating-a-scene.html

@@ -113,8 +113,7 @@
 		cube.rotation.y += 0.01;
 		</code>
 
-		<p>This will be run every frame (normally 60 times per second), and give the cube a nice rotation animation. Basically, anything you want to move or change while the app is running has to go through the animate loop. You can of course call other functions from there, so that you don't end up with a <strong>animate</strong> function that's hundreds of p.
-		</div>
+		<p>This will be run every frame (normally 60 times per second), and give the cube a nice rotation animation. Basically, anything you want to move or change while the app is running has to go through the animate loop. You can of course call other functions from there, so that you don't end up with a <strong>animate</strong> function that's hundreds of lines.</p>
 
 		<h2>The result</h2>
 		<p>Congratulations! You have now completed your first three.js application. It's simple, you have to start somewhere.</p>

+ 1 - 1
examples/files.js

@@ -320,13 +320,13 @@ var files = {
 	"webvr": [
 		"webvr_ballshooter",
 		"webvr_cubes",
+		"webvr_dragging",
 		"webvr_lorenzattractor",
 		"webvr_panorama",
 		"webvr_rollercoaster",
 		"webvr_sandbox",
 		"webvr_video",
 		"webvr_vive",
-		"webvr_vive_dragging",
 		"webvr_vive_paint",
 		"webvr_vive_sculpt"
 	],

+ 0 - 1
examples/js/animation/CCDIKSolver.js

@@ -393,7 +393,6 @@ THREE.CCDIKSolver = ( function () {
 		_init: function () {
 
 			var self = this;
-			var mesh = this.root;
 			var iks = this.iks;
 
 			function createLineGeometry( ik ) {

+ 2 - 3
examples/js/animation/MMDPhysics.js

@@ -746,8 +746,8 @@ THREE.MMDPhysics = ( function () {
 				s = Math.sqrt( t + 1.0 ) * 2;
 				w = 0.25 * s;
 				x = ( m[ 7 ] - m[ 5 ] ) / s;
-				y = ( m[ 2 ] - m[ 6 ] ) / s; 
-				z = ( m[ 3 ] - m[ 1 ] ) / s; 
+				y = ( m[ 2 ] - m[ 6 ] ) / s;
+				z = ( m[ 3 ] - m[ 1 ] ) / s;
 
 			} else if( ( m[ 0 ] > m[ 4 ] ) && ( m[ 0 ] > m[ 8 ] ) ) {
 
@@ -1348,7 +1348,6 @@ THREE.MMDPhysics = ( function () {
 
 		_init: function () {
 
-			var mesh = this.root;
 			var bodies = this.physics.bodies;
 
 			function createGeometry( param ) {

+ 17 - 15
examples/js/loaders/SVGLoader.js

@@ -373,22 +373,24 @@ THREE.SVGLoader.prototype = {
 					case 'Z':
 					case 'z':
 						path.currentPath.autoClose = true;
-						// Reset point to beginning of Path
-						var curve = path.currentPath.curves[ 0 ];
-						if ( curve.isLineCurve ) {
-							point.x = curve.v1.x;
-							point.y = curve.v1.y;
-						} else if ( curve.isEllipseCurve || curve.isArcCurve ) {
-							point.x = curve.aX;
-							point.y = curve.aY;
-						} else if ( curve.isCubicBezierCurve || curve.isQuadraticBezierCurve ) {
-							point.x = curve.v0.x;
-							point.y = curve.v0.y;
-						} else if ( curve.isSplineCurve ) {
-							point.x = curve.points[ 0 ].x;
-							point.y = curve.points[ 0 ].y;
+						if ( path.currentPath.curves.length > 0 ) {
+							// Reset point to beginning of Path
+							var curve = path.currentPath.curves[ 0 ];
+							if ( curve.isLineCurve ) {
+								point.x = curve.v1.x;
+								point.y = curve.v1.y;
+							} else if ( curve.isEllipseCurve || curve.isArcCurve ) {
+								point.x = curve.aX;
+								point.y = curve.aY;
+							} else if ( curve.isCubicBezierCurve || curve.isQuadraticBezierCurve ) {
+								point.x = curve.v0.x;
+								point.y = curve.v0.y;
+							} else if ( curve.isSplineCurve ) {
+								point.x = curve.points[ 0 ].x;
+								point.y = curve.points[ 0 ].y;
+							}
+							path.currentPath.currentPoint.copy( point );
 						}
-						path.currentPath.currentPoint.copy( point );
 						break;
 
 					default:

+ 5 - 1
examples/misc_controls_map.html

@@ -84,7 +84,8 @@
 
 				// world
 
-				var geometry = new THREE.CylinderBufferGeometry( 0, 10, 30, 4, 1 );
+				var geometry = new THREE.BoxBufferGeometry( 1, 1, 1 );
+				geometry.translate( 0, 0.5, 0 );
 				var material = new THREE.MeshPhongMaterial( { color: 0xffffff, flatShading: true } );
 
 				for ( var i = 0; i < 500; i ++ ) {
@@ -93,6 +94,9 @@
 					mesh.position.x = Math.random() * 1600 - 800;
 					mesh.position.y = 0;
 					mesh.position.z = Math.random() * 1600 - 800;
+					mesh.scale.x = 20;
+					mesh.scale.y = Math.random() * 80 + 10;
+					mesh.scale.z = 20;
 					mesh.updateMatrix();
 					mesh.matrixAutoUpdate = false;
 					scene.add( mesh );

+ 10 - 35
examples/webvr_vive_dragging.html → examples/webvr_dragging.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html lang="en">
 	<head>
-		<title>three.js webvr - htc vive - dragging</title>
+		<title>three.js webvr - dragging</title>
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<!-- Origin Trial Token, feature = WebVR (For Chrome M62+), origin = https://threejs.org, expires = 2018-07-25 -->
@@ -26,12 +26,8 @@
 	<body>
 
 		<script src="../build/three.js"></script>
-
-		<script src="js/vr/ViveController.js"></script>
 		<script src="js/vr/WebVR.js"></script>
 
-		<script src="js/loaders/OBJLoader.js"></script>
-
 		<script>
 
 			var container;
@@ -56,7 +52,7 @@
 				info.style.top = '10px';
 				info.style.width = '100%';
 				info.style.textAlign = 'center';
-				info.innerHTML = '<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - htc vive';
+				info.innerHTML = '<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - dragging';
 				container.appendChild( info );
 
 				scene = new THREE.Scene();
@@ -141,34 +137,16 @@
 
 				// controllers
 
-				controller1 = new THREE.ViveController( 0 );
-				controller1.standingMatrix = renderer.vr.getStandingMatrix();
-				controller1.addEventListener( 'triggerdown', onTriggerDown );
-				controller1.addEventListener( 'triggerup', onTriggerUp );
+				controller1 = renderer.vr.getController( 0 );
+				controller1.addEventListener( 'selectstart', onSelectStart );
+				controller1.addEventListener( 'selectend', onSelectEnd );
 				scene.add( controller1 );
 
-				controller2 = new THREE.ViveController( 1 );
-				controller2.standingMatrix = renderer.vr.getStandingMatrix();
-				controller2.addEventListener( 'triggerdown', onTriggerDown );
-				controller2.addEventListener( 'triggerup', onTriggerUp );
+				controller2 = renderer.vr.getController( 0 );
+				controller1.addEventListener( 'selectstart', onSelectStart );
+				controller1.addEventListener( 'selectend', onSelectEnd );
 				scene.add( controller2 );
 
-				var loader = new THREE.OBJLoader();
-				loader.setPath( 'models/obj/vive-controller/' );
-				loader.load( 'vr_controller_vive_1_5.obj', function ( object ) {
-
-					var loader = new THREE.TextureLoader();
-					loader.setPath( 'models/obj/vive-controller/' );
-
-					var controller = object.children[ 0 ];
-					controller.material.map = loader.load( 'onepointfive_texture.png' );
-					controller.material.specularMap = loader.load( 'onepointfive_spec.png' );
-
-					controller1.add( object.clone() );
-					controller2.add( object.clone() );
-
-				} );
-
 				//
 
 				var geometry = new THREE.BufferGeometry().setFromPoints( [ new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 0, 0, - 1 ) ] );
@@ -197,7 +175,7 @@
 
 			}
 
-			function onTriggerDown( event ) {
+			function onSelectStart( event ) {
 
 				var controller = event.target;
 
@@ -221,7 +199,7 @@
 
 			}
 
-			function onTriggerUp( event ) {
+			function onSelectEnd( event ) {
 
 				var controller = event.target;
 
@@ -299,9 +277,6 @@
 
 			function render() {
 
-				controller1.update();
-				controller2.update();
-
 				cleanIntersected();
 
 				intersectObjects( controller1 );

+ 10 - 13
examples/webvr_lorenzattractor.html

@@ -25,7 +25,12 @@
 
 		<script>
 
-			var camera, scene, renderer, x, y, z, c;
+			var camera, scene, renderer;
+			var attractor, light;
+
+			var x = 15 * Math.random();
+			var y = 15 * Math.random();
+			var z = 15 * Math.random();
 
 			var scale = .02; // for reducing overall displayed size
 			var speed = 5; // integer, increase for faster visualization
@@ -62,8 +67,9 @@
 
 					geometry.attributes.position.set( [ scale * x, scale * y, scale * z ], 0 );
 
-					c.setHSL( current / steps, 1, .5 );
-					geometry.attributes.color.set( [ c.r, c.g, c.b ], 0 );
+					light.color.setHSL( current / steps, 1, .5 );
+
+					geometry.attributes.color.set( light.color.toArray(), 0 );
 
 				}
 
@@ -87,12 +93,6 @@
 
 				//
 
-				x = 15 * Math.random();
-				y = 15 * Math.random();
-				z = 15 * Math.random();
-
-				c = new THREE.Color();
-
 				var geometry = new THREE.BufferGeometry();
 
 				var positions = new Float32Array( 3 * shown );
@@ -124,13 +124,10 @@
 
 				//
 
-				var light = new THREE.PointLight( 0xffffff, 1 );
-				light.color = c;
+				light = new THREE.PointLight( 0xffffff, 1 );
 				light.distance = 2;
 				attractor.add( light );
 
-				// scene.add( new THREE.PointLightHelper( light ))
-
 				var ground = new THREE.Mesh(
 					new THREE.PlaneBufferGeometry( 10, 10 ),
 					new THREE.MeshPhongMaterial()

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "three",
-  "version": "0.93.0",
+  "version": "0.94.0",
   "description": "JavaScript 3D library",
   "main": "build/three.js",
   "repository": "mrdoob/three.js",

+ 1 - 1
src/constants.js

@@ -1,4 +1,4 @@
-export var REVISION = '94dev';
+export var REVISION = '95dev';
 export var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };
 export var CullFaceNone = 0;
 export var CullFaceBack = 1;

+ 2 - 1
src/math/Frustum.js

@@ -150,7 +150,8 @@ Object.assign( Frustum.prototype, {
 
 				var plane = planes[ i ];
 
-				//corner at max distance
+				// corner at max distance
+
 				p.x = plane.normal.x > 0 ? box.max.x : box.min.x;
 				p.y = plane.normal.y > 0 ? box.max.y : box.min.y;
 				p.z = plane.normal.z > 0 ? box.max.z : box.min.z;

+ 69 - 6
src/objects/Sprite.js

@@ -1,5 +1,6 @@
 import { Vector2 } from '../math/Vector2.js';
 import { Vector3 } from '../math/Vector3.js';
+import { Matrix4 } from '../math/Matrix4.js';
 import { Object3D } from '../core/Object3D.js';
 import { SpriteMaterial } from '../materials/SpriteMaterial.js';
 
@@ -29,18 +30,80 @@ Sprite.prototype = Object.assign( Object.create( Object3D.prototype ), {
 	raycast: ( function () {
 
 		var intersectPoint = new Vector3();
-		var worldPosition = new Vector3();
 		var worldScale = new Vector3();
+		var mvPosition = new Vector3();
 
-		return function raycast( raycaster, intersects ) {
+		var alignedPosition = new Vector2();
+		var rotatedPosition = new Vector2();
+		var viewWorldMatrix = new Matrix4();
+
+		var vA = new Vector3();
+		var vB = new Vector3();
+		var vC = new Vector3();
+
+		function transformVertex( vertexPosition, mvPosition, center, scale, sin, cos ) {
+
+			// compute position in camera space
+			alignedPosition.subVectors( vertexPosition, center ).addScalar( 0.5 ).multiply( scale );
+
+			// to check if rotation is not zero
+			if ( sin !== undefined ) {
+
+				rotatedPosition.x = ( cos * alignedPosition.x ) - ( sin * alignedPosition.y );
+				rotatedPosition.y = ( sin * alignedPosition.x ) + ( cos * alignedPosition.y );
+
+			} else {
+
+				rotatedPosition.copy( alignedPosition );
+
+			}
+
+
+			vertexPosition.copy( mvPosition );
+			vertexPosition.x += rotatedPosition.x;
+			vertexPosition.y += rotatedPosition.y;
+
+			// transform to world space
+			vertexPosition.applyMatrix4( viewWorldMatrix );
 
-			worldPosition.setFromMatrixPosition( this.matrixWorld );
-			raycaster.ray.closestPointToPoint( worldPosition, intersectPoint );
+		}
+
+		return function raycast( raycaster, intersects ) {
 
 			worldScale.setFromMatrixScale( this.matrixWorld );
-			var guessSizeSq = worldScale.x * worldScale.y / 4;
+			viewWorldMatrix.getInverse( this.modelViewMatrix ).premultiply( this.matrixWorld );
+			mvPosition.setFromMatrixPosition( this.modelViewMatrix );
+
+			var rotation = this.material.rotation;
+			var sin, cos;
+			if ( rotation !== 0 ) {
+
+				cos = Math.cos( rotation );
+				sin = Math.sin( rotation );
+
+			}
+
+			var center = this.center;
+
+			transformVertex( vA.set( - 0.5, - 0.5, 0 ), mvPosition, center, worldScale, sin, cos );
+			transformVertex( vB.set( 0.5, - 0.5, 0 ), mvPosition, center, worldScale, sin, cos );
+			transformVertex( vC.set( 0.5, 0.5, 0 ), mvPosition, center, worldScale, sin, cos );
+
+			// check first triangle
+			var intersect = raycaster.ray.intersectTriangle( vA, vB, vC, false, intersectPoint );
+
+			if ( intersect === null ) {
+
+				// check second triangle
+				transformVertex( vB.set( - 0.5, 0.5, 0 ), mvPosition, center, worldScale, sin, cos );
+				intersect = raycaster.ray.intersectTriangle( vA, vC, vB, false, intersectPoint );
+				if ( intersect === null ) {
+
+					return;
+
+				}
 
-			if ( worldPosition.distanceToSquared( intersectPoint ) > guessSizeSq ) return;
+			}
 
 			var distance = raycaster.ray.origin.distanceTo( intersectPoint );
 

Some files were not shown because too many files changed in this diff