2
0
Эх сурвалжийг харах

Merge pull request #21351 from mrdoob/editor

Editor: Implemented clicking HTML from inside VR
Mr.doob 4 жил өмнө
parent
commit
672e9de378

+ 65 - 2
editor/js/Viewport.VR.js

@@ -11,8 +11,12 @@ class VR {
 		const signals = editor.signals;
 
 		let group = null;
+
+		let camera = null;
 		let renderer = null;
 
+		const intersectables = [];
+
 		this.currentSession = null;
 
 		const onSessionStarted = async ( session ) => {
@@ -27,6 +31,24 @@ class VR {
 				mesh.rotation.y = - 0.5;
 				group.add( mesh );
 
+				intersectables.push( mesh );
+
+				// controllers
+
+				const controller1 = renderer.xr.getController( 0 );
+				controller1.addEventListener( 'select', onSelect );
+				group.add( controller1 );
+
+				const controller2 = renderer.xr.getController( 1 );
+				controller2.addEventListener( 'selectstart', onSelect );
+				group.add( controller2 );
+
+				const geometry = new THREE.BufferGeometry();
+				geometry.setFromPoints( [ new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 0, 0, - 5 ) ] );
+
+				controller1.add( new THREE.Line( geometry ) );
+				controller2.add( new THREE.Line( geometry ) );
+
 				//
 
 				const controllerModelFactory = new XRControllerModelFactory();
@@ -41,6 +63,8 @@ class VR {
 
 			}
 
+			camera = editor.camera.clone();
+
 			group.visible = true;
 
 			this.currentSession = session;
@@ -48,9 +72,11 @@ class VR {
 
 			await renderer.xr.setSession( this.currentSession );
 
-		}
+		};
+
+		const onSessionEnded = async () => {
 
-		 const onSessionEnded = async () => {
+			editor.camera.copy( camera );
 
 			group.visible = false;
 
@@ -63,6 +89,43 @@ class VR {
 
 		};
 
+		//
+
+		function onSelect( event ) {
+
+			const controller = event.target;
+
+			const intersections = getIntersections( controller );
+
+			if ( intersections.length > 0 ) {
+
+				const intersection = intersections[ 0 ];
+
+				const object = intersection.object;
+				const uv = intersection.uv;
+
+				object.material.map.click( uv.x, 1 - uv.y );
+
+			}
+
+		}
+
+		const raycaster = new THREE.Raycaster();
+		const tempMatrix = new THREE.Matrix4();
+
+		function getIntersections( controller ) {
+
+			tempMatrix.identity().extractRotation( controller.matrixWorld );
+
+			raycaster.ray.origin.setFromMatrixPosition( controller.matrixWorld );
+			raycaster.ray.direction.set( 0, 0, - 1 ).applyMatrix4( tempMatrix );
+
+			return raycaster.intersectObjects( intersectables );
+
+		}
+
+		// signals
+
 		signals.toggleVR.add( () => {
 
 			if ( this.currentSession === null ) {

+ 50 - 0
editor/js/libs/three.html.js

@@ -33,6 +33,14 @@ class HTMLTexture extends CanvasTexture {
 
 	}
 
+	click( x, y ) {
+
+		htmlclick( this.dom, x, y );
+
+		this.update();
+
+	}
+
 	update() {
 
 		this.image = html2canvas( this.dom );
@@ -234,4 +242,46 @@ function html2canvas( element ) {
 
 }
 
+function htmlclick( element, x, y ) {
+
+	/*
+	const mouseEventInit = {
+		clientX: ( x * element.offsetWidth ) + element.offsetLeft,
+		clientY: ( y * element.offsetHeight ) + element.offsetTop,
+		view: element.ownerDocument.defaultView
+	};
+	element.dispatchEvent( new MouseEvent( 'click', mouseEventInit ) );
+	*/
+
+	const rect = element.getBoundingClientRect();
+
+	x = x * rect.width + rect.left;
+	y = y * rect.height + rect.top;
+
+	function traverse( element ) {
+
+		if ( element.nodeType !== 3 ) {
+
+			const rect = element.getBoundingClientRect();
+
+			if ( x > rect.left && x < rect.right && y > rect.top && y < rect.bottom ) {
+
+				element.click();
+
+			}
+
+			for ( var i = 0; i < element.childNodes.length; i ++ ) {
+
+				traverse( element.childNodes[ i ] );
+
+			}
+
+		}
+
+	}
+
+	traverse( element );
+
+}
+
 export { HTMLMesh, HTMLTexture };