UNPKG

matrix-engine-wgpu

Version:

Networking implemented - based on kurento openvidu server. fix arcball camera,instanced draws added also effect pipeline blend with instancing option.Normalmap added, Fixed shadows casting vs camera/video texture, webGPU powered pwa application. Crazy fas

303 lines (275 loc) 11.3 kB
import {uploadGLBModel} from "../../../src/engine/loaders/webgpu-gltf"; import {LOG_FUNNY, LOG_MATRIX} from "../../../src/engine/utils"; import {Hero} from "./hero"; import {startUpPositions} from "./static"; export class Creep extends Hero { heroAnimationArrange = { dead: null, walk: null, salute: null, attack: null, idle: null } creepFocusAttackOn = null; constructor(o, archetypes = ["creep"], group = "enemy", team) { super(o.name, archetypes); this.name = o.name; this.core = o.core; this.group = group; this.team = team; this.loadCreep(o); return this; } loadCreep = async (o) => { this.o = o; try { var glbFile01 = await fetch(o.path).then(res => res.arrayBuffer().then(buf => uploadGLBModel(buf, this.core.device))); this.core.addGlbObjInctance({ material: {type: 'standard', useTextureFromGlb: true}, scale: [20, 20, 20], position: o.position, name: o.name, texturesPaths: ['./res/meshes/glb/textures/mutant_origin.png'], raycast: {enabled: true, radius: 1.1}, pointerEffect: { enabled: true, energyBar: true } }, null, glbFile01); // make small async - cooking glbs files this.asyncHelper(this.o).then(() => { console.log('good') }).catch(() => { console.log('catch') setTimeout(() => {this.asyncHelper(this.o);}, 3000); }); } catch(err) {throw err;} } asyncHelper = async (o) => { return new Promise((resolve, reject) => { setTimeout(() => { this.heroe_bodies = app.mainRenderBundle.filter(obj => obj.name && obj.name.includes(o.name)); if(this.heroe_bodies.length == 0 || this.core.net.session == null ) { reject(); return; } this.heroe_bodies.forEach((subMesh, idx) => { subMesh.position.thrust = this.moveSpeed; subMesh.glb.animationIndex = 0; // adapt manual if blender is not setup subMesh.glb.glbJsonData.animations.forEach((a, index) => { // console.info(`%c Animation loading for creeps: ${a.name} index ${index}`, LOG_MATRIX) if(a.name == 'dead') this.heroAnimationArrange.dead = index; if(a.name == 'walk') this.heroAnimationArrange.walk = index; if(a.name == 'salute') this.heroAnimationArrange.salute = index; if(a.name == 'attack') this.heroAnimationArrange.attack = index; if(a.name == 'idle') this.heroAnimationArrange.idle = index; }); // adapt subMesh.globalAmbient = [1, 1, 1, 1]; if(this.name.indexOf('friendly_creeps') != -1) { subMesh.globalAmbient = [12, 12, 12, 1]; } else if(this.name.indexOf('enemy_creep') != -1) { subMesh.globalAmbient = [12, 1, 1, 1]; } if(this.group == 'friendly' && this.name.indexOf('friendly_creeps') != -1) { if(idx == 0) { if(this.core.net.virtualEmiter == this.core.net.session.connection.connectionId) { subMesh.position.teams[0] = app.player.remoteByTeam[app.player.data.team]; subMesh.position.teams[1] = app.player.remoteByTeam[app.player.data.enemyTeam]; subMesh.position.netObject = subMesh.name; let t = subMesh.name.replace('friendly_creeps', 'enemy_creep'); subMesh.position.remoteName = t; subMesh.rotation.teams[0] = app.player.remoteByTeam[app.player.data.team]; subMesh.rotation.teams[1] = app.player.remoteByTeam[app.player.data.enemyTeam]; subMesh.rotation.emitY = subMesh.name; subMesh.rotation.remoteName = t; subMesh.sharedState.emitAnimationEvent = true; } } } if(idx == 0) this.core.collisionSystem.register((o.name), subMesh.position, 15.0, this.group); }); this.setStartUpPosition(); this.attachEvents(); resolve(); setTimeout(() => { if(this.core.net.virtualEmiter != null) { console.info(`%c virtualEmiter navigateCreeps : `, LOG_MATRIX) app.localHero.navigateCreeps(); } }, 3000); }, 9000); }) } setWalk() { this.heroe_bodies.forEach(subMesh => { subMesh.glb.animationIndex = this.heroAnimationArrange.walk; console.info(`%chero walk`, LOG_MATRIX) }); } setSalute() { this.heroe_bodies.forEach(subMesh => { subMesh.glb.animationIndex = this.heroAnimationArrange.salute; console.info(`%chero salute`, LOG_MATRIX) }); } setDead() { this.heroe_bodies.forEach(subMesh => { subMesh.glb.animationIndex = this.heroAnimationArrange.dead; console.info(`%chero dead`, LOG_MATRIX) }); } setIdle() { this.heroe_bodies.forEach(subMesh => { subMesh.glb.animationIndex = this.heroAnimationArrange.idle; console.info(`%chero idle`, LOG_MATRIX) }); } setAttack() { this.heroe_bodies.forEach(subMesh => { subMesh.glb.animationIndex = this.heroAnimationArrange.attack; console.info(`%chero attack`, LOG_MATRIX) }); } setStartUpPosition() { if(this.group == 'enemy') { this.heroe_bodies.forEach((subMesh, idx) => { subMesh.position.setPosition( startUpPositions[this.core.player.data.enemyTeam][0], startUpPositions[this.core.player.data.enemyTeam][1], startUpPositions[this.core.player.data.enemyTeam][2]); }); } else { this.heroe_bodies.forEach((subMesh, idx) => { subMesh.position.setPosition( startUpPositions[this.core.player.data.team][0], startUpPositions[this.core.player.data.team][1], startUpPositions[this.core.player.data.team][2]); }); } } setStartUpPosCreep() { if(this.group == 'enemy') { this.heroe_bodies.forEach((subMesh, idx) => { subMesh.position.setPosition( startUpPositions[this.core.player.data.enemyTeam][0], startUpPositions[this.core.player.data.enemyTeam][1], startUpPositions[this.core.player.data.enemyTeam][2]); }); } else { this.heroe_bodies.forEach((subMesh, idx) => { subMesh.position.setPosition( startUpPositions[this.core.player.data.team][0], startUpPositions[this.core.player.data.team][1], startUpPositions[this.core.player.data.team][2]); }); } } attachEvents() { addEventListener(`onDamage-${this.name}`, (e) => { if(this.group == 'enemy') { console.info(`%c onDamage-${this.name} group: ${this.group} creep damage!`, LOG_FUNNY); } else { console.log('friendly creep damage must come from net. [never]'); return; } this.heroe_bodies[0].effects.energyBar.setProgress(e.detail.progress); this.core.net.sendOnlyData({ type: "damage-creep", defenderName: e.detail.defender, defenderTeam: this.team, hp: e.detail.hp, progress: e.detail.progress }); if(e.detail.progress == 0) { this.setDead(); console.info(`%c Creep dead [${this.name}], attacker[${e.detail.attacker}]`, LOG_MATRIX); setTimeout(() => { this.setStartUpPosCreep(this.name[this.name.length - 1]); this.setWalk(); this.creepFocusAttackOn = null; this.gotoFinal = false; this.setStartUpPosCreep(this.name[this.name.length - 1]); this.hp = 300; this.heroe_bodies[0].effects.energyBar.setProgress(1); app.localHero.setWalkCreep(this.name[this.name.length - 1]); dispatchEvent(new CustomEvent('navigate-friendly_creeps', {detail: 'test'})); }, 700); } }); if(this.group != 'enemy') { addEventListener(`animationEnd-${this.heroe_bodies[0].name}`, (e) => { // CHECK DISTANCE if(e.detail.animationName != 'attack') { // && this.creepFocusAttackOn == null) { return; } if(this.group == "friendly") { if(this.creepFocusAttackOn == null) { // console.info('setIdle:', e.detail.animationName) let isEnemiesClose = false; this.core.enemies.enemies.forEach((enemy) => { if(typeof enemy.heroe_bodies === 'undefined') return; let tt = this.core.RPG.distance3D( this.heroe_bodies[0].position, enemy.heroe_bodies[0].position); if(tt < this.core.RPG.distanceForAction) { // console.log(`%c ATTACK DAMAGE ${enemy.heroe_bodies[0].name}`, LOG_MATRIX) isEnemiesClose = true; this.calcDamage(this, enemy); // no need ?? this.creepFocusAttackOn = null; return; } }); this.core.enemies.creeps.forEach((creep) => { if(typeof creep.heroe_bodies === 'undefined') return; let tt = this.core.RPG.distance3D( this.heroe_bodies[0].position, creep.heroe_bodies[0].position); if(tt < this.core.RPG.distanceForAction) { // console.log(`%c ATTACK DAMAGE ${creep.heroe_bodies[0].name}`, LOG_MATRIX) isEnemiesClose = true; this.calcDamage(this, creep); // no need ?? this.creepFocusAttackOn = null; return; } }); let enemytron = this.core.RPG.distance3D( this.heroe_bodies[0].position, app.enemytron.position); if(enemytron < this.core.RPG.distanceForAction) { console.log(`%c ATTACK ENEMY TRON ${creep.heroe_bodies[0].name}`, LOG_MATRIX); isEnemiesClose = true; this.calcDamage(this, app.enemytron); return; } // if(isEnemiesClose == false) this.setIdle(); return; } else { // Focus on enemy vs creeps ! let tt; if(typeof this.creepFocusAttackOn.position !== 'undefined') { tt = this.core.RPG.distance3D( this.heroe_bodies[0].position, this.creepFocusAttackOn.position); } else { tt = this.core.RPG.distance3D( this.heroe_bodies[0].position, this.creepFocusAttackOn.heroe_bodies[0].position); } if(tt < this.core.RPG.distanceForAction) { console.log(`%c [creep] ATTACK DAMAGE ON`, LOG_MATRIX) this.calcDamage(this, this.creepFocusAttackOn); return; } else { this.creepFocusAttackOn = null; dispatchEvent(new CustomEvent('navigate-friendly_creeps', {detail: 'test'})) } } } }) } } }