/** * _ ___ Another * / |/ (_)______ __ _____ * / / / __(_- { 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.output('settingsMenu', app.Assets.Store.html.spaceViewSetting) this.outputs.settingsMenu.querySelectorAll('input[type="toggler"]').forEach(el => { const tog = new InputToggler(el) if(this.kfArena[tog._el.name]?.layers){ tog.value = this.kfArena.camera.layers.test(this.kfArena[tog._el.name].layers) ? 'yes' : 'no' } tog.onToggle = this.settingsToggle.bind(this) }) this.outputs.btnAddAgent.disabled = true this.outputs.btnRemoveAgent.disabled = true this.outputs.btnSaveKF.disabled = true this.outputs.btnResetKF.disabled = true this.outputs.kfName.addEventListener('keyup', this.updateKfButtons.bind(this)) this.currentlySelectedAid = null } settingsToggle(value, object){ if(['grid','axes'].includes(object._el.name)){ const layerId = {'grid':1,'axes':2}[object._el.name] if(value=='yes'){ this.kfArena.camera.layers.enable(layerId) } else { this.kfArena.camera.layers.disable(layerId) } } } deselectSceneAgent(){ if(!this.currentlySelectedAid) return const obj3D = this.kfArena.scene.getObjectByName(this.currentlySelectedAid) if(obj3D) this.kfArena.clearHighlight3DObj(obj3D, this.kfArena.scene) this.currentlySelectedAid = null this.outputs.btnRemoveAgent.disabled = true } 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) this.deselectSceneAgent() } } async onChangeKeyframe(event){ if(!this.outputs.keyframesSelector.value) return await this.loadKeyframe(this.outputs.keyframesSelector.value) } async onResetKF(evt){ if(!this.currentKeyframe.kfId) return const kfName = this.currentKeyframe.kfName const kfId = this.currentKeyframe.kfId await this.confirmDialog({ title: 'Reset keyframe ?', message: `

You are about to discard all unsaved changes
and reload the saved version of "${kfName}".

Are you sure?

`, okLabel: 'Reset', severity: 'warning', okPromise: async () => { await this.loadKeyframe(kfId) } }) } async loadKeyframe(kfId){ let kfData = await this.models.keyframes.getKeyframe(kfId).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.deselectSceneAgent() this.kfArena.reloadAgents(kfData.agents) this.outputs.agentProperties.innerHTML = '' this.outputs.btnAddAgent.disabled = true this.updateKfButtons() } onclickAgent(obj3D){ const aid = obj3D.name if(this.currentlySelectedAid == aid){ // Deselect this.deselectSceneAgent() } else { // Select this.deselectSceneAgent() 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) this.currentlySelectedAid = null this.outputs.btnRemoveAgent.disabled = true if(this.currentAgentType) this.fillAgentProperties('', this.currentAgentType) this.updateKfButtons() } 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 } this.outputs.btnResetKF.disabled = !this.currentKeyframe.kfId } 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) } if(result.success){ await this.models.keyframes.save(this.currentKeyframe.kfId, this.kfArena.agents) this.outputs.btnSaveKF.disabled = true this.updateKfButtons() ui.growl.append('Keyframe saved!','success',3000) setTimeout(() => { this.outputs.btnSaveKF.disabled = false}, 3000) } } } app.registerClass('KeyframeView', KeyframeView) //TODO : /* API update API remove API listAgentTypes if unsavec changes in scene => confirm before reloading agent rotation (param + tween) Bugs => reselect same scene resets it */