From 006bed2ad5503e6aa0025e0bf4f939dc5d48a04f Mon Sep 17 00:00:00 2001 From: STEINNI Date: Wed, 22 Oct 2025 16:27:39 +0000 Subject: [PATCH] better preview on pivot, with axes --- app/helpers/helpers3D.module.js | 55 +++++++++++++++---- .../editors/modules/agentPreview.module.js | 21 ++++--- app/views/editors/modules/kfArena.module.js | 2 +- 3 files changed, 56 insertions(+), 22 deletions(-) diff --git a/app/helpers/helpers3D.module.js b/app/helpers/helpers3D.module.js index d2c48a9..1d2b7a6 100644 --- a/app/helpers/helpers3D.module.js +++ b/app/helpers/helpers3D.module.js @@ -2,11 +2,11 @@ import * as THREE from '/app/thirdparty/Three/three.module.js' if(!app.helpers) app.helpers = {} /** - * Mixing add-in methods to your view instance. - * All of this should not be a helper, but inherited this from WindozDomContent, but not my framework anymore. - */ +* Mixing add-in methods to your view instance. +* All of this should not be a helper, but inherited this from WindozDomContent, but not my framework anymore. +*/ app.helpers.helpers3D = { - + agentFromJSON(id, desc){ let obj, wrapper if(desc.type === 'Mesh') { @@ -24,8 +24,8 @@ app.helpers.helpers3D = { matProps.color = parseInt(matProps.color) } const mat = new THREE[matType](matProps) - - + + obj = new THREE.Mesh(geom, mat) if(desc.translate){ wrapper = new THREE.Object3D() @@ -34,7 +34,7 @@ app.helpers.helpers3D = { obj.position.y = desc.translate[1] obj.position.z = desc.translate[2] } - + } else if(desc.type === 'Group') { obj = new THREE.Group() } else { @@ -43,8 +43,8 @@ app.helpers.helpers3D = { // Apply transforms if(desc.position) obj.position.set(...desc.position) - if(desc.rotation) obj.rotation.set(...desc.rotation) - if(desc.scale) obj.scale.set(...desc.scale) + if(desc.rotation) obj.rotation.set(...desc.rotation) + if(desc.scale) obj.scale.set(...desc.scale) // Recursively add children if(desc.children) { @@ -57,7 +57,7 @@ app.helpers.helpers3D = { obj.name = id return obj }, - + cameraAutoFrame(object, camera, offset = 1.5, controls) { const box = new THREE.Box3().setFromObject(object) const size = new THREE.Vector3() @@ -77,6 +77,37 @@ app.helpers.helpers3D = { controls.target.copy(center) controls.update() } - } - + }, + + getObjectCenter(object) { + object.updateWorldMatrix(true, true) + const box = new THREE.Box3().setFromObject(object) + const center = new THREE.Vector3() + box.getCenter(center) // world coords + return center + }, + + makePivotAtGeomCenter(object, scene) { + object.updateWorldMatrix(true, true) + const box = new THREE.Box3().setFromObject(object) + const centerW = box.getCenter(new THREE.Vector3()) + + // Create pivot at world center of the object + const pivot = new THREE.Object3D() + pivot.position.copy(centerW) + pivot.matrixAutoUpdate = true + scene.add(pivot) + + // Compute the center in the object's local space + const centerLocal = object.worldToLocal(centerW.clone()) + + // Shift the object so its center sits at its own origin + object.position.sub(centerLocal) + + // Reparent under the pivot (world pose preserved) + pivot.add(object) + + return pivot + }, + } \ No newline at end of file diff --git a/app/views/editors/modules/agentPreview.module.js b/app/views/editors/modules/agentPreview.module.js index 279cae7..02367da 100644 --- a/app/views/editors/modules/agentPreview.module.js +++ b/app/views/editors/modules/agentPreview.module.js @@ -40,16 +40,19 @@ export class AgentPreview{ } setAgent(id){ - if(this.currentAgentObj && (this.scene.children.includes(this.currentAgentObj))){ - this.scene.remove(this.currentAgentObj) + if(this.pivot && (this.scene.children.includes(this.pivot))){ + this.scene.remove(this.pivot) } - const agentSprite = this.agentSprites.find(item => item.atp_id==id) + const agentSprite = this.agentSprites.find(item => item.atp_id==id) if(!agentSprite) return this.currentAgentObj = this.agentFromJSON('previewedAgent', agentSprite.asp_3d) - this.currentAgentObj.position.set(0, 0, 0) - this.scene.add(this.currentAgentObj) + + this.pivot = this.makePivotAtGeomCenter(this.currentAgentObj, this.scene) + this.cameraAutoFrame(this.pivot, this.camera, 1.5) - this.cameraAutoFrame(this.currentAgentObj, this.camera, 2) + // After creating the pivot, so axes do not unbalance the center, + // and after cameraFraming so axes we frame on the object, no matter the axes + this.currentAgentObj.add(new THREE.AxesHelper(2)) } set animation(value){ @@ -63,9 +66,9 @@ export class AgentPreview{ _animate = () => { // to avoid having to bind(this) in requestAnimationFrame, because one bound fn per frame = continuous GC load requestAnimationFrame(this._animate) - if(this.currentAgentObj && this.animation){ - this.currentAgentObj.rotation.x += 0.005 - this.currentAgentObj.rotation.y += 0.01 + if(this.pivot && this.animation){ + this.pivot.rotation.x += 0.005 + this.pivot.rotation.y += 0.01 } this.renderer.render(this.scene, this.camera) } diff --git a/app/views/editors/modules/kfArena.module.js b/app/views/editors/modules/kfArena.module.js index 0fb6669..b65e457 100644 --- a/app/views/editors/modules/kfArena.module.js +++ b/app/views/editors/modules/kfArena.module.js @@ -50,7 +50,7 @@ export class kfArena{ this.basePlane.position.y=-0.01 // to avoid artefacts on objets bases this.scene.add(this.basePlane) - this.axes = new THREE.AxesHelper(this.sceneSize.x/2, this.sceneSize.y/2) + this.axes = new THREE.AxesHelper(this.sceneSize.x/2) this.axes.layers.set(2) this.scene.add(this.axes)