allow videotexture in puzzles

This commit is contained in:
2026-02-10 22:22:44 +02:00
parent ca67773650
commit a35691fc1b
6 changed files with 57 additions and 12 deletions
@@ -1,4 +1,4 @@
import { Color, Group, DoubleSide, RepeatWrapping, MeshStandardMaterial } from "three"
import { Color, Group, DoubleSide, RepeatWrapping, MeshStandardMaterial, VideoTexture } from "three"
import { EventManager } from '@/lib/EventManager';
import { centerOrigin } from "@/lib/MeshUtils";
@@ -10,7 +10,21 @@ class ClassicPuzzle extends EventManager {
const that = this;
return new Promise(async (resolve, reject)=>{
let gltf = await engine.load(`puzzle-${data.dimension}.glb`, '/static/meshes/classic-puzzle/');
let map = await engine.loadTexture(data.$go.asset.name);
let map, vi;
if (data.$go.type == 'video'){
await new Promise((resolve, reject)=>{
vi = document.createElement('video');
vi.src = engine.assetPath + data.$go.asset.name;
vi.muted = true;
vi.addEventListener('loadedmetadata', async ()=>{
map = new VideoTexture( vi );
resolve();
});
})
}else{
map = await engine.loadTexture(data.$go.asset.name);
}
map.wrapS = RepeatWrapping;
map.wrapT = RepeatWrapping;
map.flipY = false;
@@ -21,6 +35,7 @@ class ClassicPuzzle extends EventManager {
let eventsFn= {
start(){
that.dispatchEvent({type:'interaction'});
if (vi?.paused) vi.play();
},
drag(){},
end(e){
@@ -5,7 +5,7 @@
<v-img :src="`/asset/thumb/${modelValue.go}.webp`" />
<div class="text-caption text-center">{{ modelValue.title }}</div>
</div>
<asset-selector @select="assignTexture" :type="['Texture']">
<asset-selector @select="assignTexture" :type="['Texture', 'Video']">
<template v-slot:activator="props">
<v-btn v-bind="props" prepend-icon="mdi-video-box" color="deep-orange-darken-4" block>{{ l.chooseImage }}</v-btn>
</template>
@@ -1,4 +1,4 @@
import { BoxGeometry, Mesh, MeshStandardMaterial, Group } from 'three';
import { BoxGeometry, Mesh, MeshBasicMaterial, Group, VideoTexture } from 'three';
import { centerOrigin } from '@/lib/MeshUtils';
import { EventManager } from '@/lib/EventManager';
@@ -15,8 +15,23 @@ class PuzzleGame1 extends EventManager {
let bm = new BoxGeometry(1, 1, 1);
let material = new MeshStandardMaterial({
map: await engine.loadTexture(data.$go.asset.name),
let map, vi;
if (data.$go.type == 'video'){
await new Promise((resolve, reject)=>{
vi = document.createElement('video');
vi.src = engine.assetPath + data.$go.asset.name;
vi.muted = true;
vi.addEventListener('loadedmetadata', async ()=>{
map = new VideoTexture( vi );
resolve();
});
})
}else{
map = await engine.loadTexture(data.$go.asset.name);
}
let material = new MeshBasicMaterial({
map,
// roughness:1, metalness:0,
// normalMap: await engine.loadTexture('NormalMap.png', '/static/textures/'),
});
@@ -72,6 +87,7 @@ class PuzzleGame1 extends EventManager {
let clickFn = (i) => {
this.dispatchEvent({type:'interaction'});
if (vi?.paused) vi.play();
if (!this.done && !aq.isActive(i.object)) {
i.object._ri = (i.object._ri + 1) % 6;
aq.add({
@@ -6,7 +6,7 @@
<v-img :src="`/asset/thumb/${modelValue.go}.webp`" />
<div class="text-caption text-center">{{ modelValue.title }}</div>
</div>
<asset-selector @select="assignTexture" :type="['Texture']">
<asset-selector @select="assignTexture" :type="['Texture', 'Video']">
<template v-slot:activator="props">
<v-btn v-bind="props" prepend-icon="mdi-video-box" color="deep-orange-darken-4" block>{{ l.chooseImage }}</v-btn>
</template>
@@ -1,4 +1,4 @@
import { BoxGeometry, Mesh, MeshBasicMaterial, Group } from 'three';
import { BoxGeometry, Mesh, MeshBasicMaterial, Group, VideoTexture } from 'three';
import { centerOrigin } from '@/lib/MeshUtils';
import { EventManager } from '@/lib/EventManager';
@@ -8,13 +8,26 @@ class PuzzleGame2 extends EventManager {
super();
return new Promise(async (resolve, reject)=>{
let w = data.w, h = data.h, wh = w*h;
const texture = await engine.loadTexture(data.$go.asset.name);
let map, vi;
if (data.$go.type == 'video'){
await new Promise((resolve, reject)=>{
vi = document.createElement('video');
vi.src = engine.assetPath + data.$go.asset.name;
vi.muted = true;
vi.addEventListener('loadedmetadata', async ()=>{
map = new VideoTexture( vi );
resolve();
});
})
}else{
map = await engine.loadTexture(data.$go.asset.name);
}
const material = new MeshBasicMaterial({
map: texture
map
});
const aq = engine.motionQueue;
const m2 = new MeshBasicMaterial({
map: texture,
map,
transparent: true,
opacity: 0.37
});
@@ -104,6 +117,7 @@ class PuzzleGame2 extends EventManager {
let clickFn = (i) => {
this.dispatchEvent({type:'interaction'});
if (vi?.paused) vi.play();
if (!this.done && !aq.isActive(i.object)) {
let idx = container.children.indexOf(i.object);
if (idx == lidx) return; //we ignore the empty cell
@@ -6,7 +6,7 @@
<v-img :src="`/asset/thumb/${modelValue.go}.webp`" />
<div class="text-caption text-center">{{ modelValue.title }}</div>
</div>
<asset-selector @select="assignTexture" :type="['Texture']">
<asset-selector @select="assignTexture" :type="['Texture', 'Video']">
<template v-slot:activator="props">
<v-btn v-bind="props" prepend-icon="mdi-video-box" color="deep-orange-darken-4" block>{{ l.chooseImage }}</v-btn>
</template>