class KeyframeView extends WindozDomContent { constructor() { super() Object.assign(this, app.helpers.activeAttributes) Object.assign(this, app.helpers.formBuilder) } 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 execCommand(event){ console.log('cmd:', this.outputs.commands) if(this.outputs.commands.trim()=='help'){ this.outputs.results.innerHTML = ` Type any javascript at your own risks. To create an agent : this.newAgent(type, properties) ` } else { this.kfArena.evalCmd(this.outputs.commands) } } 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.atp_props) // 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 } else { // Select if(this.currentlySelectedAid){ this.kfArena.clearHighlight3DObj(this.kfArena.scene.getObjectByName(this.currentlySelectedAid), this.kfArena.scene) } this.currentlySelectedAid = aid 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() } newAgent(aType, AgentValues){ const aid = crypto.randomUUIDv7() this.kfArena.addAgent(aType, aid, this.currentAgentType.atp_props , 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 = `
ID: ${aid}
` this.outputs.agentProperties.append(...this.fieldsFromJSON(agentProps, agentValues, 'Internal properties', this.onPropsChanged.bind(this))) this.outputs.agentProperties.append(...this.fieldsFromJSON({ "position.x": { label: "Position X", type: "number", default: "0" }, "position.y": { label: "Position Y", type: "number", default: "0" }, "position.z": { label: "Position Z", type: "number", default: "0" }, }, agentValues, 'Coordinates', this.onPropsChanged.bind(this))) this.outputs.agentProperties.append(...this.fieldsFromJSON({ "speed.x": { label: "Speed X", type: "number", default: "0" }, "speed.y": { label: "Speed Y", type: "number", default: "0" }, "speed.z": { label: "Speed Z", type: "number", default: "0" }, }, agentValues, 'Speed vector', this.onPropsChanged.bind(this))) this.outputs.btnAddAgent.disabled = false this.setupRefs() } async onSaveKF(evt){ let result = { success: true } if(!this.currentKeyframe.kfId){ // Create first (and get new kfId) this.currentKeyframe.kfName = this.outputs.kfName.value result = await this.models.keyframes.create(this.currentKeyframe) this.currentKeyframe.kfId = result.payload.kfId } else if(this.currentKeyframe.kfName != this.outputs.kfName.value){ //rename this.currentKeyframe.kfName = this.outputs.kfName.value result = await this.models.keyframes.rename(this.currentKeyframe) console.log(result) } if(result.success){ await this.models.keyframes.save(this.currentKeyframe.kfId, this.kfArena.agents) } } } app.registerClass('KeyframeView', KeyframeView)