xr and gameplay
This commit is contained in:
@@ -25,6 +25,8 @@
|
||||
<v-list-item prepend-icon="mdi-cogs" :title="l.gameRules"></v-list-item>
|
||||
<v-divider></v-divider>
|
||||
<v-list-item prepend-icon="mdi-controller" :title="l.games" to="/games/list"></v-list-item>
|
||||
<v-list-item prepend-icon="mdi-cog-play" :title="l.play" to="/play/list"></v-list-item>
|
||||
|
||||
</v-list>
|
||||
<v-divider></v-divider>
|
||||
<v-list nav>
|
||||
|
||||
@@ -175,6 +175,7 @@ export default {
|
||||
targetClick(e){
|
||||
if (performance.now() - this.pointerDownTime < 200){
|
||||
let intersects = gameEngine.intersect(e, this.$refs.target, gameEngine.activeObjects.children, true);
|
||||
//console.log(intersects)
|
||||
if (intersects.length){
|
||||
//console.log('attaching controls to', intersects[0].object)
|
||||
//gameEngine.transformControls.attach(intersects[0].object);
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
<template>
|
||||
<v-navigation-drawer width="133">
|
||||
<v-btn-toggle variant="tonal" density="comfortable" class="ma-3" v-model="renderType" color="light-blue-darken-4">
|
||||
<v-btn value="ST" icon="mdi-video-3d-variant"></v-btn>
|
||||
<v-btn value="VR" icon="mdi-google-cardboard"></v-btn>
|
||||
<v-btn value="AG" icon="mdi-glasses"></v-btn>
|
||||
</v-btn-toggle>
|
||||
<v-btn-toggle variant="tonal" density="comfortable" class="ma-3" v-model="mode" color="green-darken-4">
|
||||
<v-btn class="text-none" value="translate" icon="mdi-cursor-move"></v-btn>
|
||||
<v-btn class="text-none" value="rotate" icon="mdi-rotate-orbit"></v-btn>
|
||||
<v-btn class="text-none" value="scale" icon="mdi-resize"></v-btn>
|
||||
</v-btn-toggle>
|
||||
<v-btn-toggle variant="tonal" v-model="cameraType" class="ma-3" density="comfortable" color="orange-darken-4">
|
||||
<v-btn value="perspective" icon="mdi-cone"></v-btn>
|
||||
<v-btn value="orthographic" icon="mdi-cone-off"></v-btn>
|
||||
</v-btn-toggle>
|
||||
</v-navigation-drawer>
|
||||
<div class="container my-3 position-relative game-designer-canvas">
|
||||
<div ref="target" @click="targetClick" @pointerdown="targetPointerDown"></div>
|
||||
<div class="renderer-gizmo"></div>
|
||||
</div>
|
||||
<v-toolbar density="compact">
|
||||
<v-slide-group show-arrows>
|
||||
<v-slide-group-item v-for="(a, i) in objectAnimations" :key="i" v-slot="{ isSelected }">
|
||||
<v-btn :color="isSelected ? 'primary' : undefined" class="ma-2"
|
||||
:prepend-icon="'mdi-' + (a.playing ? 'stop' : 'play')" rounded @click="toggleAnimation(a)">
|
||||
{{ a.name }}
|
||||
</v-btn>
|
||||
</v-slide-group-item>
|
||||
</v-slide-group>
|
||||
</v-toolbar>
|
||||
<v-navigation-drawer location="right">
|
||||
<v-list v-model:selected="scenesList" selectable color="primary">
|
||||
<v-list-item v-for="(s, i) in scenes" :key="i" :title="s.data.title" :value="s"></v-list-item>
|
||||
</v-list>
|
||||
<v-list selectable v-model:selected="objectsList" color="secondary">
|
||||
<v-list-item v-for="(v, k) in sceneObjects" :title="v.__title" :subtitle="k" :value=v>
|
||||
<template v-slot:prepend>
|
||||
<v-btn variant="plain" density="comfortable" size="small" v-if="v.__o"
|
||||
:icon="`mdi-eye${v.__o.visible ? '' : '-off'}`"
|
||||
@click.stop="v.__o.visible = !v.__o.visible"></v-btn>
|
||||
<!-- <v-icon :icon="components[item.name].icon" size="small"></v-icon> -->
|
||||
</template>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-navigation-drawer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { GameEngine } from '@/lib/gameEngine';
|
||||
|
||||
let gameEngine = null;
|
||||
|
||||
export default {
|
||||
props:{
|
||||
modelValue: Object,
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
scenesList: [],
|
||||
objectsList: [],
|
||||
mode: 'translate',
|
||||
pointerDownTime: 0,
|
||||
scenario: null,
|
||||
renderType: 'ST',
|
||||
cameraType: 'perspective'
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
scenes(){
|
||||
return this.scenario?.scenes || [];
|
||||
},
|
||||
scene(){
|
||||
return this.scenesList[0];
|
||||
},
|
||||
currentObject(){
|
||||
return this.objectsList[0];
|
||||
},
|
||||
sceneObjects(){
|
||||
return this.object.scenes?.[this.scene?.data?.id]?.objects;
|
||||
},
|
||||
object(){
|
||||
return this.modelValue;
|
||||
},
|
||||
objectAnimations(){
|
||||
return this.currentObject?.__g?.animations?.map(a => ({
|
||||
name: a.name, id: a.uuid, a
|
||||
}));
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
async scene(n){
|
||||
this.object.scenes = this.object.scenes || {}
|
||||
this.object.scenes[n.data.id] = this.object.scenes[n.data.id] || {}
|
||||
await this.loadEnvironment(n, this.object.scenes[n.data.id]);
|
||||
},
|
||||
mode(n){
|
||||
gameEngine.transformControls.setMode(n)
|
||||
},
|
||||
async 'object.scenario'(n){
|
||||
await this.loadScenario()
|
||||
},
|
||||
currentObject(n){
|
||||
// gameEngine.transformControls.attach(n.__o);
|
||||
// gameEngine.gizmo.target = n.__o.position;
|
||||
//gameEngine.camera.lookAt(n.__o.position)
|
||||
gameEngine.camera.updateProjectionMatrix()
|
||||
},
|
||||
renderType(v){
|
||||
gameEngine.renderType = v;
|
||||
},
|
||||
cameraType(v){
|
||||
if (v == 'perspective'){
|
||||
gameEngine.setCameraPerspective();
|
||||
}else{
|
||||
gameEngine.setCameraOrthographic();
|
||||
}
|
||||
}
|
||||
},
|
||||
async mounted(){
|
||||
gameEngine = new GameEngine();
|
||||
//this.gameEngine = gameEngine;
|
||||
await gameEngine.init(this.$refs.target);
|
||||
gameEngine.scene.add(gameEngine.transformControls.getHelper());
|
||||
gameEngine.scene.add(new gameEngine.$.GridHelper(100,100));
|
||||
this.resize();
|
||||
//gameEngine.setCamera(gameEngine.orthographicCamera)
|
||||
//gameEngine.setCameraOrthographic();
|
||||
await this.loadScenario();
|
||||
window.addEventListener('resize', this.resize);
|
||||
},
|
||||
unmounted(){
|
||||
window.removeEventListener('resize', this.resize);
|
||||
gameEngine.stop();
|
||||
},
|
||||
methods:{
|
||||
async loadScenario(){
|
||||
if (this.object.scenario){
|
||||
this.scenario = (await this.$api.scenario.load(this.object.scenario)).data;
|
||||
}else{
|
||||
this.scenario = null;
|
||||
}
|
||||
},
|
||||
async loadEnvironment(scene, target){
|
||||
await gameEngine.loadPanorama(`/asset/default/43.webp`);
|
||||
await this.expandScenarioData(scene);
|
||||
target.objects = target.objects || {};
|
||||
let l = target.objects;
|
||||
if (this.scene.data.$environment.type == 'panorama2d'){
|
||||
await gameEngine.loadPanorama(`/asset/default/${this.scene.data.$environment.asset.name}`);
|
||||
}else{
|
||||
let env = await gameEngine.load(`/asset/default/${this.scene.data.$environment.asset.name}`);
|
||||
this.setObjectAttributes(l, this.scene.data, env, 100);
|
||||
gameEngine.activeObjects.add(env.scene);
|
||||
}
|
||||
for (let i of this.scene.data.items) {
|
||||
let gltf = await gameEngine.load(`/asset/default/${i.data.$go.asset.name}`);
|
||||
this.setObjectAttributes(l, i.data, gltf, 10);
|
||||
gameEngine.activeObjects.add(gltf.scene);
|
||||
//console.log(JSON.stringify(l));
|
||||
//window.gameEngine = gameEngine;
|
||||
//console.log(new gameEngine.$.Euler({"isEuler":true,"_x":0,"_y":0,"_z":0,"_order":"XYZ"}));
|
||||
}
|
||||
},
|
||||
async expandScenarioData(scene){
|
||||
scene.data.$environment = (await this.$api.gameObject.load(scene.data.environment)).data
|
||||
for (let i of scene.data.items) {
|
||||
i.data.$go = (await this.$api.gameObject.load(i.data.go)).data;
|
||||
}
|
||||
},
|
||||
targetPointerDown(){
|
||||
this.pointerDownTime = performance.now();
|
||||
},
|
||||
targetClick(e){
|
||||
if (performance.now() - this.pointerDownTime < 200){
|
||||
let intersects = gameEngine.intersect(e, this.$refs.target, gameEngine.activeObjects.children, true);
|
||||
//console.log(intersects)
|
||||
if (intersects.length){
|
||||
|
||||
}else{
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
setObjectAttributes(l, data, o, autoScaleFactor = 1){
|
||||
if (l[data.id]){
|
||||
['position', 'scale', 'rotation'].forEach(p=>{
|
||||
o.scene[p].copy(l[data.id][p])
|
||||
})
|
||||
}else{
|
||||
gameEngine.autoScale(o.scene, autoScaleFactor);
|
||||
}
|
||||
l[data.id] = l[data.id] || {};
|
||||
['position', 'scale', 'rotation', 'visible'].forEach(p=>{
|
||||
l[data.id][p] = o.scene[p];
|
||||
})
|
||||
l[data.id].__o = o.scene;
|
||||
l[data.id].__g = o;
|
||||
l[data.id].__title = data.title;
|
||||
o.scene.__pn_id = data.id;
|
||||
},
|
||||
async toggleAnimation(animation){
|
||||
animation.playing = !animation.playing;
|
||||
gameEngine.playAnimation(gameEngine.scene, animation.a, animation.playing);
|
||||
},
|
||||
resize(){
|
||||
let r = this.$refs.target;
|
||||
gameEngine.resize(r.clientWidth, r.clientHeight);
|
||||
//this.zoom = Math.min(r.clientWidth / this.viewBox.w, r.clientHeight / this.viewBox.h);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user