/** * _ ___ Another * / |/ (_)______ __ _____ * / / / __(_- // (_-< * /_/|_/_/\__/___/\_, /___/ * /___/ * production ! * * Licensed under the MIT License: * This code is free to use and modify, * as long as the copyright notice and license are kept. */ class KeyframeView extends WindozDomContent { constructor() { super() Object.assign(this, app.helpers.activeAttributes, app.helpers.formBuilder, app.helpers.kfConsole) } DOMContentFocused(options) { if(this.wasBlured){ // Avoid 2nd refesh on DomContentLoaded //this.refreshyoustuff() } this.wasBlured = false } DOMContentBlured(options) { this.wasBlured = true } async DOMContentLoaded(options) { this.windowPrefsId = `editors.keyframeview` this.models = options.models const components = ui.eicfy(this.el) this.setupTriggers(components) this.setupRefs(components) const [sprites, types] = await Promise.all([ this.models.agents.getSprites('Basic 3D'), this.models.agents.getTypes('Test agents') ]) this.agentSprites = sprites this.agentTypes = types this.currentAgentType = null //TODO from browser this.currentKeyframe = { } this.outputs.agentsSelector.fillOptions( this.agentTypes.map(item => { return({ markup: `${item.atp_name}`, value: item.atp_id}) })) this.outputs.agentsSelector.addEventListener('change',this.onChangeAgent.bind(this)) this.agentPreview = new app.LoadedModules.AgentPreview(this.outputs.agentSampleCanvas, this.agentSprites) this.onChangeAgent() this.agentPreview.startRendering() this.agentPreview.animation = true this.models.keyframes.list('', null).then(data => data.payload).then(kflist => { this.outputs.keyframesSelector.fillOptions(kflist.map(item => { return({ markup: item.ekf_name, value: item.ekf_uuid }) })) }) this.outputs.keyframesSelector.addEventListener('change',this.onChangeKeyframe.bind(this)) this.kfArena = new app.LoadedModules.kfArena(this.outputs.kfArenaCanvas, this.agentSprites) this.kfArena.onclickAgent = this.onclickAgent.bind(this) this.kfArena.startRendering() this.outputs.btnAddAgent.disabled = true this.outputs.btnRemoveAgent.disabled = true this.outputs.btnSaveKF.disabled = true this.outputs.kfName.addEventListener('keyup', this.updateKfButtons.bind(this)) this.currentlySelectedAid = null } async onChangeAgent(event){ if(this.outputs.agentsSelector.value) this.agentPreview.setAgent(this.outputs.agentsSelector.value) if(!this.outputs.agentsSelector.value) return if(this.notUserChange) { } else { this.currentAgentType = await this.models.agents.getProperties(this.outputs.agentsSelector.value) this.fillAgentProperties('', this.currentAgentType) // Deselect any on-scene selection if(this.currentlySelectedAid){ this.kfArena.clearHighlight3DObj(this.kfArena.scene.getObjectByName(this.currentlySelectedAid), this.kfArena.scene) } this.currentlySelectedAid = null } } async onChangeKeyframe(event){ if(!this.outputs.keyframesSelector.value) return let kfData = await this.models.keyframes.getKeyframe(this.outputs.keyframesSelector.value).then(data => data.payload) this.currentKeyframe = { kfId: kfData.info.ekf_uuid, kfName: kfData.info.ekf_name, prevKfId: kfData.info.ekf_prev_uuid, } this.outputs.kfName.value = kfData.info.ekf_name this.kfArena.reloadAgents(kfData.agents) } onclickAgent(obj3D){ const aid = obj3D.name if(this.currentlySelectedAid == aid){ // Deselect this.kfArena.clearHighlight3DObj(obj3D, this.kfArena.scene) this.currentlySelectedAid = null this.outputs.btnRemoveAgent.disabled = true } else { // Select if(this.currentlySelectedAid){ this.kfArena.clearHighlight3DObj(this.kfArena.scene.getObjectByName(this.currentlySelectedAid), this.kfArena.scene) } this.currentlySelectedAid = aid this.outputs.btnRemoveAgent.disabled = false if(this.kfArena.agents[aid]) { this.kfArena.highlight3DObj(obj3D, this.kfArena.scene) this.fillAgentProperties(aid, this.kfArena.agents[aid].props, this.kfArena.agents[aid].values) this.notUserChange = true this.outputs.agentsSelector.value = this.kfArena.agents[aid].type this.notUserChange = false } } this.updateKfButtons() } onAddAgent(event){ //TODO prevent collisions ! const AgentValues = this.getFieldsValues('div[data-output="agentProperties"]') const aid = this.newAgent(this.outputs.agentsSelector.value, AgentValues) this.output('agentId', `ID: ${aid}`) this.updateKfButtons() } onRemoveAgent(event){ if(!this.currentlySelectedAid) return this.kfArena.removeAgent(this.currentlySelectedAid) } async newAgent(aType, AgentValues){ const aid = crypto.randomUUIDv7() const agentProps = await this.models.agents.getProperties(aType) this.kfArena.addAgent(aType, aid, agentProps, AgentValues) return(aid) } updateKfButtons(){ if((Object.keys(this.kfArena.agents).length > 0) && (this.outputs.kfName.value.length > 5)) { this.outputs.btnSaveKF.disabled = false } else { this.outputs.btnSaveKF.disabled = true } } onPropsChanged(evt, comp){ if(this.currentlySelectedAid && this.kfArena.agents[this.currentlySelectedAid]){ const AgentValues = this.getFieldsValues('div[data-output="agentProperties"]') this.kfArena.agents[this.currentlySelectedAid].values = AgentValues const val = Number.parseInt(comp.value, 10) if((comp.name.startsWith('position.')) && (!Number.isNaN(val))){ this.kfArena.moveAgent(this.currentlySelectedAid, { x: this.getFieldValue('div[data-output="agentProperties"]', 'position.x'), y: this.getFieldValue('div[data-output="agentProperties"]', 'position.y'), z: this.getFieldValue('div[data-output="agentProperties"]', 'position.z'), }) } else if((comp.name.startsWith('speed.')) && (!Number.isNaN(val))){ this.kfArena.changeAgentSpeed(this.currentlySelectedAid, { x: this.getFieldValue('div[data-output="agentProperties"]', 'speed.x'), y: this.getFieldValue('div[data-output="agentProperties"]', 'speed.y'), z: this.getFieldValue('div[data-output="agentProperties"]', 'speed.z'), }) } } } fillAgentProperties(aid, agentProps, agentValues = {}){ this.outputs.agentProperties.innerHTML = `