This commit is contained in:
@@ -16,19 +16,29 @@
|
|||||||
</v-btn-toggle>
|
</v-btn-toggle>
|
||||||
<div v-if="currentObject" :version="version">
|
<div v-if="currentObject" :version="version">
|
||||||
<v-card subtitle="Position" class="ma-1" color="light-blue-darken-4">
|
<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.position.x"></v-number-input>
|
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="x" v-model="currentObject.position.x" :step="0.1"></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="y" v-model="currentObject.position.y" :step="0.1"></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-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="z" v-model="currentObject.position.z" :step="0.1"></v-number-input>
|
||||||
</v-card>
|
</v-card>
|
||||||
<v-card subtitle="Rotation" class="ma-1" color="green-darken-4">
|
<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.rotation.x"></v-number-input>
|
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="x" v-model="currentObject.rotation.x" :step="0.1"></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="y" v-model="currentObject.rotation.y" :step="0.1"></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-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="z" v-model="currentObject.rotation.z" :step="0.1"></v-number-input>
|
||||||
</v-card>
|
</v-card>
|
||||||
<v-card subtitle="Scale" class="ma-1" color="pink-darken-4">
|
<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.scale.x"></v-number-input>
|
<template v-slot:append>
|
||||||
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="y" v-model="currentObject.scale.y"></v-number-input>
|
<v-btn :icon="uniformScale ? 'mdi-lock-outline' : 'mdi-lock-open-variant-outline'" size="x-small" variant="text" density="compact" @click="uniformScale = !uniformScale"></v-btn>
|
||||||
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="z" v-model="currentObject.scale.z"></v-number-input>
|
</template>
|
||||||
|
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="x" v-model="currentObject.scale.x" :step="0.01"></v-number-input>
|
||||||
|
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="y" v-model="currentObject.scale.y" :step="0.01"></v-number-input>
|
||||||
|
<v-number-input :precision="null" controlVariant="stacked" hide-details density="compact" label="z" v-model="currentObject.scale.z" :step="0.01"></v-number-input>
|
||||||
|
</v-card>
|
||||||
|
<v-card subtitle="Info" v-if="objectInfo" class="ma-1" color="purple-darken-4">
|
||||||
|
<div class="d-flex flex-column text-caption px-3">
|
||||||
|
<div>Width: {{ (currentObject.scale.x * objectInfo.width).toFixed(2) }}</div>
|
||||||
|
<div>Height: {{ (currentObject.scale.y * objectInfo.height).toFixed(2) }}</div>
|
||||||
|
<div>Depth: {{ (currentObject.scale.z * objectInfo.depth).toFixed(2) }}</div>
|
||||||
|
</div>
|
||||||
</v-card>
|
</v-card>
|
||||||
</div>
|
</div>
|
||||||
</v-navigation-drawer>
|
</v-navigation-drawer>
|
||||||
@@ -84,6 +94,7 @@ export default {
|
|||||||
pointerDownTime: 0,
|
pointerDownTime: 0,
|
||||||
renderType: 'ST',
|
renderType: 'ST',
|
||||||
cameraType: 'perspective',
|
cameraType: 'perspective',
|
||||||
|
uniformScale: true,
|
||||||
version: 0
|
version: 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -98,8 +109,8 @@ export default {
|
|||||||
});
|
});
|
||||||
manager = await new GameManager(engine, this.modelValue, null, {
|
manager = await new GameManager(engine, this.modelValue, null, {
|
||||||
onObjectLoad:(sceneObjects, data, object3d, source)=>{
|
onObjectLoad:(sceneObjects, data, object3d, source)=>{
|
||||||
['position', 'scale', 'rotation', 'visible'].forEach(p=>{
|
['position', 'scale', 'rotation'].forEach(p=>{
|
||||||
sceneObjects[data.id][p] = object3d[p];
|
sceneObjects[data.id][p] = object3d[p].clone();
|
||||||
})
|
})
|
||||||
sceneObjects[data.id].__o = markRaw(object3d);
|
sceneObjects[data.id].__o = markRaw(object3d);
|
||||||
sceneObjects[data.id].__animations = markRaw(source.animations || []);
|
sceneObjects[data.id].__animations = markRaw(source.animations || []);
|
||||||
@@ -124,6 +135,19 @@ export default {
|
|||||||
manager = null;
|
manager = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
computed:{
|
||||||
|
objectInfo(){
|
||||||
|
if (this.currentObject.__o.userData?.bbox){
|
||||||
|
let b = this.currentObject.__o.userData.bbox;
|
||||||
|
return {
|
||||||
|
width: b.max.x - b.min.x,
|
||||||
|
height: b.max.y - b.min.y,
|
||||||
|
depth: b.max.z - b.min.z
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
watch:{
|
watch:{
|
||||||
mode(n){
|
mode(n){
|
||||||
engine.transformControls.setMode(n)
|
engine.transformControls.setMode(n)
|
||||||
@@ -137,22 +161,49 @@ export default {
|
|||||||
}else{
|
}else{
|
||||||
engine.setCameraOrthographic();
|
engine.setCameraOrthographic();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
'currentObject':{
|
||||||
|
deep: true,
|
||||||
|
handler(v){
|
||||||
|
this.handleScale(this.currentObject, this.currentObject.__o)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods:{
|
methods:{
|
||||||
async loadScene(sceneId){
|
async loadScene(sceneId){
|
||||||
engine.transformControls.removeEventListener('change', this.update)
|
|
||||||
await manager.loadScene(sceneId)
|
await manager.loadScene(sceneId)
|
||||||
this.currentScene = manager.scenarioData.scenes.find(sc=>sc.data.id == sceneId);
|
this.currentScene = manager.scenarioData.scenes.find(sc=>sc.data.id == sceneId);
|
||||||
this.sceneObjects = this.modelValue.scenes?.[sceneId]?.objects
|
this.sceneObjects = this.modelValue.scenes?.[sceneId]?.objects
|
||||||
engine.transformControls.addEventListener('change', this.update)
|
engine.transformControls.addEventListener('objectChange', this.handleTransformControlsChange)
|
||||||
|
},
|
||||||
|
|
||||||
|
handleScale(src, dst){
|
||||||
|
if (this.uniformScale){
|
||||||
|
for (let p of ['x', 'y', 'z']){
|
||||||
|
if (src.scale[p] != dst.scale[p]) {
|
||||||
|
let k = src.scale[p]/dst.scale[p];
|
||||||
|
['x', 'y', 'z'].filter(c=>src.scale[c] == dst.scale[c]).forEach(c=>{
|
||||||
|
src.scale[c] = dst.scale[c] * k;
|
||||||
|
engine.transformControls._scaleStart[c] = src.scale[c];
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
['position', 'scale', 'rotation'].forEach(p=>{
|
||||||
|
dst[p].copy(src[p]);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
handleTransformControlsChange(){
|
||||||
|
this.handleScale(this.currentObject.__o, this.currentObject);
|
||||||
},
|
},
|
||||||
|
|
||||||
selectObject(oid){
|
selectObject(oid){
|
||||||
this.currentObject = this.sceneObjects[oid];
|
this.currentObject = this.sceneObjects[oid];
|
||||||
engine.transformControls.attach(this.currentObject.__o);
|
engine.transformControls.attach(this.currentObject.__o);
|
||||||
engine.gizmo.target = this.currentObject.__o.position;
|
engine.gizmo.target = this.currentObject.position;
|
||||||
engine.camera.updateProjectionMatrix();
|
engine.camera.updateProjectionMatrix();
|
||||||
this.objectAnimations = this.currentObject?.__animations?.map(a => ({
|
this.objectAnimations = this.currentObject?.__animations?.map(a => ({
|
||||||
name: a.name, id: a.uuid, a
|
name: a.name, id: a.uuid, a
|
||||||
@@ -189,10 +240,6 @@ export default {
|
|||||||
engine.resize(r.clientWidth, r.clientHeight);
|
engine.resize(r.clientWidth, r.clientHeight);
|
||||||
//this.zoom = Math.min(r.clientWidth / this.viewBox.w, r.clientHeight / this.viewBox.h);
|
//this.zoom = Math.min(r.clientWidth / this.viewBox.w, r.clientHeight / this.viewBox.h);
|
||||||
},
|
},
|
||||||
|
|
||||||
update(){
|
|
||||||
this.version ++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -26,7 +26,7 @@ THREE.Cache.enabled = true
|
|||||||
|
|
||||||
const assetPath = '/asset/default/';
|
const assetPath = '/asset/default/';
|
||||||
const defaultLightIntensity = 11;
|
const defaultLightIntensity = 11;
|
||||||
const sceneScale = 1//.33;
|
const sceneScale = 1.33;
|
||||||
|
|
||||||
class GameEngine extends EventManager{
|
class GameEngine extends EventManager{
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,10 @@ class GameManager{
|
|||||||
|
|
||||||
this.loadScene = async function(sceneId){
|
this.loadScene = async function(sceneId){
|
||||||
let scene = scenarioData.scenes.find(sc=>sc.data.id == sceneId);
|
let scene = scenarioData.scenes.find(sc=>sc.data.id == sceneId);
|
||||||
let sceneObjects = gameData.scenes?.[sceneId]?.objects || {};
|
gameData.scenes = gameData.scenes || {};
|
||||||
|
gameData.scenes[sceneId] = gameData.scenes[sceneId] || {};
|
||||||
|
gameData.scenes[sceneId].objects = gameData.scenes[sceneId].objects || {};
|
||||||
|
let sceneObjects = gameData.scenes[sceneId].objects;
|
||||||
engine.tm?.setGame(gameData.id);
|
engine.tm?.setGame(gameData.id);
|
||||||
let intro;
|
let intro;
|
||||||
await engine.resetScene();
|
await engine.resetScene();
|
||||||
|
|||||||
@@ -38,8 +38,12 @@ class MeshUtils {
|
|||||||
|
|
||||||
getBoundingBox(object){
|
getBoundingBox(object){
|
||||||
let bb = new Box3().setFromObject(object);
|
let bb = new Box3().setFromObject(object);
|
||||||
bb.min.multiplyScalar(1 / this.engine.scale);
|
let scale = new Vector3(1,1,1);
|
||||||
bb.max.multiplyScalar(1 / this.engine.scale);
|
object.traverseAncestors(o=>{
|
||||||
|
scale.multiply(o.scale);
|
||||||
|
});
|
||||||
|
bb.min.divide(scale);
|
||||||
|
bb.max.divide(scale);
|
||||||
return bb;
|
return bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export default {
|
|||||||
async save(params) {
|
async save(params) {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
try {
|
try {
|
||||||
this.debug('saving', this.object)
|
//this.debug('saving', this.object)
|
||||||
let result = await this.$api.game.save(this.object);
|
let result = await this.$api.game.save(this.object);
|
||||||
this.object.id = result.data.object.id;
|
this.object.id = result.data.object.id;
|
||||||
if (this.id == 'add') {
|
if (this.id == 'add') {
|
||||||
|
|||||||
Reference in New Issue
Block a user