This commit is contained in:
2025-06-13 20:28:16 +03:00
parent a16156d24a
commit ba3ac19704
3 changed files with 111 additions and 70 deletions
+9 -2
View File
@@ -14,6 +14,9 @@
<v-btn value="perspective" icon="mdi-cone"></v-btn> <v-btn value="perspective" icon="mdi-cone"></v-btn>
<v-btn value="orthographic" icon="mdi-cone-off"></v-btn> <v-btn value="orthographic" icon="mdi-cone-off"></v-btn>
</v-btn-toggle> </v-btn-toggle>
<v-btn-toggle variant="tonal" v-model="store.prefs.xr.depthSense" class="ma-3" density="comfortable" color="green-darken-2">
<v-btn :value="true" icon="mdi-cube-outline"></v-btn>
</v-btn-toggle>
</v-navigation-drawer> </v-navigation-drawer>
<div class="container my-3 position-relative game-designer-canvas"> <div class="container my-3 position-relative game-designer-canvas">
<div ref="target" @click="targetClick" @pointerdown="targetPointerDown"></div> <div ref="target" @click="targetClick" @pointerdown="targetPointerDown"></div>
@@ -48,6 +51,9 @@
<script> <script>
import { GameEngine } from '@/lib/gameEngine'; import { GameEngine } from '@/lib/gameEngine';
import { useAppStore } from '@/stores/app';
const store = useAppStore();
let gameEngine = null; let gameEngine = null;
@@ -63,7 +69,8 @@ export default {
pointerDownTime: 0, pointerDownTime: 0,
scenario: null, scenario: null,
renderType: 'ST', renderType: 'ST',
cameraType: 'perspective' cameraType: 'perspective',
store
} }
}, },
computed:{ computed:{
@@ -120,7 +127,7 @@ export default {
async mounted(){ async mounted(){
gameEngine = new GameEngine(); gameEngine = new GameEngine();
//this.gameEngine = gameEngine; //this.gameEngine = gameEngine;
await gameEngine.init(this.$refs.target, { xr: true }); await gameEngine.init(this.$refs.target, { xr: true, depthSense: this.store.prefs.xr.depthSense});
gameEngine.scene.add(gameEngine.transformControls.getHelper()); gameEngine.scene.add(gameEngine.transformControls.getHelper());
gameEngine.scene.add(new gameEngine.$.GridHelper(100,100)); gameEngine.scene.add(new gameEngine.$.GridHelper(100,100));
this.resize(); this.resize();
+89 -65
View File
@@ -109,33 +109,7 @@ class GameEngine {
function animate(time) { function animate(time) {
let delta = clock.getDelta(); let delta = clock.getDelta();
mixer.update(delta); mixer.update(delta);
if (gameEngine.xrController1?.gamepad){ gameEngine.handleXrAction(gameEngine, delta)
let gp = gameEngine.xrController1.gamepad;
if (gp.axes[3] != 0){
gameEngine.scene.position.z += gp.axes[3] * delta;
}
if (gp.axes[2] != 0){
gameEngine.scene.position.x += gp.axes[2] * delta;
}
}
if (gameEngine.xrController2?.gamepad){
let gp = gameEngine.xrController2.gamepad;
let gp1 = gameEngine.xrController1.gamepad;
// if (gp.axes[3] != 0){
// let sc = gameEngine.scene.scale.x + gp.axes[3] * delta * 0.5;
// gameEngine.scene.scale.set(sc, sc, sc);
// }
if (gp.axes[2] != 0){
if (gp1.buttons[4]?.pressed){
gameEngine.scene.position.y += gp.axes[2] * delta;
}else if (gp1.buttons[5]?.pressed){
let sc = gameEngine.scene.scale.x + gp.axes[2] * delta * 0.1;
gameEngine.scene.scale.set(sc, sc, sc);
}else{
gameEngine.scene.rotation.y += gp.axes[2] * delta * 0.5;
}
}
}
gameEngine.render(scene, gameEngine.camera); gameEngine.render(scene, gameEngine.camera);
gameEngine.gizmo?.render(); gameEngine.gizmo?.render();
} }
@@ -179,13 +153,14 @@ class GameEngine {
} }
if (opts.xr){ if (opts.xr){
renderer.xr.enabled = true; renderer.xr.enabled = true;
document.body.appendChild( XRButton.createButton( renderer, { document.body.appendChild(XRButton.createButton(renderer, opts.depthSense ?{
'optionalFeatures': [ 'depth-sensing' ], 'requiredFeatures': ['depth-sensing'],
depthSensing: { 'depthSensing': {
usagePreference: ["cpu-optimized", "gpu-optimized"], usagePreference: ["gpu-optimized"],
dataFormatPreference: ["luminance-alpha", "float32"], dataFormatPreference: ["unsigned-short"],
}, matchDepthView: false
} ) ); }
} : {}));
this.initXrControllers(); this.initXrControllers();
} }
} }
@@ -199,6 +174,8 @@ class GameEngine {
c1.userData.active = false; c1.userData.active = false;
c1.addEventListener('connected', e=>{ c1.addEventListener('connected', e=>{
c1.gamepad = e.data.gamepad; c1.gamepad = e.data.gamepad;
this.session = this.renderer.xr.getSession();
this.session.addEventListener('selectstart', this.onControllerEvent.bind(this));
}) })
this.scene.add( c1 ); this.scene.add( c1 );
@@ -233,45 +210,92 @@ class GameEngine {
this.xrController2 = c2 this.xrController2 = c2
} }
onControllerEvent(event) { handleXrAction(gameEngine, delta){
const controller = event.target; //console.log(event.type);
if (controller.userData.active === false) return; if (gameEngine.xrController1?.gamepad){
this.raycaster.setFromXRController(controller); let gp = gameEngine.xrController1.gamepad;
switch (event.type) { if (gp.axes[3] != 0){
case 'selectstart': gameEngine.scene.position.z += gp.axes[3] * delta;
this.transformControls.pointerDown(null); }
break; if (gp.axes[2] != 0){
case 'selectend': gameEngine.scene.position.x += gp.axes[2] * delta;
this.transformControls.pointerUp(null); }
break; }
case 'move': if (gameEngine.xrController2?.gamepad){
this.transformControls.pointerHover(null); let gp = gameEngine.xrController2.gamepad;
this.transformControls.pointerMove(null); let gp1 = gameEngine.xrController1.gamepad;
break; // if (gp.axes[3] != 0){
// let sc = gameEngine.scene.scale.x + gp.axes[3] * delta * 0.5;
// gameEngine.scene.scale.set(sc, sc, sc);
// }
if (gp.axes[2] != 0){
if (gp1.buttons[4]?.pressed){
gameEngine.scene.position.y += gp.axes[2] * delta;
}else if (gp1.buttons[5]?.pressed){
let sc = gameEngine.scene.scale.x * (gp.axes[2] * delta * 0.5 + 1);
gameEngine.scene.scale.set(sc, sc, sc);
}else{
gameEngine.scene.rotation.y += gp.axes[2] * delta * 0.5;
}
}
if (gp.buttons[4]?.pressed){
// gameEngine.setCameraOrthographic();
// gameEngine.renderer.xr.updateCamera(gameEngine.orthographicCamera);
let session = gameEngine.renderer.xr.getFrame().session;
console.log(session);
session.pauseDepthSensing();
}
if (gp.buttons[5]?.pressed){
// gameEngine.setCameraOrthographic();
// gameEngine.renderer.xr.updateCamera(gameEngine.orthographicCamera);
let session = gameEngine.renderer.xr.getFrame().session;
console.log(session);
session.resumeDepthSensing();
}
} }
} }
onControllerEvent(event) {
//this.handleXrAction(event, this);
event.type !=='move' && console.log(event)
// const controller = event.target;
// if (controller.userData.active === false) return;
// this.raycaster.setFromXRController(controller);
// switch (event.type) {
// case 'selectstart':
// this.transformControls.pointerDown(null);
// break;
// case 'selectend':
// this.transformControls.pointerUp(null);
// break;
// case 'move':
// this.transformControls.pointerHover(null);
// this.transformControls.pointerMove(null);
// break;
// }
}
onSelect(event) { onSelect(event) {
const controller = event.target; // const controller = event.target;
this.xrController1.userData.active = false; // this.xrController1.userData.active = false;
this.xrController2.userData.active = false; // this.xrController2.userData.active = false;
if (controller === this.xrController1) { // if (controller === this.xrController1) {
this.xrController1.userData.active = true; // this.xrController1.userData.active = true;
this.xrController1.add(line); // this.xrController1.add(line);
} // }
if (controller === this.xrController2) { // if (controller === this.xrController2) {
this.xrController2.userData.active = true; // this.xrController2.userData.active = true;
this.xrController2.add(line); // this.xrController2.add(line);
} // }
this.raycaster.setFromXRController(controller); // this.raycaster.setFromXRController(controller);
const intersects = this.raycaster.intersectObjects(this.activeObjects.children); // const intersects = this.raycaster.intersectObjects(this.activeObjects.children);
if (intersects.length > 0) { // if (intersects.length > 0) {
this.transformControls.attach(intersects[0].object); // this.transformControls.attach(intersects[0].object);
} // }
} }
$ = THREE; $ = THREE;
+13 -3
View File
@@ -1,8 +1,18 @@
// Utilities // Utilities
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { computed, reactive, watch } from 'vue'
let prefs = localStorage.getItem('prefs')
prefs = reactive(prefs ? JSON.parse(prefs) : {
xr: {
depthSense: true
}
})
watch(prefs, (newPrefs) => {
localStorage.setItem('prefs', JSON.stringify(newPrefs))
}, { deep: true })
export const useAppStore = defineStore('app', { export const useAppStore = defineStore('app', {
state: () => ({ state: () => ({ prefs }),
//
}),
}) })