XR controllers on scene
This commit is contained in:
@@ -48,7 +48,7 @@ class PairMatchingGame extends EventManager {
|
|||||||
uv[xi].array[8 * i + 7] = s[1];
|
uv[xi].array[8 * i + 7] = s[1];
|
||||||
}
|
}
|
||||||
let mesh = new Mesh(b[xi], material.clone());
|
let mesh = new Mesh(b[xi], material.clone());
|
||||||
mesh.position.set(xi * dx, o[xi][i] * dy, 0);
|
mesh.position.set(xi * dx + Math.random() * (xi+0.5) * dx, o[xi][i] * dy, Math.random() * (xi+0.5) * dx);
|
||||||
mesh.userData.gd = {
|
mesh.userData.gd = {
|
||||||
pair: xi,
|
pair: xi,
|
||||||
id: i
|
id: i
|
||||||
@@ -75,7 +75,7 @@ class PairMatchingGame extends EventManager {
|
|||||||
|
|
||||||
let actionDef = {material:{emissiveIntensity:k=>(1+Math.sin((k*2+1.5)*Math.PI))*4 }};
|
let actionDef = {material:{emissiveIntensity:k=>(1+Math.sin((k*2+1.5)*Math.PI))*4 }};
|
||||||
|
|
||||||
let clickFn = (i) => {
|
var clickFn = (i) => {
|
||||||
this.dispatchEvent({type:'interaction'});
|
this.dispatchEvent({type:'interaction'});
|
||||||
let oc = clicked;
|
let oc = clicked;
|
||||||
if (done.includes(i.object.userData.gd.id)) return;
|
if (done.includes(i.object.userData.gd.id)) return;
|
||||||
|
|||||||
+18
-13
@@ -1,7 +1,7 @@
|
|||||||
import { Raycaster, Vector3 } from "three"
|
import { Raycaster, Vector3 } from "three"
|
||||||
|
|
||||||
class Clickable {
|
class Clickable {
|
||||||
constructor(defaultDistance) {
|
constructor(engine, defaultDistance) {
|
||||||
const objects = [];
|
const objects = [];
|
||||||
const raycaster = new Raycaster();
|
const raycaster = new Raycaster();
|
||||||
let v = new Vector3;
|
let v = new Vector3;
|
||||||
@@ -21,34 +21,39 @@ class Clickable {
|
|||||||
objects.splice(0, objects.length);
|
objects.splice(0, objects.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.update = function (mouse, camera, event) {
|
this.handleController = function(controller){
|
||||||
raycaster.setFromCamera(mouse, camera);
|
raycaster.setFromXRController(controller);
|
||||||
|
this.handle();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.handleMouse = function (mouse, event) {
|
||||||
|
raycaster.setFromCamera(mouse, engine.camera);
|
||||||
|
this.handle();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.handle = function(){
|
||||||
let forExecute = [];
|
let forExecute = [];
|
||||||
objects.filter(o=>{
|
objects.filter(o=>{
|
||||||
do {
|
do {
|
||||||
if (o.__active === false) return false;
|
if (o.__active === false || o.visible === false) return false;
|
||||||
o = o.parent;
|
o = o.parent;
|
||||||
} while (o);
|
} while (o);
|
||||||
return true;
|
return true;
|
||||||
}).forEach(o => {
|
}).forEach(o => {
|
||||||
o.getWorldPosition(v);
|
o.getWorldPosition(v);
|
||||||
if (camera.position.distanceTo(v) <= o._clickable.distance && o.visible) {
|
if (engine.cameraWorld.position.distanceTo(v) <= o._clickable.distance) {
|
||||||
const intersects = raycaster.intersectObject(o);
|
const intersects = raycaster.intersectObject(o);
|
||||||
// intersects.forEach(i=>{
|
if (intersects[0]) {
|
||||||
// forExecute.push({o, i})
|
forExecute.push({ o, i: intersects[0] });
|
||||||
// })
|
}
|
||||||
if (intersects[0]) forExecute.push({ o, i: intersects[0] });
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (forExecute[0]) {
|
if (forExecute[0]) {
|
||||||
let sorted = forExecute.sort((a, b) => a.i.distance - b.i.distance);
|
let sorted = forExecute.sort((a, b) => a.i.distance - b.i.distance);
|
||||||
sorted[0].o._clickable.fn(sorted[0].i);
|
sorted[0].o._clickable.fn(sorted[0].i);
|
||||||
if (this.onclick) {
|
|
||||||
this.onclick(sorted[0].o, sorted[0].i, event);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export {Clickable}
|
export { Clickable }
|
||||||
@@ -29,7 +29,7 @@ class DashBoard extends EventManager {
|
|||||||
dash.visible = false;
|
dash.visible = false;
|
||||||
const k = 3.11;
|
const k = 3.11;
|
||||||
const dashWidth = engine.aspect * k, dashHeight = k;
|
const dashWidth = engine.aspect * k, dashHeight = k;
|
||||||
const dashDistance = 2.5;
|
const dashDistance = 1.77;
|
||||||
|
|
||||||
this.width = dashWidth;
|
this.width = dashWidth;
|
||||||
this.height = dashHeight;
|
this.height = dashHeight;
|
||||||
@@ -202,7 +202,7 @@ class DashBoard extends EventManager {
|
|||||||
//dashPlacement, rotate = false, plane = false
|
//dashPlacement, rotate = false, plane = false
|
||||||
this.attach = (object, opts = {})=>{
|
this.attach = (object, opts = {})=>{
|
||||||
this.cameraFix = engine.hero.cameraZ;
|
this.cameraFix = engine.hero.cameraZ;
|
||||||
engine.hero.cameraZ = 12;
|
engine.hero.cameraZ = 6;
|
||||||
hud.visible = true;
|
hud.visible = true;
|
||||||
hudPlane.visible = !!opts.plane;
|
hudPlane.visible = !!opts.plane;
|
||||||
if (opts.plane){
|
if (opts.plane){
|
||||||
|
|||||||
+16
-7
@@ -1,7 +1,7 @@
|
|||||||
import { Raycaster, Vector3 } from "three"
|
import { Raycaster, Vector3 } from "three"
|
||||||
|
|
||||||
class Draggable{
|
class Draggable{
|
||||||
constructor(defaultDistance){
|
constructor(engine, defaultDistance){
|
||||||
const objects = [];
|
const objects = [];
|
||||||
const raycaster = new Raycaster();
|
const raycaster = new Raycaster();
|
||||||
let v = new Vector3;
|
let v = new Vector3;
|
||||||
@@ -16,13 +16,22 @@ class Draggable{
|
|||||||
objects.splice(objects.indexOf(object), 1);
|
objects.splice(objects.indexOf(object), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.update = function(pointer, camera, action){
|
this.handleController = function(controller, action){
|
||||||
raycaster.setFromCamera(pointer, camera);
|
raycaster.setFromXRController(controller);
|
||||||
if (action == 'start'){
|
this.handle(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.handleMouse = function (mouse, action) {
|
||||||
|
raycaster.setFromCamera(mouse, engine.camera);
|
||||||
|
this.handle(action);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.handle = function(action){
|
||||||
|
if (['start', 'selectstart'].includes(action)){
|
||||||
let forExecute = [];
|
let forExecute = [];
|
||||||
objects.forEach(o=>{
|
objects.forEach(o=>{
|
||||||
o.getWorldPosition(v);
|
o.getWorldPosition(v);
|
||||||
if (camera.position.distanceTo(v) <= o._draggable.distance && o.visible){
|
if (engine.cameraWorld.position.distanceTo(v) <= o._draggable.distance && o.visible){
|
||||||
const intersects = raycaster.intersectObject(o);
|
const intersects = raycaster.intersectObject(o);
|
||||||
if (intersects[0]) forExecute.push({o, i:intersects[0]})
|
if (intersects[0]) forExecute.push({o, i:intersects[0]})
|
||||||
}
|
}
|
||||||
@@ -34,10 +43,10 @@ class Draggable{
|
|||||||
dragging = s;
|
dragging = s;
|
||||||
dragging.zone = raycaster.intersectObject(s.o._draggable.dragZone)[0];
|
dragging.zone = raycaster.intersectObject(s.o._draggable.dragZone)[0];
|
||||||
}
|
}
|
||||||
}else if (action == 'end' && dragging){
|
}else if (['end', 'selectend'].includes(action) && dragging){
|
||||||
dragging.o._draggable.fn.end && dragging.o._draggable.fn.end(dragging);
|
dragging.o._draggable.fn.end && dragging.o._draggable.fn.end(dragging);
|
||||||
dragging = null;
|
dragging = null;
|
||||||
}else if(action == 'drag' && dragging){
|
}else if(['drag', 'move'].includes(action) && dragging){
|
||||||
const intersect = raycaster.intersectObject(dragging.o._draggable.dragZone)[0];
|
const intersect = raycaster.intersectObject(dragging.o._draggable.dragZone)[0];
|
||||||
if (intersect?.uv && dragging.zone?.uv){
|
if (intersect?.uv && dragging.zone?.uv){
|
||||||
dragging.o.position.x += -4*(dragging.zone.uv.x - intersect.uv.x);
|
dragging.o.position.x += -4*(dragging.zone.uv.x - intersect.uv.x);
|
||||||
|
|||||||
+15
-16
@@ -245,8 +245,8 @@ class GameEngine extends EventManager{
|
|||||||
this.initXr();
|
this.initXr();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.clickable = new Clickable(20);
|
this.clickable = new Clickable(this, 20);
|
||||||
this.draggable = new Draggable(20);
|
this.draggable = new Draggable(this, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
initXr() {
|
initXr() {
|
||||||
@@ -261,7 +261,7 @@ class GameEngine extends EventManager{
|
|||||||
// this.session = this.renderer.xr.getSession();
|
// this.session = this.renderer.xr.getSession();
|
||||||
// this.session.addEventListener('selectstart', this.onControllerEvent.bind(this));
|
// this.session.addEventListener('selectstart', this.onControllerEvent.bind(this));
|
||||||
})
|
})
|
||||||
this.scene.add(c1);
|
this.cameraRig.add(c1);
|
||||||
|
|
||||||
let c2 = this.renderer.xr.getController(1);
|
let c2 = this.renderer.xr.getController(1);
|
||||||
c2.addEventListener('select', this.onSelect.bind(this));
|
c2.addEventListener('select', this.onSelect.bind(this));
|
||||||
@@ -272,17 +272,17 @@ class GameEngine extends EventManager{
|
|||||||
c2.addEventListener('connected', e => {
|
c2.addEventListener('connected', e => {
|
||||||
c2.gamepad = e.data.gamepad;
|
c2.gamepad = e.data.gamepad;
|
||||||
})
|
})
|
||||||
this.scene.add(c2);
|
this.cameraRig.add(c2);
|
||||||
|
|
||||||
const controllerModelFactory = new XRControllerModelFactory();
|
const controllerModelFactory = new XRControllerModelFactory();
|
||||||
|
|
||||||
let controllerGrip1 = this.renderer.xr.getControllerGrip(0);
|
let controllerGrip1 = this.renderer.xr.getControllerGrip(0);
|
||||||
controllerGrip1.add(controllerModelFactory.createControllerModel(controllerGrip1));
|
controllerGrip1.add(controllerModelFactory.createControllerModel(controllerGrip1));
|
||||||
this.scene.add(controllerGrip1);
|
this.cameraRig.add(controllerGrip1);
|
||||||
|
|
||||||
let controllerGrip2 = this.renderer.xr.getControllerGrip(1);
|
let controllerGrip2 = this.renderer.xr.getControllerGrip(1);
|
||||||
controllerGrip2.add(controllerModelFactory.createControllerModel(controllerGrip2));
|
controllerGrip2.add(controllerModelFactory.createControllerModel(controllerGrip2));
|
||||||
this.scene.add(controllerGrip2);
|
this.cameraRig.add(controllerGrip2);
|
||||||
|
|
||||||
const geometry = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 0, - 1)]);
|
const geometry = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 0, - 1)]);
|
||||||
|
|
||||||
@@ -379,14 +379,10 @@ class GameEngine extends EventManager{
|
|||||||
}
|
}
|
||||||
|
|
||||||
onControllerEvent(event) {
|
onControllerEvent(event) {
|
||||||
//this.handleXrAction(event, this);
|
|
||||||
//event.type !== 'move' && console.log(event)
|
|
||||||
const controller = event.target;
|
const controller = event.target;
|
||||||
//console.log(event)
|
if (!controller.userData?.active) return;
|
||||||
|
|
||||||
if (this.opts.designMode){
|
if (this.opts.designMode){
|
||||||
if (!controller.userData) return
|
|
||||||
if (controller.userData.active === false) return;
|
|
||||||
this.transformControls.getRaycaster().setFromXRController(controller);
|
this.transformControls.getRaycaster().setFromXRController(controller);
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case 'selectstart':
|
case 'selectstart':
|
||||||
@@ -400,13 +396,13 @@ class GameEngine extends EventManager{
|
|||||||
this.transformControls.pointerMove(null);
|
this.transformControls.pointerMove(null);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}else{
|
||||||
|
this.draggable?.handleController(controller, event.type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onSelect(event) {
|
onSelect(event) {
|
||||||
const controller = event.target;
|
const controller = event.target;
|
||||||
|
|
||||||
if (this.opts.designMode){
|
|
||||||
this.xrController1.userData.active = false;
|
this.xrController1.userData.active = false;
|
||||||
this.xrController2.userData.active = false;
|
this.xrController2.userData.active = false;
|
||||||
|
|
||||||
@@ -420,6 +416,7 @@ class GameEngine extends EventManager{
|
|||||||
this.xrController2.add(this.controllerLine);
|
this.xrController2.add(this.controllerLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.opts.designMode){
|
||||||
this.raycaster.setFromXRController(controller);
|
this.raycaster.setFromXRController(controller);
|
||||||
const intersects = this.raycaster.intersectObjects(this.activeObjects.children, true);
|
const intersects = this.raycaster.intersectObjects(this.activeObjects.children, true);
|
||||||
|
|
||||||
@@ -434,6 +431,8 @@ class GameEngine extends EventManager{
|
|||||||
this.transformControls.attach(intersects[0].object);
|
this.transformControls.attach(intersects[0].object);
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
|
}else{
|
||||||
|
this.clickable.handleController(controller, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -525,14 +524,14 @@ class GameEngine extends EventManager{
|
|||||||
|
|
||||||
onClick(mouseEvent, domElement){
|
onClick(mouseEvent, domElement){
|
||||||
let mouse = this.getMouseVector(mouseEvent, domElement);
|
let mouse = this.getMouseVector(mouseEvent, domElement);
|
||||||
this.raycaster.setFromCamera(mouse, this.camera);
|
//this.raycaster.setFromCamera(mouse, this.camera);
|
||||||
this.clickable.update(mouse, this.camera, mouseEvent);
|
this.clickable.handleMouse(mouse, mouseEvent);
|
||||||
this.hero?.idleReset();
|
this.hero?.idleReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
onPointer(mouseEvent, domElement, type){
|
onPointer(mouseEvent, domElement, type){
|
||||||
let mouse = this.getMouseVector(mouseEvent, domElement);
|
let mouse = this.getMouseVector(mouseEvent, domElement);
|
||||||
this.draggable?.update(mouse, this.camera, type);
|
this.draggable?.handleMouse(mouse, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
setCamera(camera) {
|
setCamera(camera) {
|
||||||
|
|||||||
+4
-2
@@ -95,11 +95,13 @@ class Hero{
|
|||||||
this.updateCharacterControls(delta)
|
this.updateCharacterControls(delta)
|
||||||
if (this.engine.renderer.xr.isPresenting){
|
if (this.engine.renderer.xr.isPresenting){
|
||||||
this.cameraMode = 'fixed'
|
this.cameraMode = 'fixed'
|
||||||
|
this.cameraY = this.size.y * 1;
|
||||||
//this.camera = this.engine.cameraWorld;
|
//this.camera = this.engine.cameraWorld;
|
||||||
// this.engine.activeObjects.position.x = -this.camera.position.x;
|
// this.engine.activeObjects.position.x = -this.camera.position.x;
|
||||||
// this.engine.activeObjects.position.z = -this.camera.position.z;
|
// this.engine.activeObjects.position.z = -this.camera.position.z;
|
||||||
}else{
|
}else{
|
||||||
this.cameraMode = 'rotate'
|
this.cameraMode = 'rotate'
|
||||||
|
this.cameraY = this.size.y * 1.5;
|
||||||
// this.camera = this.engine.cameraWorld;
|
// this.camera = this.engine.cameraWorld;
|
||||||
// this.engine.camera.position.set(0,0,0);
|
// this.engine.camera.position.set(0,0,0);
|
||||||
// this.engine.camera.rotation.set(0,0,0);
|
// this.engine.camera.rotation.set(0,0,0);
|
||||||
@@ -163,7 +165,7 @@ class Hero{
|
|||||||
this.fadeDuration = 1;
|
this.fadeDuration = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.currentAction.startsWith('idle') && play != 'idle' && !pc.isLocked){
|
if (this.currentAction.startsWith('idle') && play != 'idle' && !pc.isLocked && !this.engine.renderer.xr.isPresenting){
|
||||||
this.cameraIdleDelta += delta * 0.33;
|
this.cameraIdleDelta += delta * 0.33;
|
||||||
}else {
|
}else {
|
||||||
this.cameraIdleDelta = 0;
|
this.cameraIdleDelta = 0;
|
||||||
@@ -261,7 +263,7 @@ class Hero{
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
cameraPosition.lerp(cameraDesiredPosition, this.cameraMode == 'fixed' ? 1 : delta*2)
|
cameraPosition.lerp(cameraDesiredPosition, this.cameraMode == 'fixed' ? delta*2 : delta*2)
|
||||||
this.camera.position.copy(cameraPosition)
|
this.camera.position.copy(cameraPosition)
|
||||||
if (!pc.isLocked){
|
if (!pc.isLocked){
|
||||||
this.camera.lookAt(
|
this.camera.lookAt(
|
||||||
|
|||||||
@@ -127,7 +127,8 @@ video{
|
|||||||
.canvas-wrapper{
|
.canvas-wrapper{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 100vw;
|
max-width: 100vw;
|
||||||
height: calc(100vh - 288px);
|
//height: calc(100vh - 288px);
|
||||||
|
aspect-ratio: 16 / 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.canvas-wrapper:has(canvas:fullscreen){
|
.canvas-wrapper:has(canvas:fullscreen){
|
||||||
|
|||||||
Reference in New Issue
Block a user