提交 d7636259 编写于 作者: M Mr.doob

Refactored interaction code.

上级 08a651b2
import * as THREE from '../../build/three.module.js';
import { HTMLMesh } from './libs/three.html.js';
import { InteractiveGroup } from '../../examples/jsm/interactive/InteractiveGroup.js';
import { HTMLMesh } from '../../examples/jsm/interactive/HTMLMesh.js';
import { XRControllerModelFactory } from '../../examples/jsm/webxr/XRControllerModelFactory.js';
......@@ -29,7 +30,7 @@ class VR {
if ( group === null ) {
group = new THREE.Group();
group = new InteractiveGroup( renderer );
editor.sceneHelpers.add( group );
const mesh = new HTMLMesh( sidebar );
......@@ -41,19 +42,16 @@ class VR {
// controllers
const controller1 = renderer.xr.getController( 0 );
controller1.addEventListener( 'select', onSelect );
group.add( controller1 );
const controller2 = renderer.xr.getController( 1 );
controller2.addEventListener( 'select', onSelect );
group.add( controller2 );
const geometry = new THREE.BufferGeometry();
geometry.setFromPoints( [ new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 0, 0, - 5 ) ] );
const controller1 = renderer.xr.getController( 0 );
controller1.add( new THREE.Line( geometry ) );
group.add( controller1 );
const controller2 = renderer.xr.getController( 1 );
controller2.add( new THREE.Line( geometry ) );
group.add( controller2 );
//
......@@ -101,41 +99,6 @@ 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.dispatchEvent( '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( () => {
......
......@@ -57,6 +57,9 @@ const assets = [
'../examples/jsm/curves/NURBSCurve.js',
'../examples/jsm/curves/NURBSUtils.js',
'../examples/jsm/interactive/HTMLMesh.js',
'../examples/jsm/interactive/InteractiveGroup.js',
'../examples/jsm/environments/RoomEnvironment.js',
'../examples/jsm/exporters/ColladaExporter.js',
......@@ -108,7 +111,6 @@ const assets = [
'./js/libs/tern-threejs/threejs.js',
'./js/libs/signals.min.js',
'./js/libs/three.html.js',
'./js/libs/ui.js',
'./js/libs/ui.three.js',
......
import * as THREE from '../../../build/three.module.js';
import {
CanvasTexture,
LinearFilter,
Mesh,
MeshBasicMaterial,
PlaneGeometry,
sRGBEncoding
} from '../../../build/three.module.js';
class HTMLMesh extends THREE.Mesh {
class HTMLMesh extends Mesh {
constructor( dom ) {
const texture = new HTMLTexture( dom );
const geometry = new THREE.PlaneGeometry( texture.image.width * 0.002, texture.image.height * 0.002 );
const material = new THREE.MeshBasicMaterial( { map: texture, toneMapped: false } );
const geometry = new PlaneGeometry( texture.image.width * 0.002, texture.image.height * 0.002 );
const material = new MeshBasicMaterial( { map: texture, toneMapped: false } );
super( geometry, material );
function onEvent( event ) {
console.log( event.type );
material.map.dispatchEvent( event );
}
this.addEventListener( 'mousedown', onEvent );
this.addEventListener( 'mousemove', onEvent );
this.addEventListener( 'mouseup', onEvent );
this.addEventListener( 'click', onEvent );
}
}
class HTMLTexture extends THREE.CanvasTexture {
class HTMLTexture extends CanvasTexture {
constructor( dom ) {
......@@ -24,15 +44,15 @@ class HTMLTexture extends THREE.CanvasTexture {
this.dom = dom;
this.anisotropy = 16;
this.encoding = THREE.sRGBEncoding;
this.minFilter = THREE.LinearFilter;
this.magFilter = THREE.LinearFilter;
this.encoding = sRGBEncoding;
this.minFilter = LinearFilter;
this.magFilter = LinearFilter;
}
dispatchEvent( event, x, y ) {
dispatchEvent( event ) {
htmlevent( this.dom, event, x, y );
htmlevent( this.dom, event.type, event.data.x, event.data.y );
this.update();
......@@ -288,4 +308,4 @@ function htmlevent( element, event, x, y ) {
}
export { HTMLMesh, HTMLTexture };
export { HTMLMesh };
import {
Group,
Matrix4,
Raycaster,
Vector2
} from '../../../build/three.module.js';
const _event = { type: '', data: new Vector2() };
class InteractiveGroup extends Group {
constructor( renderer ) {
super();
const scope = this;
const raycaster = new Raycaster();
const tempMatrix = new Matrix4();
// TODO PointerEvents
const events = {
'move': 'mousemove',
'select': 'click',
'selectstart': 'mousedown',
'selectend': 'mouseup'
};
function onXRControllerEvent( event ) {
const controller = event.target;
tempMatrix.identity().extractRotation( controller.matrixWorld );
raycaster.ray.origin.setFromMatrixPosition( controller.matrixWorld );
raycaster.ray.direction.set( 0, 0, - 1 ).applyMatrix4( tempMatrix );
const intersections = raycaster.intersectObjects( scope.children );
if ( intersections.length > 0 ) {
const intersection = intersections[ 0 ];
const object = intersection.object;
const uv = intersection.uv;
_event.type = events[ event.type ];
_event.data.set( uv.x, 1 - uv.y );
object.dispatchEvent( _event );
}
}
const controller1 = renderer.xr.getController( 0 );
controller1.addEventListener( 'move', onXRControllerEvent );
controller1.addEventListener( 'select', onXRControllerEvent );
controller1.addEventListener( 'selectstart', onXRControllerEvent );
controller1.addEventListener( 'selectend', onXRControllerEvent );
const controller2 = renderer.xr.getController( 1 );
controller2.addEventListener( 'move', onXRControllerEvent );
controller2.addEventListener( 'select', onXRControllerEvent );
controller2.addEventListener( 'selectstart', onXRControllerEvent );
controller2.addEventListener( 'selectend', onXRControllerEvent );
}
}
export { InteractiveGroup };
import {
Matrix4,
Raycaster
} from '../../../build/three.module.js';
class InteractionManager {
constructor( objects ) {
this._objects = objects;
this._raycaster = new Raycaster();
this._tempMatrix = new Matrix4();
}
listenPointerEvents() {
// TODO
}
listenXRControllerEvents( controller ) {
const scope = this;
const events = {
'move': 'mousemove',
'select': 'click',
'selectstart': 'mousedown',
'selectend': 'mouseup'
};
function onEvent( event ) {
const controller = event.target;
scope._tempMatrix.identity().extractRotation( controller.matrixWorld );
scope._raycaster.ray.origin.setFromMatrixPosition( controller.matrixWorld );
scope._raycaster.ray.direction.set( 0, 0, - 1 ).applyMatrix4( scope._tempMatrix );
const intersections = scope._raycaster.intersectObjects( scope._objects );
if ( intersections.length > 0 ) {
const intersection = intersections[ 0 ];
const object = intersection.object;
const uv = intersection.uv;
object.material.map.dispatchEvent( events[ event.type ], uv.x, 1 - uv.y );
}
}
controller.addEventListener( 'move', onEvent );
controller.addEventListener( 'select', onEvent );
controller.addEventListener( 'selectstart', onEvent );
controller.addEventListener( 'selectend', onEvent );
}
}
export { InteractionManager };
......@@ -15,8 +15,8 @@
import { Reflector } from './jsm/objects/Reflector.js';
import { VRButton } from './jsm/webxr/VRButton.js';
import { HTMLMesh } from '../editor/js/libs/three.html.js';
import { InteractionManager } from './jsm/webxr/InteractionManager.js';
import { HTMLMesh } from './jsm/interactive/HTMLMesh.js';
import { InteractiveGroup } from './jsm/interactive/InteractiveGroup.js';
import { XRControllerModelFactory } from './jsm/webxr/XRControllerModelFactory.js';
import { GUI } from './jsm/libs/dat.gui.module.js';
......@@ -181,20 +181,19 @@
gui.add( parameters, 'p', 0, 10, 1 ).onChange( onChange );
gui.add( parameters, 'q', 0, 10, 1 ).onChange( onChange );
const group = new InteractiveGroup( renderer );
scene.add( group );
const mesh = new HTMLMesh( gui.domElement );
mesh.position.x = - 1;
mesh.position.y = 1;
mesh.position.z = - 1;
mesh.visible = false;
scene.add( mesh );
group.add( mesh );
renderer.xr.addEventListener( 'sessionstart', () => { mesh.visible = true; } );
renderer.xr.addEventListener( 'sessionend', () => { mesh.visible = false; } );
const interaction = new InteractionManager( [ mesh ] );
interaction.listenXRControllerEvents( controller1 );
interaction.listenXRControllerEvents( controller2 );
}
function onWindowResize() {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册