Просмотр исходного кода

JSM: Added module and TS files for VR controller.

Mugen87 6 лет назад
Родитель
Сommit
5a2653bc93

+ 12 - 0
docs/manual/en/introduction/Import-via-modules.html

@@ -374,6 +374,18 @@
 						<li>UVsDebug</li>
 					</ul>
 				</li>
+				<li>vr
+					<ul>
+						<li>deprecated
+							<ul>
+								<li>DaydreamController</li>
+								<li>GearVRController</li>
+							</ul>
+						</li>
+						<li>PaintViveController</li>
+						<li>ViveController</li>
+					</ul>
+				</li>
 			</ul>
 		</p>
 		<p>

+ 1 - 1
examples/js/vr/ViveController.js

@@ -72,7 +72,7 @@ THREE.ViveController = function ( id ) {
 			if ( pose.position !== null ) scope.position.fromArray( pose.position );
 			if ( pose.orientation !== null ) scope.quaternion.fromArray( pose.orientation );
 			scope.matrix.compose( scope.position, scope.quaternion, scope.scale );
-			scope.matrix.premultiply( scope.standingMatrix );	
+			scope.matrix.premultiply( scope.standingMatrix );
 			scope.matrixWorldNeedsUpdate = true;
 			scope.visible = true;
 

+ 1 - 1
examples/js/vr/deprecated/GearVRController.js

@@ -101,7 +101,7 @@ THREE.GearVRController = function () {
 
 			}
 
-		// app button not available, reserved for use by the browser
+			// app button not available, reserved for use by the browser
 
 		} else {
 

+ 12 - 0
examples/jsm/vr/PaintViveController.d.ts

@@ -0,0 +1,12 @@
+import {
+  Color
+} from '../../../src/Three';
+
+import { ViveController } from './ViveController';
+
+export class PaintViveController extends ViveController {
+  constructor(id: number);
+
+  getColor(): Color;
+  getSize(): number;
+}

+ 200 - 0
examples/jsm/vr/PaintViveController.js

@@ -0,0 +1,200 @@
+/**
+ * @author mrdoob / http://mrdoob.com
+ */
+
+import {
+	CanvasTexture,
+	CircleBufferGeometry,
+	Color,
+	DoubleSide,
+	Group,
+	IcosahedronBufferGeometry,
+	Mesh,
+	MeshBasicMaterial,
+	Shape,
+	ShapeBufferGeometry
+} from "../../../build/three.module.js";
+import { ViveController } from "../vr/ViveController.js";
+
+var PaintViveController = function ( id ) {
+
+	ViveController.call( this, id );
+
+	var PI2 = Math.PI * 2;
+
+	var MODES = { COLOR: 0, SIZE: 1 };
+	var mode = MODES.COLOR;
+
+	var color = new Color( 1, 1, 1 );
+	var size = 1.0;
+
+	//
+
+	function generateHueTexture() {
+
+		var canvas = document.createElement( 'canvas' );
+		canvas.width = 256;
+		canvas.height = 256;
+
+		var context = canvas.getContext( '2d' );
+		var imageData = context.getImageData( 0, 0, 256, 256 );
+		var data = imageData.data;
+		var swatchColor = new Color();
+
+		for ( var i = 0, j = 0; i < data.length; i += 4, j ++ ) {
+
+			var x = ( ( j % 256 ) / 256 ) - 0.5;
+			var y = ( Math.floor( j / 256 ) / 256 ) - 0.5;
+
+			swatchColor.setHSL( Math.atan2( y, x ) / PI2, 1, ( 0.5 - Math.sqrt( x * x + y * y ) ) * 2.0 );
+
+			data[ i + 0 ] = swatchColor.r * 256;
+			data[ i + 1 ] = swatchColor.g * 256;
+			data[ i + 2 ] = swatchColor.b * 256;
+			data[ i + 3 ] = 256;
+
+		}
+
+		context.putImageData( imageData, 0, 0 );
+
+		return new CanvasTexture( canvas );
+
+	}
+
+	// COLOR UI
+
+	var geometry = new CircleBufferGeometry( 1, 32 );
+	var material = new MeshBasicMaterial( { map: generateHueTexture() } );
+	var colorUI = new Mesh( geometry, material );
+	colorUI.position.set( 0, 0.005, 0.0495 );
+	colorUI.rotation.x = - 1.45;
+	colorUI.scale.setScalar( 0.02 );
+	this.add( colorUI );
+
+	var geometry = new IcosahedronBufferGeometry( 0.1, 2 );
+	var material = new MeshBasicMaterial();
+	material.color = color;
+	var ball = new Mesh( geometry, material );
+	colorUI.add( ball );
+
+
+	// SIZE UI
+	var sizeUI = new Group();
+	sizeUI.position.set( 0, 0.005, 0.0495 );
+	sizeUI.rotation.x = - 1.45;
+	sizeUI.scale.setScalar( 0.02 );
+	this.add( sizeUI );
+
+	var triangleShape = new Shape();
+	triangleShape.moveTo( 0, - 1 );
+	triangleShape.lineTo( 1, 1 );
+	triangleShape.lineTo( - 1, 1 );
+
+	var geometry = new ShapeBufferGeometry( triangleShape );
+	var material = new MeshBasicMaterial( { color: 0x222222, wireframe: true } );
+	var sizeUIOutline = new Mesh( geometry, material );
+	sizeUIOutline.position.z = 0.001;
+	resizeTriangleGeometry( sizeUIOutline.geometry, 1.0 );
+	sizeUI.add( sizeUIOutline );
+
+	var geometry = new ShapeBufferGeometry( triangleShape );
+	var material = new MeshBasicMaterial( { side: DoubleSide } );
+	material.color = color;
+	var sizeUIFill = new Mesh( geometry, material );
+	sizeUIFill.position.z = 0.0011;
+	resizeTriangleGeometry( sizeUIFill.geometry, 0.5 );
+	sizeUI.add( sizeUIFill );
+
+	sizeUI.visible = false;
+
+
+
+	function onAxisChanged( event ) {
+
+		if ( this.getButtonState( 'thumbpad' ) === false ) return;
+
+		var x = event.axes[ 0 ] / 2.0;
+		var y = - event.axes[ 1 ] / 2.0;
+
+		if ( mode === MODES.COLOR ) {
+
+			color.setHSL( Math.atan2( y, x ) / PI2, 1, ( 0.5 - Math.sqrt( x * x + y * y ) ) * 2.0 );
+
+			ball.position.set( event.axes[ 0 ], event.axes[ 1 ], 0 );
+
+		}
+
+		if ( mode === MODES.SIZE ) {
+
+			var ratio = 0.5 - y;
+			size = ratio * 2;
+
+			resizeTriangleGeometry( sizeUIFill.geometry, ratio );
+
+		}
+
+	}
+
+	function resizeTriangleGeometry( geometry, ratio ) {
+
+		var x = 0, y = 0;
+		var fullWidth = 0.75, fullHeight = 1.5;
+		var angle = Math.atan( ( fullWidth / 2 ) / fullHeight );
+
+		var bottomY = y - fullHeight / 2;
+		var height = fullHeight * ratio;
+		var width = ( Math.tan( angle ) * height ) * 2;
+
+		var position = geometry.attributes.position;
+
+		position.setXYZ( 0, x, bottomY, 0 );
+		position.setXYZ( 1, x + width / 2, bottomY + height, 0 );
+		position.setXYZ( 2, x - width / 2, bottomY + height, 0 );
+
+		position.needsUpdate = true;
+
+	}
+
+	function onGripsDown() {
+
+		if ( mode === MODES.COLOR ) {
+
+			mode = MODES.SIZE;
+			colorUI.visible = false;
+			sizeUI.visible = true;
+			return;
+
+		}
+
+		if ( mode === MODES.SIZE ) {
+
+			mode = MODES.COLOR;
+			colorUI.visible = true;
+			sizeUI.visible = false;
+			return;
+
+		}
+
+	}
+
+	this.getColor = function () {
+
+		return color;
+
+	};
+
+	this.getSize = function () {
+
+		return size;
+
+	 };
+
+	this.addEventListener( 'axischanged', onAxisChanged );
+	this.addEventListener( 'gripsdown', onGripsDown );
+
+};
+
+PaintViveController.prototype = Object.create( ViveController.prototype );
+PaintViveController.prototype.constructor = PaintViveController;
+
+export { PaintViveController };

+ 13 - 0
examples/jsm/vr/ViveController.d.ts

@@ -0,0 +1,13 @@
+import {
+  Matrix4,
+  Object3D
+} from '../../../src/Three';
+
+export class ViveController extends Object3D {
+  constructor(id: number);
+  standingMatrix: Matrix4;
+
+  getButtonState(button: string): boolean;
+  getGamepad(): object;
+  update(): void;
+}

+ 135 - 0
examples/jsm/vr/ViveController.js

@@ -0,0 +1,135 @@
+/**
+ * @author mrdoob / http://mrdoob.com
+ * @author stewdio / http://stewd.io
+ */
+
+import {
+	Matrix4,
+	Object3D
+} from "../../../build/three.module.js";
+
+var ViveController = function ( id ) {
+
+	Object3D.call( this );
+
+	var scope = this;
+	var gamepad;
+
+	var axes = [ 0, 0 ];
+	var thumbpadIsPressed = false;
+	var triggerIsPressed = false;
+	var gripsArePressed = false;
+	var menuIsPressed = false;
+
+	function findGamepad( id ) {
+
+		// Iterate across gamepads as Vive Controllers may not be
+		// in position 0 and 1.
+
+		var gamepads = navigator.getGamepads && navigator.getGamepads();
+
+		for ( var i = 0, j = 0; i < gamepads.length; i ++ ) {
+
+			var gamepad = gamepads[ i ];
+
+			if ( gamepad && ( gamepad.id === 'OpenVR Gamepad' || gamepad.id.startsWith( 'Oculus Touch' ) || gamepad.id.startsWith( 'Spatial Controller' ) ) ) {
+
+				if ( j === id ) return gamepad;
+
+				j ++;
+
+			}
+
+		}
+
+	}
+
+	this.matrixAutoUpdate = false;
+	this.standingMatrix = new Matrix4();
+
+	this.getGamepad = function () {
+
+		return gamepad;
+
+	};
+
+	this.getButtonState = function ( button ) {
+
+		if ( button === 'thumbpad' ) return thumbpadIsPressed;
+		if ( button === 'trigger' ) return triggerIsPressed;
+		if ( button === 'grips' ) return gripsArePressed;
+		if ( button === 'menu' ) return menuIsPressed;
+
+	};
+
+	this.update = function () {
+
+		gamepad = findGamepad( id );
+
+		if ( gamepad !== undefined && gamepad.pose !== undefined ) {
+
+			if ( gamepad.pose === null ) return; // No user action yet
+
+			//  Position and orientation.
+
+			var pose = gamepad.pose;
+
+			if ( pose.position !== null ) scope.position.fromArray( pose.position );
+			if ( pose.orientation !== null ) scope.quaternion.fromArray( pose.orientation );
+			scope.matrix.compose( scope.position, scope.quaternion, scope.scale );
+			scope.matrix.premultiply( scope.standingMatrix );
+			scope.matrixWorldNeedsUpdate = true;
+			scope.visible = true;
+
+			//  Thumbpad and Buttons.
+
+			if ( axes[ 0 ] !== gamepad.axes[ 0 ] || axes[ 1 ] !== gamepad.axes[ 1 ] ) {
+
+				axes[ 0 ] = gamepad.axes[ 0 ]; //  X axis: -1 = Left, +1 = Right.
+				axes[ 1 ] = gamepad.axes[ 1 ]; //  Y axis: -1 = Bottom, +1 = Top.
+				scope.dispatchEvent( { type: 'axischanged', axes: axes } );
+
+			}
+
+			if ( thumbpadIsPressed !== gamepad.buttons[ 0 ].pressed ) {
+
+				thumbpadIsPressed = gamepad.buttons[ 0 ].pressed;
+				scope.dispatchEvent( { type: thumbpadIsPressed ? 'thumbpaddown' : 'thumbpadup', axes: axes } );
+
+			}
+
+			if ( triggerIsPressed !== gamepad.buttons[ 1 ].pressed ) {
+
+				triggerIsPressed = gamepad.buttons[ 1 ].pressed;
+				scope.dispatchEvent( { type: triggerIsPressed ? 'triggerdown' : 'triggerup' } );
+
+			}
+
+			if ( gripsArePressed !== gamepad.buttons[ 2 ].pressed ) {
+
+				gripsArePressed = gamepad.buttons[ 2 ].pressed;
+				scope.dispatchEvent( { type: gripsArePressed ? 'gripsdown' : 'gripsup' } );
+
+			}
+
+			if ( menuIsPressed !== gamepad.buttons[ 3 ].pressed ) {
+
+				menuIsPressed = gamepad.buttons[ 3 ].pressed;
+				scope.dispatchEvent( { type: menuIsPressed ? 'menudown' : 'menuup' } );
+
+			}
+
+		} else {
+
+			scope.visible = false;
+
+		}
+
+	};
+
+};
+
+ViveController.prototype = Object.create( Object3D.prototype );
+ViveController.prototype.constructor = ViveController;
+
+export { ViveController };

+ 11 - 0
examples/jsm/vr/deprecated/DaydreamController.d.ts

@@ -0,0 +1,11 @@
+import {
+  Object3D
+} from '../../../../src/Three';
+
+export class DaydreamController extends Object3D {
+  constructor(id: number);
+
+	getTouchpadState(): boolean;
+  getGamepad(): object;
+  update(): void;
+}

+ 125 - 0
examples/jsm/vr/deprecated/DaydreamController.js

@@ -0,0 +1,125 @@
+/**
+ * @author Mugen87 / https://github.com/Mugen87
+ */
+
+import {
+	Object3D,
+	Vector3
+} from "../../../../build/three.module.js";
+
+var DaydreamController = function () {
+
+	Object3D.call( this );
+
+	var scope = this;
+	var gamepad;
+
+	var axes = [ 0, 0 ];
+	var touchpadIsPressed = false;
+	var angularVelocity = new Vector3();
+
+	this.matrixAutoUpdate = false;
+
+	function findGamepad() {
+
+		// iterate across gamepads as the Daydream Controller may not be
+		// in position 0
+
+		var gamepads = navigator.getGamepads && navigator.getGamepads();
+
+		for ( var i = 0; i < 4; i ++ ) {
+
+			var gamepad = gamepads[ i ];
+
+			if ( gamepad && ( gamepad.id === 'Daydream Controller' ) ) {
+
+				return gamepad;
+
+			}
+
+		}
+
+	}
+
+	this.getGamepad = function () {
+
+		return gamepad;
+
+	};
+
+	this.getTouchpadState = function () {
+
+		return touchpadIsPressed;
+
+	};
+
+	this.update = function () {
+
+		gamepad = findGamepad();
+
+		if ( gamepad !== undefined && gamepad.pose !== undefined ) {
+
+			var pose = gamepad.pose;
+
+			if ( pose === null ) return; // no user action yet
+
+			//  orientation
+
+			if ( pose.orientation !== null ) scope.quaternion.fromArray( pose.orientation );
+
+			scope.updateMatrix();
+			scope.visible = true;
+
+			// angular velocity
+
+			if ( pose.angularVelocity !== null && ! angularVelocity.equals( pose.angularVelocity ) ) {
+
+				angularVelocity.fromArray( pose.angularVelocity );
+				scope.dispatchEvent( { type: 'angularvelocitychanged', angularVelocity: angularVelocity } );
+
+			}
+
+			// axes (touchpad)
+
+			if ( axes[ 0 ] !== gamepad.axes[ 0 ] || axes[ 1 ] !== gamepad.axes[ 1 ] ) {
+
+				axes[ 0 ] = gamepad.axes[ 0 ];
+				axes[ 1 ] = gamepad.axes[ 1 ];
+				scope.dispatchEvent( { type: 'axischanged', axes: axes } );
+
+			}
+
+			// button (touchpad)
+
+			if ( touchpadIsPressed !== gamepad.buttons[ 0 ].pressed ) {
+
+				touchpadIsPressed = gamepad.buttons[ 0 ].pressed;
+				scope.dispatchEvent( { type: touchpadIsPressed ? 'touchpaddown' : 'touchpadup' } );
+
+			}
+
+			// app button not available, reserved for use by the browser
+
+		} else {
+
+			scope.visible = false;
+
+		}
+
+	};
+
+	// DEPRECATED
+
+	this.getTouchPadState = function () {
+
+		console.warn( 'THREE.DaydreamController: getTouchPadState() is now getTouchpadState()' );
+		return touchpadIsPressed;
+
+	};
+
+};
+
+DaydreamController.prototype = Object.create( Object3D.prototype );
+DaydreamController.prototype.constructor = DaydreamController;
+
+export { DaydreamController };

+ 11 - 0
examples/jsm/vr/deprecated/GearVRController.d.ts

@@ -0,0 +1,11 @@
+import {
+  Object3D
+} from '../../../../src/Three';
+
+export class GearVRController extends Object3D {
+  constructor(id: number);
+
+	getTouchpadState(): boolean;
+  getGamepad(): object;
+  update(): void;
+}

+ 139 - 0
examples/jsm/vr/deprecated/GearVRController.js

@@ -0,0 +1,139 @@
+/**
+ * @author servinlp
+ */
+
+import {
+	Object3D,
+	Vector3
+} from "../../../../build/three.module.js";
+
+var GearVRController = function () {
+
+	Object3D.call( this );
+
+	var scope = this;
+	var gamepad;
+
+	var axes = [ 0, 0 ];
+	var touchpadIsPressed = false;
+	var triggerIsPressed = false;
+	var angularVelocity = new Vector3();
+
+	this.matrixAutoUpdate = true;
+
+	function findGamepad() {
+
+		var gamepads = navigator.getGamepads && navigator.getGamepads();
+
+		for ( var i = 0; i < 4; i ++ ) {
+
+			var gamepad = gamepads[ i ];
+
+			if ( gamepad && ( gamepad.id === 'Gear VR Controller' || gamepad.id === 'Oculus Go Controller' ) ) {
+
+				return gamepad;
+
+			}
+
+		}
+
+	}
+
+	this.getGamepad = function () {
+
+		return gamepad;
+
+	};
+
+	this.getTouchpadState = function () {
+
+		return touchpadIsPressed;
+
+	};
+
+	this.update = function () {
+
+		gamepad = findGamepad();
+
+		if ( gamepad !== undefined && gamepad.pose !== undefined ) {
+
+			var pose = gamepad.pose;
+
+			if ( pose === null ) return; // no user action yet
+
+			//  orientation
+
+			if ( pose.orientation !== null ) scope.quaternion.fromArray( pose.orientation );
+
+			scope.updateMatrix();
+			scope.visible = true;
+
+			// angular velocity
+
+			if ( pose.angularVelocity !== null && ! angularVelocity.equals( pose.angularVelocity ) ) {
+
+				angularVelocity.fromArray( pose.angularVelocity );
+				scope.dispatchEvent( { type: 'angularvelocitychanged', angularVelocity: angularVelocity } );
+
+			}
+
+			// axes (touchpad)
+
+			if ( axes[ 0 ] !== gamepad.axes[ 0 ] || axes[ 1 ] !== gamepad.axes[ 1 ] ) {
+
+				axes[ 0 ] = gamepad.axes[ 0 ];
+				axes[ 1 ] = gamepad.axes[ 1 ];
+				scope.dispatchEvent( { type: 'axischanged', axes: axes } );
+
+			}
+
+			// button (touchpad)
+
+			if ( touchpadIsPressed !== gamepad.buttons[ 0 ].pressed ) {
+
+				touchpadIsPressed = gamepad.buttons[ 0 ].pressed;
+				scope.dispatchEvent( { type: touchpadIsPressed ? 'touchpaddown' : 'touchpadup', axes: axes } );
+
+			}
+
+
+			// trigger
+
+			if ( triggerIsPressed !== gamepad.buttons[ 1 ].pressed ) {
+
+				triggerIsPressed = gamepad.buttons[ 1 ].pressed;
+				scope.dispatchEvent( { type: triggerIsPressed ? 'triggerdown' : 'triggerup' } );
+
+			}
+
+			// app button not available, reserved for use by the browser
+
+		} else {
+
+			scope.visible = false;
+
+		}
+
+	};
+
+	// DEPRECATED
+
+	this.getTouchPadState = function () {
+
+		console.warn( 'THREE.GearVRController: getTouchPadState() is now getTouchpadState()' );
+		return touchpadIsPressed;
+
+	};
+
+	this.setHand = function () {
+
+		console.warn( 'THREE.GearVRController: setHand() has been removed.' );
+
+	};
+
+};
+
+GearVRController.prototype = Object.create( Object3D.prototype );
+GearVRController.prototype.constructor = GearVRController;
+
+export { GearVRController };

+ 5 - 0
utils/modularize.js

@@ -247,6 +247,11 @@ var files = [
 	{ path: 'utils/SkeletonUtils.js', dependencies: [], ignoreList: [] },
 	{ path: 'utils/TypedArrayUtils.js', dependencies: [], ignoreList: [] },
 	{ path: 'utils/UVsDebug.js', dependencies: [], ignoreList: [ 'SphereBufferGeometry' ] },
+
+	{ path: 'vr/deprecated/DaydreamController.js', dependencies: [], ignoreList: [] },
+	{ path: 'vr/deprecated/GearVRController.js', dependencies: [], ignoreList: [] },
+	{ path: 'vr/PaintViveController.js', dependencies: [ { name: 'ViveController', path: 'vr/ViveController.js' } ], ignoreList: [] },
+	{ path: 'vr/ViveController.js', dependencies: [], ignoreList: [] },
 ];
 
 for ( var i = 0; i < files.length; i ++ ) {