agentIDs and raycasting like mad!
This commit is contained in:
@@ -103,8 +103,6 @@ menu[eicmenu] [menuitem] > a > button, menu[eicmenu] [menuitem] > .nolink button
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
grid-template-rows: min-content 1fr;
|
grid-template-rows: min-content 1fr;
|
||||||
max-height: 90vh;
|
|
||||||
max-width: 90vw;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
border-radius: .3rem;
|
border-radius: .3rem;
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ app.helpers.activeAttributes = {
|
|||||||
* setupRefs is re-entrant: it can be called again after refreshing part of the view
|
* setupRefs is re-entrant: it can be called again after refreshing part of the view
|
||||||
* @param {eicui-components []} components : the view's components (usually result of ui.eicfy(this.el) )
|
* @param {eicui-components []} components : the view's components (usually result of ui.eicfy(this.el) )
|
||||||
*/
|
*/
|
||||||
setupRefs(components){
|
setupRefs(components = []){
|
||||||
if(!this.components) this.components = {}
|
if(!this.components) this.components = {}
|
||||||
for(let component of components.filter(component => component.el.hasAttribute('data-ref'))) {
|
for(let component of components.filter(component => component.el.hasAttribute('data-ref'))) {
|
||||||
this.components[component.el.dataset.ref] = component
|
this.components[component.el.dataset.ref] = component
|
||||||
@@ -61,6 +61,7 @@ app.helpers.activeAttributes = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* output (singular) : this.output('mydiv', '<p>Some markup</p>') places markup in a data-output node
|
* output (singular) : this.output('mydiv', '<p>Some markup</p>') places markup in a data-output node
|
||||||
* @param {*} name
|
* @param {*} name
|
||||||
|
|||||||
@@ -110,4 +110,10 @@ app.helpers.helpers3D = {
|
|||||||
return pivot
|
return pivot
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getNamedParent(obj) {
|
||||||
|
while (obj && !obj.name) {
|
||||||
|
obj = obj.parent
|
||||||
|
}
|
||||||
|
return obj
|
||||||
|
},
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,16 @@
|
|||||||
.kf-editor button[data-trigger="onResetKF"] { background-color: #A00; }
|
.kf-editor button[data-trigger="onResetKF"] { background-color: #A00; }
|
||||||
.kf-editor section[data-output="agentProperties"] label{ font-size: 0.9em; }
|
.kf-editor section[data-output="agentProperties"] label{ font-size: 0.9em; }
|
||||||
.kf-editor section[data-output="agentProperties"] div.cols-2 { grid-template-columns: 4fr 3fr; }
|
.kf-editor section[data-output="agentProperties"] div.cols-2 { grid-template-columns: 4fr 3fr; }
|
||||||
|
.kf-editor div[data-output="agentId"] {
|
||||||
|
border: 1px solid #574;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #231;
|
||||||
|
box-shadow: 0px 0px 7px #0B69;
|
||||||
|
height: 2em;
|
||||||
|
padding: .2em 5px .2em 5px;
|
||||||
|
margin-top: 1em;
|
||||||
|
font-size: .8em;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="kf-editor cols-3">
|
<div class="kf-editor cols-3">
|
||||||
<article eiccard class="agent-preview">
|
<article eiccard class="agent-preview">
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ class KeyframeView extends WindozDomContent {
|
|||||||
this.agentPreview.animation = true
|
this.agentPreview.animation = true
|
||||||
|
|
||||||
this.kfArena = new app.LoadedModules.kfArena(this.outputs.kfArenaCanvas, this.agentSprites)
|
this.kfArena = new app.LoadedModules.kfArena(this.outputs.kfArenaCanvas, this.agentSprites)
|
||||||
|
this.kfArena.onclickAgent = this.onclickAgent.bind(this)
|
||||||
this.kfArena.startRendering()
|
this.kfArena.startRendering()
|
||||||
|
|
||||||
this.outputs.btnAddAgent.disabled = true
|
this.outputs.btnAddAgent.disabled = true
|
||||||
@@ -53,20 +54,37 @@ class KeyframeView extends WindozDomContent {
|
|||||||
if(this.outputs.agentsSelector.value) this.agentPreview.setAgent(this.outputs.agentsSelector.value)
|
if(this.outputs.agentsSelector.value) this.agentPreview.setAgent(this.outputs.agentsSelector.value)
|
||||||
if(!this.outputs.agentsSelector.value) return
|
if(!this.outputs.agentsSelector.value) return
|
||||||
const agent = await this.models.agents.getProperties(this.outputs.agentsSelector.value)
|
const agent = await this.models.agents.getProperties(this.outputs.agentsSelector.value)
|
||||||
this.fillAgentProperties(agent.atp_props)
|
this.fillAgentProperties('', agent.atp_props)
|
||||||
|
}
|
||||||
|
|
||||||
|
onclickAgent(aid){
|
||||||
|
console.log('Agent clicked:', aid)
|
||||||
|
this.updateKfButtons()
|
||||||
}
|
}
|
||||||
|
|
||||||
onAddAgent(event){
|
onAddAgent(event){
|
||||||
|
//TODO prevent collisions !
|
||||||
|
|
||||||
const aid = crypto.randomUUIDv7()
|
const aid = crypto.randomUUIDv7()
|
||||||
|
this.output('agentId', `ID: ${aid}`)
|
||||||
this.kfArena.addAgent(this.outputs.agentsSelector.value, aid, {
|
this.kfArena.addAgent(this.outputs.agentsSelector.value, aid, {
|
||||||
|
position: {
|
||||||
x: document.querySelector('[name="position.x"]').value,
|
x: document.querySelector('[name="position.x"]').value,
|
||||||
y: document.querySelector('[name="position.y"]').value,
|
y: document.querySelector('[name="position.y"]').value,
|
||||||
z: document.querySelector('[name="position.z"]').value,
|
z: document.querySelector('[name="position.z"]').value,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
this.updateKfButtons()
|
||||||
}
|
}
|
||||||
|
|
||||||
fillAgentProperties(agentProps){
|
updateKfButtons(){
|
||||||
this.outputs.agentProperties.innerHTML=''
|
if(this.kfArena.agents.length > 0) this.outputs.btnSaveKF.disabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
fillAgentProperties(aid, agentProps){
|
||||||
|
this.outputs.agentProperties.innerHTML = `
|
||||||
|
<div data-output="agentId">ID: ${aid}</div>
|
||||||
|
`
|
||||||
this.outputs.agentProperties.append(...this.fieldsFromJSON(agentProps, 'Internal properties'))
|
this.outputs.agentProperties.append(...this.fieldsFromJSON(agentProps, 'Internal properties'))
|
||||||
this.outputs.agentProperties.append(...this.fieldsFromJSON({
|
this.outputs.agentProperties.append(...this.fieldsFromJSON({
|
||||||
"position.x": {
|
"position.x": {
|
||||||
@@ -103,8 +121,10 @@ class KeyframeView extends WindozDomContent {
|
|||||||
},
|
},
|
||||||
}, 'Speed vector'))
|
}, 'Speed vector'))
|
||||||
this.outputs.btnAddAgent.disabled = false
|
this.outputs.btnAddAgent.disabled = false
|
||||||
|
this.setupRefs()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
app.registerClass('KeyframeView', KeyframeView)
|
app.registerClass('KeyframeView', KeyframeView)
|
||||||
|
|||||||
@@ -10,9 +10,12 @@ export class kfArena{
|
|||||||
this.canvasEl = canvasEl
|
this.canvasEl = canvasEl
|
||||||
this.agentSprites = agentSprites
|
this.agentSprites = agentSprites
|
||||||
this.renderer = null
|
this.renderer = null
|
||||||
this.mode='3D'
|
this.mode = '3D'
|
||||||
this.sceneSize = app.Assets.Store.json.arenaConfig.arenaSize
|
this.sceneSize = app.Assets.Store.json.arenaConfig.arenaSize
|
||||||
this.initScene()
|
this.initScene()
|
||||||
|
this.raycaster = new THREE.Raycaster()
|
||||||
|
this.agents = []
|
||||||
|
this.onclickAgent = null
|
||||||
}
|
}
|
||||||
|
|
||||||
initScene(){
|
initScene(){
|
||||||
@@ -55,6 +58,7 @@ export class kfArena{
|
|||||||
this.scene.add(this.axes)
|
this.scene.add(this.axes)
|
||||||
|
|
||||||
this.renderer = new THREE.WebGLRenderer({ antialias: true, canvas: this.canvasEl })
|
this.renderer = new THREE.WebGLRenderer({ antialias: true, canvas: this.canvasEl })
|
||||||
|
this.canvasEl.addEventListener('click', this.onSceneClick.bind(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
startRendering(){
|
startRendering(){
|
||||||
@@ -98,21 +102,50 @@ export class kfArena{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addAgent(typeId, aid, position){
|
|
||||||
|
onSceneClick(event){ // ray from the mouse, through the camera lens, to find the first (most foreground) object
|
||||||
|
if(typeof(this.onclickAgent) != 'function') return
|
||||||
|
const normalizedPointer = new THREE.Vector2()
|
||||||
|
const rect = this.canvasEl.getBoundingClientRect()
|
||||||
|
normalizedPointer.x = ((event.clientX - rect.left) / rect.width) * 2 - 1
|
||||||
|
normalizedPointer.y = -((event.clientY - rect.top) / rect.height) * 2 + 1
|
||||||
|
this.raycaster.setFromCamera(normalizedPointer, this.camera)
|
||||||
|
const intersects = this.raycaster.intersectObjects(this.scene.children, true)
|
||||||
|
|
||||||
|
if (intersects.length > 0) {
|
||||||
|
const hit = this.getNamedParent(intersects[0].object)
|
||||||
|
if(hit) this.onclickAgent(hit.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
addAgent(typeId, aid, properties){
|
||||||
const agentSprite = this.agentSprites.find(item => item.atp_id==typeId)
|
const agentSprite = this.agentSprites.find(item => item.atp_id==typeId)
|
||||||
if(!agentSprite) return
|
if(!agentSprite) return
|
||||||
const agentObj = this.agentFromJSON(aid, agentSprite.asp_3d)
|
const agentObj = this.agentFromJSON(aid, agentSprite.asp_3d)
|
||||||
|
|
||||||
agentObj.position.set(position.x, position.z, position.y )
|
agentObj.position.set(properties.position.x, properties.position.z, properties.position.y )
|
||||||
|
//TODO Speed vector
|
||||||
this.scene.add(agentObj)
|
this.scene.add(agentObj)
|
||||||
|
|
||||||
|
this.agents.push({
|
||||||
|
aid: aid,
|
||||||
|
props: properties,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
removeAgent(id){
|
removeAgent(aid){
|
||||||
//find obj by id
|
const obj3d = scene.getObjectByName(aid)
|
||||||
//this.scene.remove(this.currentAgentObj)
|
this.scene.remove(obj3d)
|
||||||
|
this.agents = this.agents.filter(a => a.aid !== aid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getAllAgents(){
|
||||||
|
// const agents = []
|
||||||
|
// scene.traverse(o => o.name && names.push(o.name))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Make this module available to common JS
|
// Make this module available to common JS
|
||||||
if(!app.LoadedModules) app.LoadedModules = {}
|
if(!app.LoadedModules) app.LoadedModules = {}
|
||||||
app.LoadedModules.kfArena = kfArena
|
app.LoadedModules.kfArena = kfArena
|
||||||
|
|||||||
Reference in New Issue
Block a user