video player as interactive object + move to HUD
This commit is contained in:
@@ -65,11 +65,8 @@
|
||||
|
||||
<script>
|
||||
|
||||
import { GameEngine } from '@/lib/GameEngine';
|
||||
import GameEnvironmentMixin from '@/mixins/GameEnvironmentMixin';
|
||||
|
||||
let gameEngine = null;
|
||||
|
||||
export default {
|
||||
mixins: [GameEnvironmentMixin],
|
||||
props:{
|
||||
|
||||
@@ -52,12 +52,7 @@
|
||||
|
||||
<script>
|
||||
|
||||
import { GameEngine } from '@/lib/GameEngine';
|
||||
import { Hero } from '@/lib/Hero';
|
||||
import { Grass } from '@/components/InteractiveObjects/Grass';
|
||||
import { VideoPlayer } from '@/components/InteractiveObjects/VideoPlayer';
|
||||
import { useAppStore } from '@/stores/app';
|
||||
import { MazeQuizGame } from '../InteractiveObjects/MazeQuizGame/MazeQuizGame';
|
||||
|
||||
import GameEnvironmentMixin from '@/mixins/GameEnvironmentMixin';
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import { PuzzleGame4 } from "./PuzzleGame4";
|
||||
// import { Game6 } from "./games/Game6";
|
||||
import { TextObject } from "./TextObject";
|
||||
import { ImageObject } from "./ImageObject";
|
||||
import { VideoPlayer } from "./VideoPlayer";
|
||||
|
||||
const games = {PuzzleGame1, PuzzleGame2, PuzzleGame4};
|
||||
|
||||
@@ -18,7 +19,7 @@ class InteractiveObject {
|
||||
this.name = obj.name;
|
||||
this.ready = new Promise((resolve, reject) => {
|
||||
let mesh;
|
||||
switch (obj.type) {
|
||||
switch (obj.id) {
|
||||
case 'group':
|
||||
mesh = new Group();
|
||||
obj.group.forEach(g => {
|
||||
@@ -48,7 +49,7 @@ class InteractiveObject {
|
||||
resolve(mesh);
|
||||
break;
|
||||
case 'gltf':
|
||||
console.log('loadingg', obj.value)
|
||||
//console.log('loadingg', obj.value)
|
||||
new GLTFLoader().load(obj.value, (gltf) => {
|
||||
let gltfObj = gltf.scene;
|
||||
gltf.scene.traverse(function (object) {
|
||||
@@ -81,11 +82,15 @@ class InteractiveObject {
|
||||
case 'PuzzleGame4':
|
||||
case 'PuzzleGame5':
|
||||
case 'PuzzleGame6':
|
||||
var game = new games[obj.type](context, obj.args[0], obj.args[1], obj.args[2]);
|
||||
let game = new games[obj.type](context, obj.args[0], obj.args[1], obj.args[2]);
|
||||
mesh = game.object;
|
||||
mesh.game = game;
|
||||
resolve(mesh);
|
||||
break;
|
||||
case 'VideoPlayer':
|
||||
let vp = new VideoPlayer(context, `/asset/default/${obj.$go.asset.name}`);
|
||||
vp.ready.then(resolve);
|
||||
break;
|
||||
}
|
||||
});
|
||||
this.ready.then((mesh) => {
|
||||
@@ -137,6 +142,6 @@ const InteractiveObjectTypes = [
|
||||
}, {
|
||||
id: 'VideoPlayer', name: 'Video Player'
|
||||
}
|
||||
]
|
||||
];
|
||||
|
||||
export { InteractiveObject, InteractiveObjectTypes }
|
||||
@@ -2,28 +2,78 @@ import * as THREE from 'three';
|
||||
|
||||
|
||||
class VideoPlayer {
|
||||
constructor(context, video, w, h){
|
||||
let geometry = new THREE.PlaneGeometry( w, h );
|
||||
let map = new THREE.VideoTexture( video );
|
||||
map.colorSpace = THREE.SRGBColorSpace;
|
||||
let material = new THREE.MeshStandardMaterial( {
|
||||
color: 0xffffff,
|
||||
map,
|
||||
transparent: true,
|
||||
opacity: 0.5,
|
||||
} );
|
||||
let plane = new THREE.Mesh( geometry, material );
|
||||
this.object = plane;
|
||||
constructor(context, src){
|
||||
let vi, plane, data;
|
||||
|
||||
context.clickable.add(plane, ()=>{
|
||||
material.opacity = 0.9
|
||||
if (video.paused){
|
||||
video.play();
|
||||
}else{
|
||||
video.pause();
|
||||
}
|
||||
});
|
||||
this.ready = new Promise((resolve, reject)=>{
|
||||
vi = document.createElement('video');
|
||||
vi.src = src;
|
||||
vi.addEventListener('loadedmetadata', ()=>{
|
||||
this.aspect = vi.videoWidth / vi.videoHeight;
|
||||
let geometry = new THREE.PlaneGeometry( this.aspect, 1 );
|
||||
let map = new THREE.VideoTexture( vi );
|
||||
map.colorSpace = THREE.SRGBColorSpace;
|
||||
let material = new THREE.MeshStandardMaterial( {
|
||||
color: 0xffffff,
|
||||
map,
|
||||
transparent: true,
|
||||
opacity: 0.5,
|
||||
side: THREE.DoubleSide
|
||||
} );
|
||||
plane = new THREE.Mesh( geometry, material );
|
||||
this.object = plane;
|
||||
context.clickable.add(plane, ()=>{
|
||||
material.opacity = 1
|
||||
if (vi.paused){
|
||||
vi.play();
|
||||
}else{
|
||||
vi.pause();
|
||||
}
|
||||
});
|
||||
resolve(plane);
|
||||
})
|
||||
vi.addEventListener('play', ()=>{
|
||||
if (context.dashboard?.active){
|
||||
//console.log(plane);
|
||||
// plane.matrix.multiply(context.dashboard.group.matrix)
|
||||
// plane.applyMatrix4(plane.matrix)
|
||||
|
||||
// let m1 = plane.matrix.clone(), m2 = context.dashboard.group.matrix.clone();
|
||||
// let m = m1.premultiply(m2);
|
||||
data = {
|
||||
parent: plane.parent,
|
||||
location: {
|
||||
position: plane.position.clone(),
|
||||
quaternion: plane.quaternion.clone(),
|
||||
scale: plane.scale.clone()
|
||||
}
|
||||
}
|
||||
console.log(data.location)
|
||||
context.dashboard.group.attach(plane);
|
||||
//plane.applyMatrix4(m.invert())
|
||||
|
||||
|
||||
context.motionQueue.add({
|
||||
o: plane,
|
||||
a: {
|
||||
rotation: { x:0, y:0, z:0 },
|
||||
position: { x:0, y:0, z:-0.25 },
|
||||
scale: { x: 1, y:1, z:1 }
|
||||
},
|
||||
t: 1
|
||||
})
|
||||
}
|
||||
})
|
||||
vi.addEventListener('pause', ()=>{
|
||||
data.parent.attach(plane);
|
||||
context.motionQueue.add({
|
||||
o: plane,
|
||||
a: data.location,
|
||||
t: 1
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export {VideoPlayer}
|
||||
export { VideoPlayer }
|
||||
@@ -29,6 +29,8 @@ class DashBoard {
|
||||
})
|
||||
|
||||
const dash = new Group();
|
||||
this.group = dash;
|
||||
dash.visible = false;
|
||||
|
||||
const dashGeometry = new PlaneGeometry(engine.aspect, 1);
|
||||
const dashMesh = new Mesh(dashGeometry, new MeshStandardMaterial({
|
||||
@@ -81,9 +83,25 @@ class DashBoard {
|
||||
progressCylinder.position.x = padLeft - engine.aspect/2 + progressCylinder.scale.y/2
|
||||
}
|
||||
|
||||
this.enable = ()=>{
|
||||
dash.visible = true;
|
||||
}
|
||||
|
||||
this.disable = ()=>{
|
||||
dash.visible = false;
|
||||
}
|
||||
|
||||
this.createProgressBar();
|
||||
this.update();
|
||||
}
|
||||
|
||||
get active(){
|
||||
return this.group.visible;
|
||||
}
|
||||
|
||||
set active(v){
|
||||
this.group.visible = v;
|
||||
}
|
||||
}
|
||||
|
||||
export { DashBoard };
|
||||
@@ -14,6 +14,7 @@ import { XRControllerModelFactory } from 'three/addons/webxr/XRControllerModelFa
|
||||
import { Physics } from './Physics.js';
|
||||
import { Clickable } from './Clickable.js';
|
||||
import { DashBoard } from './Dashboard.js';
|
||||
import { MotionEngine } from './MotionEngine.js';
|
||||
|
||||
class GameEngine extends THREE.EventDispatcher{
|
||||
async init(domNode, opts = {}) {
|
||||
@@ -99,6 +100,8 @@ class GameEngine extends THREE.EventDispatcher{
|
||||
const dashboard = new DashBoard(this);
|
||||
this.dashboard = dashboard;
|
||||
|
||||
this.motionQueue = new MotionEngine();
|
||||
|
||||
this.activeObjects = new THREE.Group();
|
||||
scene.add(this.activeObjects);
|
||||
|
||||
@@ -129,8 +132,8 @@ class GameEngine extends THREE.EventDispatcher{
|
||||
gameEngine.hero?.update();
|
||||
gameEngine.mixers.forEach(m => m.update(delta));
|
||||
gameEngine.handleXrAction(gameEngine, delta)
|
||||
|
||||
gameEngine.dispatchEvent({type: 'beforeRender'})
|
||||
this.motionQueue.update();
|
||||
|
||||
gameEngine.render(scene, gameEngine.camera);
|
||||
if (!renderer.xr.isPresenting) {
|
||||
@@ -140,7 +143,7 @@ class GameEngine extends THREE.EventDispatcher{
|
||||
// dashboard.render();
|
||||
// renderer.autoClear = true;
|
||||
}
|
||||
renderer.setAnimationLoop(animate);
|
||||
renderer.setAnimationLoop(animate.bind(this));
|
||||
|
||||
const mixer = new THREE.AnimationMixer(this.scene);
|
||||
const clock = new THREE.Clock();
|
||||
@@ -162,7 +165,7 @@ class GameEngine extends THREE.EventDispatcher{
|
||||
// scene.background = bck; //new THREE.Color(0.7,0.7,0.7);
|
||||
scene.environment = texture;
|
||||
scene.background = new THREE.Color(1, 1, 1);
|
||||
console.log('GameEngine started')
|
||||
//console.log('GameEngine started')
|
||||
renderer.domElement.addEventListener('wheel', (event) => {
|
||||
gameEngine.camera.zoom -= event.deltaY / 1000;
|
||||
gameEngine.camera.zoom = Math.max(gameEngine.camera.zoom, .4);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { InteractiveObject } from '@/components/InteractiveObjects/InteractiveObject';
|
||||
import { GameEngine } from '@/lib/GameEngine';
|
||||
import { Hero } from '@/lib/Hero';
|
||||
let gameEngine = null;
|
||||
@@ -13,8 +14,12 @@ export default {
|
||||
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));
|
||||
if (this.env == 'GameDesigner'){
|
||||
gameEngine.scene.add(gameEngine.transformControls.getHelper());
|
||||
}else{
|
||||
gameEngine.dashboard.enable();
|
||||
}
|
||||
this.resize();
|
||||
//gameEngine.setCamera(gameEngine.orthographicCamera)
|
||||
//gameEngine.setCameraOrthographic();
|
||||
@@ -63,10 +68,11 @@ export default {
|
||||
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()
|
||||
if (this.env == 'GameDesigner'){
|
||||
gameEngine.transformControls.attach(n.__o);
|
||||
gameEngine.gizmo.target = n.__o.position;
|
||||
gameEngine.camera.updateProjectionMatrix()
|
||||
}
|
||||
},
|
||||
renderType(v){
|
||||
gameEngine.renderType = v;
|
||||
@@ -124,7 +130,11 @@ export default {
|
||||
}
|
||||
for (let i of this.scene.data.items || []) {
|
||||
if (i.data.io){
|
||||
|
||||
i.data.$io = new InteractiveObject(i.data.io, gameEngine)
|
||||
i.data.$io.ready.then(o=>{
|
||||
this.setObjectAttributes(l, i.data, { scene: o }, 1);
|
||||
gameEngine.activeObjects.add(o);
|
||||
})
|
||||
}else{
|
||||
let gltf = await gameEngine.load(`/asset/default/${i.data.$go.asset.name}`);
|
||||
this.setObjectAttributes(l, i.data, gltf, 1);
|
||||
@@ -156,17 +166,21 @@ export default {
|
||||
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();
|
||||
if (this.env == 'GameDesigner'){
|
||||
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();
|
||||
}
|
||||
}
|
||||
}else{
|
||||
gameEngine.onClick(e, this.$refs.target);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user