Files
P42_UI/app/views/editors/KeyframeView.js
T

227 lines
8.9 KiB
JavaScript

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: `<i class="icon-${item.atp_hascode ? 'bug' : 'atom1'}"></i>${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
// this.output('console',`
// <div class="inner-console">
// <div class="results">
// JS 3D Console. for help, type "help"
// </div>
// <div class="cols-2 commandline">
// <textarea type="text" style="" data-output="commands"></textarea>
// <button class="icon-play" data-trigger="execCommand"></button>
// </div>
// </div>
// `)
}
async execCommand(event){
console.log('cmd:', this.ouputs.caommands)
}
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
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
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 aid = crypto.randomUUIDv7()
this.output('agentId', `ID: ${aid}`)
const AgentValues = this.getFieldsValues('div[data-output="agentProperties"]')
this.kfArena.addAgent(this.outputs.agentsSelector.value, aid, this.currentAgentType.atp_props , AgentValues)
this.updateKfButtons()
}
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 = `
<div data-output="agentId">ID: ${aid}</div>
`
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)