#72 epic refactoring
This commit is contained in:
@@ -1,320 +0,0 @@
|
||||
import { InteractiveObject } from '@/components/InteractiveObjects/InteractiveObject';
|
||||
import { VideoPlayer } from '@/components/InteractiveObjects/VideoPlayer';
|
||||
import { GameEngine } from '@/lib/GameEngine';
|
||||
import { Hero } from '@/lib/Hero';
|
||||
import { autoScale, getBoundingBox, getBoundingBoxSize } from '@/lib/MeshUtils';
|
||||
let engine = null;
|
||||
|
||||
export default {
|
||||
|
||||
async mounted(){
|
||||
engine = new GameEngine();
|
||||
await engine.init(this.$refs.target, {
|
||||
xr: true,
|
||||
gizmo: this.env == 'GameDesigner',
|
||||
stats: this.env != 'GamePlay',
|
||||
designMode: this.env == 'GameDesigner',
|
||||
depthSense: this.env == 'GameDesigner' ? false : this.store.prefs.xr.depthSense,
|
||||
telemetry: this.$api.user.tm,
|
||||
mode: this.env
|
||||
});
|
||||
//engine.scene.add(new engine.$.GridHelper(100,100));
|
||||
this.resize();
|
||||
|
||||
if (!this.scenario) {
|
||||
await this.loadScenario();
|
||||
}
|
||||
window.addEventListener('resize', this.resize);
|
||||
},
|
||||
|
||||
async unmounted(){
|
||||
this.debug('Disposing scene')
|
||||
window.removeEventListener('resize', this.resize);
|
||||
engine.tm?.setGame(null);
|
||||
engine.dispose();
|
||||
this.debug('Disposed scene', engine.renderer.info.memory);
|
||||
engine = null;
|
||||
},
|
||||
|
||||
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){
|
||||
engine.transformControls.setMode(n)
|
||||
},
|
||||
currentObject(n){
|
||||
if (this.env == 'GameDesigner'){
|
||||
engine.transformControls.attach(n.__o);
|
||||
engine.gizmo.target = n.__o.position;
|
||||
engine.camera.updateProjectionMatrix()
|
||||
}
|
||||
},
|
||||
renderType(v){
|
||||
engine.renderType = v;
|
||||
},
|
||||
cameraType(v){
|
||||
if (v == 'perspective'){
|
||||
engine.setCameraPerspective();
|
||||
}else{
|
||||
engine.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 = [];
|
||||
['environment', 'scene', 'intro', 'audio'].filter(e=>scene.data[e]).forEach(e=>{
|
||||
promises.push(this.$api.gameObject.load(scene.data[e]).then(r=>scene.data['$'+e] = r.data))
|
||||
})
|
||||
|
||||
for (let i of scene.data.items || []) {
|
||||
Object.keys(i.data).filter(k=>k == 'go' || k.startsWith('go_')).forEach(k=>{
|
||||
promises.push(this.$api.gameObject.load(i.data[k]).then(r=>i.data['$'+k] = 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){
|
||||
this.debug('loading environment');
|
||||
engine.tm?.setGame(this.object?.id);
|
||||
//await engine.loadPanorama(`/asset/default/43.webp`);
|
||||
let intro;
|
||||
await engine.resetScene();
|
||||
engine.activeObjects.visible = false;
|
||||
await engine.dashboard?.ready;
|
||||
engine.dashboard?.initScene(scene, async ()=>{
|
||||
if (this.scene.data.$audio){
|
||||
await engine.playAmbientSound(this.scene.data.$audio.asset.name);
|
||||
engine.ambientSound.setVolume( 0.5 );
|
||||
}
|
||||
engine.tm?.setScene(scene.data.id);
|
||||
if (intro){
|
||||
intro.play();
|
||||
}else{
|
||||
engine.activeObjects.visible = true;
|
||||
}
|
||||
});
|
||||
await this.expandScenarioData(scene);
|
||||
engine.dashboard?.loading(0.05);
|
||||
|
||||
//engine.orbitControls.enableRotate = this.env == 'GameDesigner'
|
||||
|
||||
//this is needed cause when mounted canvas has different size
|
||||
this.resize();
|
||||
target.objects = target.objects || {};
|
||||
let l = target.objects;
|
||||
if (this.scene.data.$environment){
|
||||
this.debug('loading panorama', this.scene.data.$environment.asset.name)
|
||||
await engine.loadPanorama(this.scene.data.$environment.asset.name);
|
||||
}
|
||||
if (this.scene.data.$scene){
|
||||
let env = await engine.load(this.scene.data.$scene.asset.name);
|
||||
this.setObjectAttributes(l, this.scene.data, env.scene, env, null);
|
||||
if (this.env != 'GameDesigner'){
|
||||
env.scene.traverse(o=>{
|
||||
if (o.name.startsWith('land') || o.name == 'Sphere'){
|
||||
this.debug('Fixing ground. TODO!!!')
|
||||
engine.physics.add(o, 'fixed', true, undefined, 'mesh', { root: env.scene})
|
||||
}
|
||||
})
|
||||
}
|
||||
engine.activeObjects.add(env.scene);
|
||||
}
|
||||
let expectToFinish = 0, finished = 0;;
|
||||
if (this.scene.data.items){
|
||||
let loaded = 0;
|
||||
for (let i of this.scene.data.items) {
|
||||
this.debug('Loading', i.data.id);
|
||||
if (this.env != 'GameDesigner'){
|
||||
if (i.data.activationTriggers?.length || i.data.activationScore){
|
||||
i.data.shouldBeLocked = true;
|
||||
}
|
||||
}
|
||||
let io = await new InteractiveObject(engine, i.data)
|
||||
i.__io = io;
|
||||
if (io.emits?.includes('finish')){
|
||||
expectToFinish++;
|
||||
}
|
||||
this.setObjectAttributes(l, i.data, io.object, io.source, 1);
|
||||
engine.activeObjects.add(io.object);
|
||||
if (this.env != 'GameDesigner'){
|
||||
if (i.data.$go?.type == 'player3d'){
|
||||
let hero = new Hero(engine, io);
|
||||
}else{
|
||||
if (io.source?.animations?.length){
|
||||
engine.playAnimation(engine.scene, io.source.animations[0]);
|
||||
}
|
||||
|
||||
if (!i.data.noPhysics){
|
||||
let bb = getBoundingBox(io.object);
|
||||
let bbs = getBoundingBoxSize(bb);
|
||||
engine.physics.add(io.object, 'fixed', false, undefined, 'capsule', {
|
||||
radius: Math.max(bbs.x, bbs.z)/2, halfHeight: bbs.y/2
|
||||
})
|
||||
}
|
||||
}
|
||||
io.addEventListener('finish', ()=>{
|
||||
finished ++;
|
||||
if (!i.data.pointsGiven){
|
||||
engine.dashboard?.addPoints(i.data.points)
|
||||
}
|
||||
i.data.pointsGiven = true;
|
||||
this.scene.data.items.forEach(di=>{
|
||||
if (di.data.activationTriggers?.includes(i.data.id)){
|
||||
let idx = di.data.activationTriggers.indexOf(i.data.id)
|
||||
di.data.activationTriggers.splice(idx, 1);
|
||||
}
|
||||
if (!di.data.activationTriggers?.length && di.__io.object.__active === false &&
|
||||
engine.dashboard.points > di.data.activationScore){
|
||||
di.__io.activator.activate();
|
||||
}
|
||||
});
|
||||
if (finished == expectToFinish){
|
||||
//GO TO NEXT LEVEL
|
||||
this.debug('LEVEL FINISHED')
|
||||
}
|
||||
engine.tm?.setGameObject(null);
|
||||
});
|
||||
io.addEventListener('sceneSwitch', (e)=>{
|
||||
this.scenesList = [this.scenes.find(s=>s.data.id == e.scene)]
|
||||
})
|
||||
}
|
||||
loaded += 1/this.scene.data.items.length
|
||||
engine.dashboard?.loading(0.1 + 0.89*loaded);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.env == 'GameDesigner'){
|
||||
engine.activeObjects.visible = true;
|
||||
}else if (this.scene.data.$intro){
|
||||
intro = await new VideoPlayer(engine, {
|
||||
$go: this.scene.data.$intro,
|
||||
skipTransition: true,
|
||||
playInHud: true,
|
||||
immersive: true
|
||||
});
|
||||
engine.activeObjects.add(intro.object);
|
||||
intro.video.addEventListener('pause',()=>{
|
||||
intro.object.removeFromParent();
|
||||
engine.clickable.remove(intro.object); //TODO!!!!
|
||||
engine.activeObjects.visible = true;
|
||||
});
|
||||
}
|
||||
|
||||
engine.dashboard?.loading(1)
|
||||
engine.physics.start();
|
||||
this.debug('Scene loaded', engine.renderer.info.memory)
|
||||
},
|
||||
|
||||
targetPointerDown(){
|
||||
this.pointerDownTime = performance.now();
|
||||
},
|
||||
targetClick(e){
|
||||
if (this.env == 'GameDesigner'){
|
||||
if (performance.now() - this.pointerDownTime < 200){
|
||||
let intersects = engine.intersect(e, this.$refs.target, engine.activeObjects.children, true);
|
||||
//console.log(intersects)
|
||||
if (intersects.length){
|
||||
//console.log('attaching controls to', intersects[0].object)
|
||||
//engine.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{
|
||||
engine.transformControls.detach();
|
||||
}
|
||||
}
|
||||
}else{
|
||||
engine.onClick(e, this.$refs.target);
|
||||
}
|
||||
},
|
||||
|
||||
targetPointer(e, t){
|
||||
engine.onPointer(e, this.$refs.target, t);
|
||||
},
|
||||
|
||||
setObjectAttributes(l, data, object, source, autoScaleFactor = 1){
|
||||
if (l[data.id]){
|
||||
['position', 'scale', 'rotation'].forEach(p=>{
|
||||
object[p].copy(l[data.id][p])
|
||||
})
|
||||
}else if (!data.type || data.type == 'GenericObject'){
|
||||
autoScale(object, autoScaleFactor);
|
||||
}
|
||||
l[data.id] = l[data.id] || {};
|
||||
['position', 'scale', 'rotation', 'visible'].forEach(p=>{
|
||||
l[data.id][p] = object[p];
|
||||
})
|
||||
l[data.id].__o = object;
|
||||
l[data.id].__g = source;
|
||||
l[data.id].__title = data.title;
|
||||
object.__pn_id = data.id;
|
||||
},
|
||||
|
||||
async toggleAnimation(animation){
|
||||
animation.playing = !animation.playing;
|
||||
engine.playAnimation(engine.scene, animation.a, animation.playing);
|
||||
},
|
||||
resize(){
|
||||
let r = this.$refs.target;
|
||||
this.debug('resizing!!', r.clientWidth, r.clientHeight, r)
|
||||
engine.resize(r.clientWidth, r.clientHeight);
|
||||
//this.zoom = Math.min(r.clientWidth / this.viewBox.w, r.clientHeight / this.viewBox.h);
|
||||
},
|
||||
|
||||
control(){
|
||||
engine.pointerControls.lock(true);
|
||||
},
|
||||
|
||||
async fullScreen(){
|
||||
await engine.renderer.domElement.requestFullscreen()
|
||||
},
|
||||
|
||||
async setGameHeader(){
|
||||
let screenshot = await engine.captureScreenshot();
|
||||
let fd = new FormData();
|
||||
fd.append('file', screenshot);
|
||||
await this.$api.game.setHeader(this.modelValue.id, fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user