#72 epic refactoring
This commit is contained in:
@@ -14,23 +14,23 @@
|
||||
<v-btn value="perspective" icon="mdi-cone"></v-btn>
|
||||
<v-btn value="orthographic" icon="mdi-cone-off"></v-btn>
|
||||
</v-btn-toggle>
|
||||
<template v-if="currentObject?.__o">
|
||||
<div v-if="currentObject" :version="version">
|
||||
<v-card subtitle="Position" class="ma-1" color="light-blue-darken-4">
|
||||
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="x" v-model="currentObject.__o.position.x"></v-number-input>
|
||||
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="y" v-model="currentObject.__o.position.y"></v-number-input>
|
||||
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="z" v-model="currentObject.__o.position.z"></v-number-input>
|
||||
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="x" v-model="currentObject.position.x"></v-number-input>
|
||||
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="y" v-model="currentObject.position.y"></v-number-input>
|
||||
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="z" v-model="currentObject.position.z"></v-number-input>
|
||||
</v-card>
|
||||
<v-card subtitle="Rotation" class="ma-1" color="green-darken-4">
|
||||
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="x" v-model="currentObject.__o.rotation.x"></v-number-input>
|
||||
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="y" v-model="currentObject.__o.rotation.y"></v-number-input>
|
||||
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="z" v-model="currentObject.__o.rotation.z"></v-number-input>
|
||||
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="x" v-model="currentObject.rotation.x"></v-number-input>
|
||||
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="y" v-model="currentObject.rotation.y"></v-number-input>
|
||||
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="z" v-model="currentObject.rotation.z"></v-number-input>
|
||||
</v-card>
|
||||
<v-card subtitle="Scale" class="ma-1" color="pink-darken-4">
|
||||
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="x" v-model="currentObject.__o.scale.x"></v-number-input>
|
||||
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="y" v-model="currentObject.__o.scale.y"></v-number-input>
|
||||
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="z" v-model="currentObject.__o.scale.z"></v-number-input>
|
||||
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="x" v-model="currentObject.scale.x"></v-number-input>
|
||||
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="y" v-model="currentObject.scale.y"></v-number-input>
|
||||
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="z" v-model="currentObject.scale.z"></v-number-input>
|
||||
</v-card>
|
||||
</template>
|
||||
</div>
|
||||
</v-navigation-drawer>
|
||||
<div class="container my-3 position-relative game-designer-canvas">
|
||||
<div ref="target" @click="targetClick" @pointerdown="targetPointerDown"></div>
|
||||
@@ -47,11 +47,9 @@
|
||||
</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>
|
||||
<v-list selectable color="primary" @update:selected="loadScene($event[0])" :items="scenes"></v-list>
|
||||
<v-list selectable @update:selected="selectObject($event[0])" color="secondary">
|
||||
<v-list-item v-for="(v, k) in sceneObjects" :title="v.__title" :subtitle="k" :value="k">
|
||||
<template v-slot:prepend>
|
||||
<v-btn variant="plain" density="comfortable" size="small" v-if="v.__o"
|
||||
:icon="`mdi-eye${v.__o.visible ? '' : '-off'}`"
|
||||
@@ -64,35 +62,137 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GameEngine } from '@/lib/GameEngine';
|
||||
import { GameManager } from '@/lib/GameManager';
|
||||
import { markRaw } from 'vue';
|
||||
|
||||
import GameEnvironmentMixin from '@/mixins/GameEnvironmentMixin';
|
||||
let engine = null, manager = null;
|
||||
|
||||
export default {
|
||||
mixins: [GameEnvironmentMixin],
|
||||
props:{
|
||||
modelValue: Object,
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
env: 'GameDesigner',
|
||||
scenesList: [],
|
||||
objectsList: [],
|
||||
scenes: [],
|
||||
currentScene: null,
|
||||
sceneObjects: {},
|
||||
currentObject: null,
|
||||
objectAnimations: [],
|
||||
mode: 'translate',
|
||||
pointerDownTime: 0,
|
||||
scenario: null,
|
||||
renderType: 'ST',
|
||||
cameraType: 'perspective'
|
||||
cameraType: 'perspective',
|
||||
version: 0
|
||||
}
|
||||
},
|
||||
|
||||
async mounted(){
|
||||
engine = new GameEngine();
|
||||
await engine.init(this.$refs.target, {
|
||||
xr: true,
|
||||
gizmo: true,
|
||||
stats: true,
|
||||
mode: 'GameDesigner'
|
||||
});
|
||||
manager = await new GameManager(engine, this.modelValue, null, {
|
||||
onObjectLoad:(sceneObjects, data, object3d, source)=>{
|
||||
['position', 'scale', 'rotation', 'visible'].forEach(p=>{
|
||||
sceneObjects[data.id][p] = object3d[p];
|
||||
})
|
||||
sceneObjects[data.id].__o = markRaw(object3d);
|
||||
sceneObjects[data.id].__animations = markRaw(source.animations || []);
|
||||
sceneObjects[data.id].__title = data.title;
|
||||
}
|
||||
});
|
||||
this.scenes = manager.scenarioData.scenes.map(s=>({
|
||||
title: s.data.title,
|
||||
value: s.data.id
|
||||
}))
|
||||
window.addEventListener('resize', this.resize);
|
||||
},
|
||||
|
||||
async unmounted(){
|
||||
this.debug('Disposing scene')
|
||||
window.removeEventListener('resize', this.resize);
|
||||
engine.transformControls.removeEventListener('change', this.update)
|
||||
engine.tm?.setGame(null);
|
||||
engine.dispose();
|
||||
this.debug('Disposed scene', JSON.stringify(engine.renderer.info.memory));
|
||||
engine = null;
|
||||
manager = null;
|
||||
},
|
||||
|
||||
watch:{
|
||||
async 'object.scenario'(n){
|
||||
await this.loadScenario()
|
||||
mode(n){
|
||||
engine.transformControls.setMode(n)
|
||||
},
|
||||
renderType(v){
|
||||
engine.renderType = v;
|
||||
},
|
||||
cameraType(v){
|
||||
if (v == 'perspective'){
|
||||
engine.setCameraPerspective();
|
||||
}else{
|
||||
engine.setCameraOrthographic();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods:{
|
||||
async loadScene(sceneId){
|
||||
engine.transformControls.removeEventListener('change', this.update)
|
||||
await manager.loadScene(sceneId)
|
||||
this.currentScene = manager.scenarioData.scenes.find(sc=>sc.data.id == sceneId);
|
||||
this.sceneObjects = this.modelValue.scenes?.[sceneId]?.objects
|
||||
engine.transformControls.addEventListener('change', this.update)
|
||||
},
|
||||
|
||||
selectObject(oid){
|
||||
this.currentObject = this.sceneObjects[oid];
|
||||
engine.transformControls.attach(this.currentObject.__o);
|
||||
engine.gizmo.target = this.currentObject.__o.position;
|
||||
engine.camera.updateProjectionMatrix();
|
||||
this.objectAnimations = this.currentObject?.__animations?.map(a => ({
|
||||
name: a.name, id: a.uuid, a
|
||||
}));
|
||||
},
|
||||
|
||||
targetClick(e){
|
||||
if (performance.now() - this.pointerDownTime < 200){
|
||||
let intersects = engine.intersect(e, this.$refs.target, engine.activeObjects.children, true);
|
||||
if (intersects.length){
|
||||
this.selectObject(intersects[0].object.__pn_id)
|
||||
}else{
|
||||
engine.transformControls.detach();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
targetPointerDown(){
|
||||
this.pointerDownTime = performance.now();
|
||||
},
|
||||
|
||||
targetPointer(e, t){
|
||||
engine.onPointer(e, this.$refs.target, t);
|
||||
},
|
||||
|
||||
async toggleAnimation(animation){
|
||||
animation.playing = !animation.playing;
|
||||
engine.playAnimation(engine.scene, animation.a, animation.playing);
|
||||
},
|
||||
|
||||
resize(){
|
||||
let r = this.$refs.target;
|
||||
this.debug('resizing!!', r.clientWidth, r.clientHeight, r)
|
||||
engine.resize(r.clientWidth, r.clientHeight);
|
||||
//this.zoom = Math.min(r.clientWidth / this.viewBox.w, r.clientHeight / this.viewBox.h);
|
||||
},
|
||||
|
||||
update(){
|
||||
this.version ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user