Skip to content

Commit 672e9de

Browse files
authored
Merge pull request #21351 from mrdoob/editor
Editor: Implemented clicking HTML from inside VR
2 parents 9522135 + 77c2e00 commit 672e9de

File tree

2 files changed

+115
-2
lines changed

2 files changed

+115
-2
lines changed

editor/js/Viewport.VR.js

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,12 @@ class VR {
1111
const signals = editor.signals;
1212

1313
let group = null;
14+
15+
let camera = null;
1416
let renderer = null;
1517

18+
const intersectables = [];
19+
1620
this.currentSession = null;
1721

1822
const onSessionStarted = async ( session ) => {
@@ -27,6 +31,24 @@ class VR {
2731
mesh.rotation.y = - 0.5;
2832
group.add( mesh );
2933

34+
intersectables.push( mesh );
35+
36+
// controllers
37+
38+
const controller1 = renderer.xr.getController( 0 );
39+
controller1.addEventListener( 'select', onSelect );
40+
group.add( controller1 );
41+
42+
const controller2 = renderer.xr.getController( 1 );
43+
controller2.addEventListener( 'selectstart', onSelect );
44+
group.add( controller2 );
45+
46+
const geometry = new THREE.BufferGeometry();
47+
geometry.setFromPoints( [ new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 0, 0, - 5 ) ] );
48+
49+
controller1.add( new THREE.Line( geometry ) );
50+
controller2.add( new THREE.Line( geometry ) );
51+
3052
//
3153

3254
const controllerModelFactory = new XRControllerModelFactory();
@@ -41,16 +63,20 @@ class VR {
4163

4264
}
4365

66+
camera = editor.camera.clone();
67+
4468
group.visible = true;
4569

4670
this.currentSession = session;
4771
this.currentSession.addEventListener( 'end', onSessionEnded );
4872

4973
await renderer.xr.setSession( this.currentSession );
5074

51-
}
75+
};
76+
77+
const onSessionEnded = async () => {
5278

53-
const onSessionEnded = async () => {
79+
editor.camera.copy( camera );
5480

5581
group.visible = false;
5682

@@ -63,6 +89,43 @@ class VR {
6389

6490
};
6591

92+
//
93+
94+
function onSelect( event ) {
95+
96+
const controller = event.target;
97+
98+
const intersections = getIntersections( controller );
99+
100+
if ( intersections.length > 0 ) {
101+
102+
const intersection = intersections[ 0 ];
103+
104+
const object = intersection.object;
105+
const uv = intersection.uv;
106+
107+
object.material.map.click( uv.x, 1 - uv.y );
108+
109+
}
110+
111+
}
112+
113+
const raycaster = new THREE.Raycaster();
114+
const tempMatrix = new THREE.Matrix4();
115+
116+
function getIntersections( controller ) {
117+
118+
tempMatrix.identity().extractRotation( controller.matrixWorld );
119+
120+
raycaster.ray.origin.setFromMatrixPosition( controller.matrixWorld );
121+
raycaster.ray.direction.set( 0, 0, - 1 ).applyMatrix4( tempMatrix );
122+
123+
return raycaster.intersectObjects( intersectables );
124+
125+
}
126+
127+
// signals
128+
66129
signals.toggleVR.add( () => {
67130

68131
if ( this.currentSession === null ) {

editor/js/libs/three.html.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ class HTMLTexture extends CanvasTexture {
3333

3434
}
3535

36+
click( x, y ) {
37+
38+
htmlclick( this.dom, x, y );
39+
40+
this.update();
41+
42+
}
43+
3644
update() {
3745

3846
this.image = html2canvas( this.dom );
@@ -234,4 +242,46 @@ function html2canvas( element ) {
234242

235243
}
236244

245+
function htmlclick( element, x, y ) {
246+
247+
/*
248+
const mouseEventInit = {
249+
clientX: ( x * element.offsetWidth ) + element.offsetLeft,
250+
clientY: ( y * element.offsetHeight ) + element.offsetTop,
251+
view: element.ownerDocument.defaultView
252+
};
253+
element.dispatchEvent( new MouseEvent( 'click', mouseEventInit ) );
254+
*/
255+
256+
const rect = element.getBoundingClientRect();
257+
258+
x = x * rect.width + rect.left;
259+
y = y * rect.height + rect.top;
260+
261+
function traverse( element ) {
262+
263+
if ( element.nodeType !== 3 ) {
264+
265+
const rect = element.getBoundingClientRect();
266+
267+
if ( x > rect.left && x < rect.right && y > rect.top && y < rect.bottom ) {
268+
269+
element.click();
270+
271+
}
272+
273+
for ( var i = 0; i < element.childNodes.length; i ++ ) {
274+
275+
traverse( element.childNodes[ i ] );
276+
277+
}
278+
279+
}
280+
281+
}
282+
283+
traverse( element );
284+
285+
}
286+
237287
export { HTMLMesh, HTMLTexture };

0 commit comments

Comments
 (0)