scene introduction

This commit is contained in:
2025-11-08 11:51:15 +02:00
parent 49dc4e9f7c
commit 168fb5b770
9 changed files with 46 additions and 30 deletions
@@ -22,13 +22,12 @@ const InteractiveObjectsImports = {
class InteractiveObject { class InteractiveObject {
constructor(gameEngine, obj) { constructor(gameEngine, obj) {
this.name = obj.name; this.name = obj.name;
this.ready = new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
switch (obj.type || 'GenericObject') { switch (obj.type || 'GenericObject') {
case 'Group': case 'Group':
this.object = new Group(); this.object = new Group();
for (let g of obj.group){ for (let g of obj.group){
let go = new InteractiveObject(gameEngine, g); let gameMesh = await new InteractiveObject(gameEngine, g);
let gameMesh = await go.ready;
this.object.add(gameMesh.object); this.object.add(gameMesh.object);
} }
break; break;
@@ -78,9 +77,8 @@ class InteractiveObject {
this.object.game = game; this.object.game = game;
break; break;
case 'VideoPlayer': case 'VideoPlayer':
let vp = new VideoPlayer(gameEngine, gameEngine.assetPath + obj.$go.asset.name); this.source = await new VideoPlayer(gameEngine, obj.$go.asset.name, gameEngine.assetPath);
this.source = await vp.ready; this.object = this.source.object;
this.object = vp.object;
break; break;
case 'PuzzleGame1': case 'PuzzleGame1':
case 'PuzzleGame2': case 'PuzzleGame2':
@@ -110,8 +110,7 @@ class MazeObject {
//console.log('loadingggg', def.objects) //console.log('loadingggg', def.objects)
def.objects?.forEach(async obj => { def.objects?.forEach(async obj => {
obj.room = room; obj.room = room;
let go = new InteractiveObject(engine, obj) let go = await new InteractiveObject(engine, obj)
await go.ready;
go.object.scale.multiplyScalar(wallSize) go.object.scale.multiplyScalar(wallSize)
go.object.position.multiplyScalar(wallSize) go.object.position.multiplyScalar(wallSize)
go.object.applyMatrix4(def.matrix); go.object.applyMatrix4(def.matrix);
@@ -4,7 +4,6 @@ import { assignParams } from "@/lib/MeshUtils";
class TextObject { class TextObject {
constructor(engine, obj) { constructor(engine, obj) {
console.log('OBJ', obj)
const txt = new Text(); const txt = new Text();
// Set properties to configure: // Set properties to configure:
txt.text = obj.text; txt.text = obj.text;
@@ -2,12 +2,11 @@ import * as THREE from 'three';
class VideoPlayer { class VideoPlayer {
constructor(engine, src){ constructor(engine, src, path = ''){
let vi, plane, data; let vi, plane;
return new Promise((resolve, reject)=>{
this.ready = new Promise((resolve, reject)=>{
vi = document.createElement('video'); vi = document.createElement('video');
vi.src = src; vi.src = path + src;
vi.addEventListener('loadedmetadata', ()=>{ vi.addEventListener('loadedmetadata', ()=>{
this.aspect = vi.videoWidth / vi.videoHeight; this.aspect = vi.videoWidth / vi.videoHeight;
let geometry = new THREE.PlaneGeometry( this.aspect, 1 ); let geometry = new THREE.PlaneGeometry( this.aspect, 1 );
@@ -23,23 +22,27 @@ class VideoPlayer {
plane = new THREE.Mesh( geometry, material ); plane = new THREE.Mesh( geometry, material );
this.object = plane; this.object = plane;
engine.clickable.add(plane, ()=>{ engine.clickable.add(plane, ()=>{
material.opacity = 1
if (vi.paused){ if (vi.paused){
vi.play(); vi.play();
}else{ }else{
vi.pause(); vi.pause();
} }
}); });
vi.addEventListener('play', ()=>{
material.opacity = 1
if (engine.dashboard?.active){
engine.dashboard.attach(plane);
}
})
vi.addEventListener('pause', ()=>{
material.opacity = 0.5;
engine.dashboard?.detach(plane);
})
this.video = vi;
resolve(this); resolve(this);
}) })
vi.addEventListener('play', ()=>{
if (engine.dashboard?.active){
engine.dashboard.attach(plane);
}
})
vi.addEventListener('pause', ()=>{
engine.dashboard?.detach(plane);
})
}) })
} }
} }
@@ -5,7 +5,7 @@
<div class="text-caption text-center">{{ modelValue.title }}</div> <div class="text-caption text-center">{{ modelValue.title }}</div>
</v-card-item> </v-card-item>
</v-card> </v-card>
<asset-selector @select="assignVideoObject" :type="['Descriptive']"> <asset-selector @select="assignVideoObject" :type="['Video']">
<template v-slot:activator="props"> <template v-slot:activator="props">
<v-btn v-bind="props" prepend-icon="mdi-video-box" color="deep-orange-darken-4" block>Choose video object</v-btn> <v-btn v-bind="props" prepend-icon="mdi-video-box" color="deep-orange-darken-4" block>Choose video object</v-btn>
</template> </template>
+10
View File
@@ -23,6 +23,13 @@
</template> </template>
</asset-selector> </asset-selector>
<v-img v-if="modelValue.intro" :src="`/asset/thumb/${modelValue.intro}.webp`" />
<asset-selector @select="assignIntro" :type="['Video']">
<template v-slot:activator="props">
<v-btn v-bind="props" prepend-icon="mdi-filmstrip" block color="deep-orange-darken-4" class="my-4">Select introduction</v-btn>
</template>
</asset-selector>
<v-form class="py-4"> <v-form class="py-4">
<v-text-field density="compact" :label="l.name" v-model="modelValue.title"></v-text-field> <v-text-field density="compact" :label="l.name" v-model="modelValue.title"></v-text-field>
<v-textarea :label="l.description" v-model="modelValue.description"></v-textarea> <v-textarea :label="l.description" v-model="modelValue.description"></v-textarea>
@@ -78,6 +85,9 @@ export default {
this.modelValue.title = e.name this.modelValue.title = e.name
} }
}, },
assignIntro(e){
this.modelValue.intro = e.id;
},
} }
} }
</script> </script>
+1 -1
View File
@@ -11,7 +11,7 @@
</g> </g>
</teleport> </teleport>
<v-card v-if="selected" :title="modelValue.title" class="mx-2" variant="text"> <v-card v-if="selected" :title="modelValue.title" class="mx-2" variant="text">
<asset-selector @select="assignTaskIntro" :type="['Descriptive']"> <asset-selector @select="assignTaskIntro" :type="['Video']">
<template v-slot:activator="props"> <template v-slot:activator="props">
<v-btn v-bind="props" prepend-icon="mdi-panorama-outline" color="success" block>Choose task description</v-btn> <v-btn v-bind="props" prepend-icon="mdi-panorama-outline" color="success" block>Choose task description</v-btn>
</template> </template>
+11 -4
View File
@@ -1,4 +1,5 @@
import { InteractiveObject } from '@/components/InteractiveObjects/InteractiveObject'; import { InteractiveObject } from '@/components/InteractiveObjects/InteractiveObject';
import { VideoPlayer } from '@/components/InteractiveObjects/VideoPlayer';
import { GameEngine } from '@/lib/GameEngine'; import { GameEngine } from '@/lib/GameEngine';
import { Hero } from '@/lib/Hero'; import { Hero } from '@/lib/Hero';
import { autoScale } from '@/lib/MeshUtils'; import { autoScale } from '@/lib/MeshUtils';
@@ -98,7 +99,7 @@ export default {
async expandScenarioData(scene){ async expandScenarioData(scene){
const promises = []; const promises = [];
['environment', 'scene'].filter(e=>scene.data[e]).forEach(e=>{ ['environment', 'scene', 'intro'].filter(e=>scene.data[e]).forEach(e=>{
promises.push(this.$api.gameObject.load(scene.data[e]).then(r=>scene.data['$'+e] = r.data)) promises.push(this.$api.gameObject.load(scene.data[e]).then(r=>scene.data['$'+e] = r.data))
}) })
@@ -124,13 +125,19 @@ export default {
} }
if (this.scene.data.$scene){ if (this.scene.data.$scene){
let env = await gameEngine.load(this.scene.data.$scene.asset.name); let env = await gameEngine.load(this.scene.data.$scene.asset.name);
//console.log('ENV', env)
this.setObjectAttributes(l, this.scene.data, env.scene, env, 100); this.setObjectAttributes(l, this.scene.data, env.scene, env, 100);
gameEngine.activeObjects.add(env.scene); gameEngine.activeObjects.add(env.scene);
} }
if (this.scene.data.$intro && this.env == 'GamePlaying'){
let intro = await new VideoPlayer(gameEngine, this.scene.data.$intro.asset.name, gameEngine.assetPath);
gameEngine.activeObjects.add(intro.object);
intro.video.addEventListener('pause',()=>{
intro.object.removeFromParent();
});
intro.video.play();
}
for (let i of this.scene.data.items || []) { for (let i of this.scene.data.items || []) {
let io = new InteractiveObject(gameEngine, i.data) let io = await new InteractiveObject(gameEngine, i.data)
await io.ready;
//let gltf = await gameEngine.load(`/asset/default/${i.data.$go.asset.name}`); //let gltf = await gameEngine.load(`/asset/default/${i.data.$go.asset.name}`);
//console.log(i.data, io.object) //console.log(i.data, io.object)
+1 -1
View File
@@ -33,7 +33,7 @@ export default {
}, { }, {
value: 'video', value: 'video',
icon: 'filmstrip', icon: 'filmstrip',
type: 'Descriptive', type: 'Video',
color: 'deep-orange-darken-4' color: 'deep-orange-darken-4'
}, { }, {
value: 'audio', value: 'audio',