interactive objects parametrization

This commit is contained in:
2025-11-02 18:03:46 +02:00
parent 6253fc32d7
commit d8618c69f4
15 changed files with 411 additions and 474 deletions
+205
View File
@@ -0,0 +1,205 @@
import { GameEngine } from '@/lib/GameEngine';
import { Hero } from '@/lib/Hero';
let gameEngine = null;
export default {
async mounted(){
gameEngine = new GameEngine();
//this.gameEngine = gameEngine;
await gameEngine.init(this.$refs.target, {
xr: true,
gizmo: this.env == 'GameDesigner',
designMode: this.env == 'GameDesigner',
depthSense: this.env == 'GameDesigner' ? false : this.store.prefs.xr.depthSense
});
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();
},
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();
}
}
},
methods:{
async loadScenario(){
if (this.object.scenario){
this.scenario = (await this.$api.scenario.load(this.object.scenario)).data;
}else{
this.scenario = null;
}
},
async expandScenarioData(scene){
const promises = [];
promises.push(this.$api.gameObject.load(scene.data.environment).then(r=>scene.data.$environment = r.data))
for (let i of scene.data.items || []) {
if (i.data.io){
if (i.data.io.go){
promises.push(this.$api.gameObject.load(i.data.io.go).then(r=>i.data.io.$go = r.data));
}
}else{
promises.push(this.$api.gameObject.load(i.data.go).then(r=>i.data.$go = r.data));
}
}
await Promise.all(promises);
},
/**
* loads all environment objects
* @param scene Scene object from the Scenario Module
* @param target Target scene definition from Game Module
*/
async loadEnvironment(scene, target){
//await gameEngine.loadPanorama(`/asset/default/43.webp`);
gameEngine.activeObjects.clear();
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 || []) {
if (i.data.io){
}else{
let gltf = await gameEngine.load(`/asset/default/${i.data.$go.asset.name}`);
this.setObjectAttributes(l, i.data, gltf, 1);
gameEngine.activeObjects.add(gltf.scene);
if (this.env == 'GamePlaying'){
if (i.data.$go.type == 'player3d'){
let hero = new Hero(gltf, i.data.$go);
hero.init(gameEngine);
}else{
if (gltf.animations?.length){
gameEngine.playAnimation(gameEngine.scene, gltf.animations[0]);
}
}
}
}
}
// let camera = new gameEngine.$.PerspectiveCamera();
// let cameraHelper = new gameEngine.$.CameraHelper(camera);
// gameEngine.activeObjects.add(cameraHelper);
// gameEngine.activeObjects.add(camera);
// this.setObjectAttributes(l, { id: 'camera', 'title': 'Main camera' }, { scene: camera })
// cameraHelper.update();
//this is needed cause when mounted canvas has different size
this.resize();
},
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){
//console.log('attaching controls to', intersects[0].object)
//gameEngine.transformControls.attach(intersects[0].object);
console.log(this.sceneObjects[intersects[0].object.__pn_id])
this.objectsList[0] = this.sceneObjects[intersects[0].object.__pn_id]
}else{
gameEngine.transformControls.detach();
}
}
},
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);
},
control(){
gameEngine.hero.lockControls();
}
}
}