From e12e83c0e18171a4b6e30e2acb0a468e281a49d3 Mon Sep 17 00:00:00 2001 From: STEINNI Date: Thu, 30 Oct 2025 19:20:21 +0000 Subject: [PATCH] speed vectors + better scene selection --- app/helpers/formBuilder.js | 6 +++ app/helpers/helpers3D.module.js | 35 +++++++++++++- app/views/editors/KeyframeView.js | 20 +++++++- app/views/editors/modules/kfArena.module.js | 51 +++++++++++++++++---- 4 files changed, 101 insertions(+), 11 deletions(-) diff --git a/app/helpers/formBuilder.js b/app/helpers/formBuilder.js index a007f0f..bb20e7b 100644 --- a/app/helpers/formBuilder.js +++ b/app/helpers/formBuilder.js @@ -94,4 +94,10 @@ app.helpers.formBuilder = { return(result) }, + getFieldValue(rootSel, name){ + const comp = document.querySelector(`${rootSel} .formbuilder-field[name="${name}"]`) + if(comp) return(comp.value) + else return(null) + }, + } \ No newline at end of file diff --git a/app/helpers/helpers3D.module.js b/app/helpers/helpers3D.module.js index ffa9ff9..8819c84 100644 --- a/app/helpers/helpers3D.module.js +++ b/app/helpers/helpers3D.module.js @@ -111,6 +111,17 @@ app.helpers.helpers3D = { box.getCenter(center) // world coords 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){ if (!this.composer) { @@ -168,4 +179,26 @@ app.helpers.helpers3D = { } return obj }, -} \ No newline at end of file + + 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 + }, +} diff --git a/app/views/editors/KeyframeView.js b/app/views/editors/KeyframeView.js index bd64e5a..be2a318 100644 --- a/app/views/editors/KeyframeView.js +++ b/app/views/editors/KeyframeView.js @@ -88,6 +88,7 @@ class KeyframeView extends WindozDomContent { kfName: kfData.info.ekf_name, prevKfId: kfData.info.ekf_prev_uuid, } + this.outputs.kfName.value = kfData.info.ekf_name this.kfArena.reloadAgents(kfData.agents) } @@ -124,9 +125,24 @@ class KeyframeView extends WindozDomContent { } onPropsChanged(evt, comp){ - console.log('onPropsChanged', comp, evt) + console.log('onPropsChanged', comp.name, comp.value) 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'), + }) + } } } diff --git a/app/views/editors/modules/kfArena.module.js b/app/views/editors/modules/kfArena.module.js index b3ed925..c8d6b5a 100644 --- a/app/views/editors/modules/kfArena.module.js +++ b/app/views/editors/modules/kfArena.module.js @@ -42,7 +42,7 @@ export class kfArena{ // Base plane const planeGeo = new THREE.PlaneGeometry(100, 100) const planeMat = new THREE.MeshBasicMaterial({ - color: 0x8888aa, + color: 0x000055, opacity: 0.3, transparent: true, // needed for opacity < 1 to take effect side: THREE.DoubleSide @@ -115,10 +115,14 @@ export class kfArena{ 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) + let hit = null + for(let i=0; i', agents) for(const agent of agents){ this.addAgent(agent.ekfs_atp_id, agent.aid, agent.props, {...agent.gps_values, ...agent.store_values}) }