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