speed vectors + better scene selection
This commit is contained in:
@@ -94,4 +94,10 @@ app.helpers.formBuilder = {
|
|||||||
return(result)
|
return(result)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getFieldValue(rootSel, name){
|
||||||
|
const comp = document.querySelector(`${rootSel} .formbuilder-field[name="${name}"]`)
|
||||||
|
if(comp) return(comp.value)
|
||||||
|
else return(null)
|
||||||
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -111,6 +111,17 @@ app.helpers.helpers3D = {
|
|||||||
box.getCenter(center) // world coords
|
box.getCenter(center) // world coords
|
||||||
return center
|
return center
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getObjectTopCenter(object, offset = 0.1) {
|
||||||
|
object.updateWorldMatrix(true, true)
|
||||||
|
const box = new THREE.Box3().setFromObject(object)
|
||||||
|
const center = new THREE.Vector3()
|
||||||
|
box.getCenter(center)
|
||||||
|
const up = new THREE.Vector3(0, 1, 0).applyQuaternion(object.quaternion).normalize()
|
||||||
|
const height = box.max.y - box.min.y
|
||||||
|
const top = center.clone().addScaledVector(up, height / 2 + offset)
|
||||||
|
return top
|
||||||
|
},
|
||||||
|
|
||||||
init3DHighlighter(options){
|
init3DHighlighter(options){
|
||||||
if (!this.composer) {
|
if (!this.composer) {
|
||||||
@@ -168,4 +179,26 @@ app.helpers.helpers3D = {
|
|||||||
}
|
}
|
||||||
return obj
|
return obj
|
||||||
},
|
},
|
||||||
}
|
|
||||||
|
createArrow(origin, vector, name='', color = 0xffaa00, headLength = 0.25, headWidth = 0.1) {
|
||||||
|
//const from = new THREE.Vector3(origin.x, origin.y, origin.z)
|
||||||
|
const dir = new THREE.Vector3(vector.x, vector.y, vector.z).normalize()
|
||||||
|
const length = Math.sqrt(vector.x**2 + vector.y**2 + vector.z**2)
|
||||||
|
if(length==0) return(null)
|
||||||
|
const arrow = new THREE.ArrowHelper(dir, origin, length, color, headLength, headWidth)
|
||||||
|
|
||||||
|
// Optional: add a subtle tube body for style
|
||||||
|
const shaftGeo = new THREE.CylinderGeometry(0.02, 0.02, length - headLength, 16)
|
||||||
|
const shaftMat = new THREE.MeshStandardMaterial({ color, metalness: 0.3, roughness: 0.2 })
|
||||||
|
const shaft = new THREE.Mesh(shaftGeo, shaftMat)
|
||||||
|
shaft.position.copy(origin.clone().add(dir.clone().multiplyScalar((length - headLength) / 2)))
|
||||||
|
shaft.quaternion.setFromUnitVectors(new THREE.Vector3(0, 1, 0), dir)
|
||||||
|
|
||||||
|
const group = new THREE.Group()
|
||||||
|
group.add(arrow)
|
||||||
|
group.add(shaft)
|
||||||
|
if(name) group.name = name
|
||||||
|
this.scene.add(group)
|
||||||
|
return group
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ class KeyframeView extends WindozDomContent {
|
|||||||
kfName: kfData.info.ekf_name,
|
kfName: kfData.info.ekf_name,
|
||||||
prevKfId: kfData.info.ekf_prev_uuid,
|
prevKfId: kfData.info.ekf_prev_uuid,
|
||||||
}
|
}
|
||||||
|
this.outputs.kfName.value = kfData.info.ekf_name
|
||||||
this.kfArena.reloadAgents(kfData.agents)
|
this.kfArena.reloadAgents(kfData.agents)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,9 +125,24 @@ class KeyframeView extends WindozDomContent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onPropsChanged(evt, comp){
|
onPropsChanged(evt, comp){
|
||||||
console.log('onPropsChanged', comp, evt)
|
console.log('onPropsChanged', comp.name, comp.value)
|
||||||
if(this.currentlySelectedAid && this.kfArena.agents[this.currentlySelectedAid]){
|
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'),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export class kfArena{
|
|||||||
// Base plane
|
// Base plane
|
||||||
const planeGeo = new THREE.PlaneGeometry(100, 100)
|
const planeGeo = new THREE.PlaneGeometry(100, 100)
|
||||||
const planeMat = new THREE.MeshBasicMaterial({
|
const planeMat = new THREE.MeshBasicMaterial({
|
||||||
color: 0x8888aa,
|
color: 0x000055,
|
||||||
opacity: 0.3,
|
opacity: 0.3,
|
||||||
transparent: true, // needed for opacity < 1 to take effect
|
transparent: true, // needed for opacity < 1 to take effect
|
||||||
side: THREE.DoubleSide
|
side: THREE.DoubleSide
|
||||||
@@ -115,10 +115,14 @@ export class kfArena{
|
|||||||
normalizedPointer.y = -((event.clientY - rect.top) / rect.height) * 2 + 1
|
normalizedPointer.y = -((event.clientY - rect.top) / rect.height) * 2 + 1
|
||||||
this.raycaster.setFromCamera(normalizedPointer, this.camera)
|
this.raycaster.setFromCamera(normalizedPointer, this.camera)
|
||||||
const intersects = this.raycaster.intersectObjects(this.scene.children, true)
|
const intersects = this.raycaster.intersectObjects(this.scene.children, true)
|
||||||
|
|
||||||
if (intersects.length > 0) {
|
if (intersects.length > 0) {
|
||||||
const hit = this.getNamedParent(intersects[0].object)
|
let hit = null
|
||||||
if(hit) this.onclickAgent(hit)
|
for(let i=0; i<intersects.length; i++){
|
||||||
|
hit = this.getNamedParent(intersects[i].object)
|
||||||
|
if((!hit) || (!hit.name)) continue
|
||||||
|
if(Object.keys(this.agents).includes(hit.name)) break
|
||||||
|
}
|
||||||
|
if(hit && Object.keys(this.agents).includes(hit.name)) this.onclickAgent(hit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,9 +136,17 @@ export class kfArena{
|
|||||||
const agentObj = this.agentFromJSON(aid, agentSprite.asp_3d)
|
const agentObj = this.agentFromJSON(aid, agentSprite.asp_3d)
|
||||||
|
|
||||||
agentObj.position.set(values.position.x, values.position.z, values.position.y )
|
agentObj.position.set(values.position.x, values.position.z, values.position.y )
|
||||||
//TODO Speed vector
|
|
||||||
this.scene.add(agentObj)
|
this.scene.add(agentObj)
|
||||||
|
//Speed vector
|
||||||
|
const objAboveHead = this.getObjectTopCenter(this.scene.getObjectByName(aid))
|
||||||
|
this.createArrow(objAboveHead, {
|
||||||
|
x: values.speed.x,
|
||||||
|
y: values.speed.z,
|
||||||
|
z:values.speed.y },
|
||||||
|
`_speed_${aid}`,
|
||||||
|
0xff0055)
|
||||||
|
|
||||||
|
|
||||||
this.agents[aid] = {
|
this.agents[aid] = {
|
||||||
type: typeId,
|
type: typeId,
|
||||||
props: properties,
|
props: properties,
|
||||||
@@ -143,16 +155,39 @@ export class kfArena{
|
|||||||
}
|
}
|
||||||
|
|
||||||
removeAgent(aid){
|
removeAgent(aid){
|
||||||
const obj3d = scene.getObjectByName(aid)
|
const obj3d = this.scene.getObjectByName(aid)
|
||||||
this.scene.remove(obj3d)
|
this.scene.remove(obj3d)
|
||||||
if(aid in this.agents) delete(this.agents[aid])
|
if(aid in this.agents) delete(this.agents[aid])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
moveAgent(aid, position){
|
||||||
|
const obj3d = this.scene.getObjectByName(aid)
|
||||||
|
new TWEEN.Tween(obj3d.position)
|
||||||
|
.to({ x: Number(position.x),
|
||||||
|
y: Number(position.z),
|
||||||
|
z: Number(position.y),
|
||||||
|
}, 500)
|
||||||
|
.easing(TWEEN.Easing.Quadratic.InOut)
|
||||||
|
.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
changeAgentSpeed(aid, speed){
|
||||||
|
const objName = `_speed_${aid}`
|
||||||
|
const obj3d = this.scene.getObjectByName(objName)
|
||||||
|
if(obj3d) this.scene.remove(obj3d)
|
||||||
|
const objAboveHead = this.getObjectTopCenter(this.scene.getObjectByName(aid))
|
||||||
|
this.createArrow(objAboveHead, {
|
||||||
|
x: speed.x,
|
||||||
|
y: speed.z,
|
||||||
|
z: speed.y },
|
||||||
|
objName,
|
||||||
|
0xff0055)
|
||||||
|
}
|
||||||
|
|
||||||
reloadAgents(agents){
|
reloadAgents(agents){
|
||||||
for(const aid in this.agents){
|
for(const aid in this.agents){
|
||||||
this.removeAgent(aid)
|
this.removeAgent(aid)
|
||||||
}
|
}
|
||||||
console.log('====>', agents)
|
|
||||||
for(const agent of agents){
|
for(const agent of agents){
|
||||||
this.addAgent(agent.ekfs_atp_id, agent.aid, agent.props, {...agent.gps_values, ...agent.store_values})
|
this.addAgent(agent.ekfs_atp_id, agent.aid, agent.props, {...agent.gps_values, ...agent.store_values})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user