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. */ app.helpers.helpers3D = { agentFromJSON(id, desc){ let obj if(desc.type === 'Mesh') { const geom = new THREE[desc.geometry.type](...(desc.geometry.args || [])) const matType = desc.material.type const matProps = { ...desc.material } for (const key in matProps) { if (key === 'type') continue if (typeof matProps[key] === 'string' && THREE[matProps[key]] !== undefined) { matProps[key] = THREE[matProps[key]] } } // convert color strings like "0xffffaa" to numbers if (typeof matProps.color === 'string' && matProps.color.startsWith('0x')) { matProps.color = parseInt(matProps.color) } const mat = new THREE[matType](matProps) obj = new THREE.Mesh(geom, mat) } else if(desc.type === 'Group') { obj = new THREE.Group() } else { throw new Error("Unknown type: " + desc.type) } // 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) // Recursively add children if(desc.children) { desc.children.forEach(childDesc => { const childId = (childDesc.childSuffix) ? `${id}_${childDesc.childSuffix}` : '' obj.add(this.agentFromJSON(childId, childDesc)) }) } obj.name = id return obj }, cameraAutoFrame(object, camera, offset = 1.25, controls) { const box = new THREE.Box3().setFromObject(object) const size = new THREE.Vector3() const center = new THREE.Vector3() box.getSize(size) box.getCenter(center) const maxDim = Math.max(size.x, size.y, size.z) const fov = camera.fov * Math.PI / 180 let cameraZ = maxDim / (2 * Math.tan(fov / 2)) * offset camera.position.copy(center) camera.position.z += cameraZ camera.lookAt(center) if (controls) { controls.target.copy(center) controls.update() } } }