From dd860b45a9de722cf72749b1211351f0ede1af8a Mon Sep 17 00:00:00 2001 From: STEINNI Date: Fri, 26 Sep 2025 21:02:32 +0000 Subject: [PATCH] agent def + windows fixes + 2d view + 3d view --- app/assets/styles/app.css | 18 ++- .../dashboard/DashboardsController.js | 31 +++- app/libs/EIC/EICController.js | 8 +- .../Threetobus/threetobus.module.js | 150 +++++++++++------- app/views/dashboards/MainDashboardView.js | 77 ++++----- 5 files changed, 177 insertions(+), 107 deletions(-) diff --git a/app/assets/styles/app.css b/app/assets/styles/app.css index 8a4533e..da6b722 100755 --- a/app/assets/styles/app.css +++ b/app/assets/styles/app.css @@ -37,7 +37,7 @@ body[eicapp] { grid-template-columns: min-content auto; min-height: 100vh; box-sizing: border-box; - background: repeating-linear-gradient( -45deg, #000, #555 10px, #000 10px, #555 20px ); + background: repeating-linear-gradient( -45deg, #000, #333 10px, #000 10px, #333 20px ); } [eicapp] [eicapptoolbar] { @@ -95,17 +95,20 @@ body[eicapp] { bottom: auto; overflow: hidden; z-index: 2; - display: block; grid-template-rows: min-content 1fr; max-height: 90vh; max-width: 90vw; + display: flex; + flex-direction: column; } [eicapp] .app-workspace .window.active { z-index: 3; background: var(--app-color-primary); border-radius: .3rem; } -[eicapp] .app-workspace .window > header { display: grid; } +[eicapp] .app-workspace .window > header { + flex: 0 0 auto; +} [eicapp] .app-workspace .window > header h1 { padding: var(--eicui-base-spacing-xs); color: var(--app-color-white); @@ -125,12 +128,13 @@ body[eicapp] { [eicapp] .app-workspace .window > header .controls button.expand { display: inline-flex; } [eicapp] .app-workspace .window > header .controls button.shrink { display: none; } [eicapp] .app-workspace .window > section { - padding: var(--eicui-base-spacing-xs) var(--eicui-base-spacing-s); - /*background: var(--app-bg-color);*/ + padding: var(--eicui-base-spacing-2xs) var(--eicui-base-spacing-2xs); cursor: default; margin: 0; overflow: auto; transition: all 0.5s; + flex: 1 1 auto; + } [eicapp] .app-workspace .window[device="tablet"] > section { padding: 0; @@ -142,8 +146,8 @@ body[eicapp] { box-shadow: none; width: 100%; max-width:none; - padding: 0 var(--eicui-base-spacing-2xs) var(--eicui-base-spacing-3xl) var(--eicui-base-spacing-2xs); - background: repeating-linear-gradient( -45deg, #000, #555 10px, #000 10px, #555 20px ); + padding: 0 var(--eicui-base-spacing-2xs) 0 var(--eicui-base-spacing-2xs); + background: repeating-linear-gradient( -45deg, #000, #333 10px, #000 10px, #333 20px ); cursor: default; margin: 0; overflow: visible; diff --git a/app/controllers/dashboard/DashboardsController.js b/app/controllers/dashboard/DashboardsController.js index 1c2c9f5..65d6ebd 100644 --- a/app/controllers/dashboard/DashboardsController.js +++ b/app/controllers/dashboard/DashboardsController.js @@ -17,14 +17,39 @@ class DashboardsController extends EICController { this.loadWindow( 'dashboards/MainDashboardView', { - title: 'Main dashboard', + title: '3D view', static: true, - expanded: true + expanded: false, + windowStyle:{ + width: '800px', + height: '600px', + left: '50px', + top: '100px', + } }, { - models: models + models: models, + camName: 'persp1' } ) + this.loadWindow( + 'dashboards/MainDashboardView', + { + title: '2D View', + static: true, + expanded: false, + windowStyle:{ + width: '600px', + height: '450px', + right:'10px', + top:'100px', + } + }, + { + models: models, + camName: 'cam2Dtop' + } + ) } } diff --git a/app/libs/EIC/EICController.js b/app/libs/EIC/EICController.js index c99104a..f8bffab 100755 --- a/app/libs/EIC/EICController.js +++ b/app/libs/EIC/EICController.js @@ -103,6 +103,11 @@ class EICController extends Controller {
`); if(options.expanded) content.setAttribute('expanded',''); + if(options.windowStyle){ + for(const k in options.windowStyle){ + content.style[k] = options.windowStyle[k] + } + } let container = content.querySelector('section'); container.innerHTML = Controller.processTemplate(options.name, html, data); @@ -291,7 +296,8 @@ class EICController extends Controller { } attach(content) { - ui.show(content.view.el,!content.expanded ? 'grid': 'block'); + //ui.show(content.view.el,!content.expanded ? 'grid': 'block'); + ui.show(content.view.el, 'flex'); content.visible = true; } diff --git a/app/thirdparty/Threetobus/threetobus.module.js b/app/thirdparty/Threetobus/threetobus.module.js index 49c82e3..cce5196 100644 --- a/app/thirdparty/Threetobus/threetobus.module.js +++ b/app/thirdparty/Threetobus/threetobus.module.js @@ -5,79 +5,109 @@ export class Threetobus{ constructor(canvasEl){ this.canvasEl = canvasEl + this.cameras = {} } - init(){ + initScene(){ // Scene - this.scene = new THREE.Scene() - //scene.background = new THREE.Color(0x202080) + this.scene = new THREE.Scene() + + // Cameras + this.cameras.persp1 = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000) + this.cameras.persp1.position.set(3, 3, 5) + const aspect = window.innerWidth / window.innerHeight + const frustumSize = 10 + this.cameras.cam2Dtop = new THREE.OrthographicCamera( + -frustumSize * aspect / 2, + frustumSize * aspect / 2, + frustumSize / 2, + -frustumSize / 2, + 0.1, + 1000 + ) + this.cameras.cam2Dtop.position.set(0, 100, 0) + this.cameras.cam2Dtop.lookAt(0, 0, 0) + //this.camera = this.cameras.persp1 + + // Lights + const light = new THREE.DirectionalLight(0xffffff, 1) + light.position.set(5, 5, 5) + light.intensity = 2 + this.scene.add(light) + this.scene.add(new THREE.AmbientLight(0xffffff, 0.4)) + + // Renderer + this.renderer = new THREE.WebGLRenderer({ antialias: true, canvas: this.canvasEl }) + + } + + startRendering(){ + //controls + this.controls = new OrbitControls(this.camera, this.renderer.domElement) + //this.renderer.render(this.scene, this.camera) + + window.addEventListener('resize', () => { + this.camera.aspect = window.innerWidth / window.innerHeight + this.camera.updateProjectionMatrix() + renderer.setSize(window.innerWidth, window.innerHeight) + }) - // Camera - this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000) - this.camera.position.set(3, 3, 5) + this.render() + } - // Renderer - this.renderer = new THREE.WebGLRenderer({ antialias: true, canvas: this.canvasEl }) + changeCamera(camName){ + if(camName in this.cameras){ + this.camera = this.cameras[camName] + } + } - //renderer.setSize(window.innerWidth, window.innerHeight) - - // Cube - const geometry = new THREE.BoxGeometry() - const material = new THREE.MeshStandardMaterial({ color: 'red' }) - this.cube = new THREE.Mesh(geometry, material) - this.scene.add(this.cube) - this.cube.position.x+=2 - - - // Light - const light = new THREE.DirectionalLight(0xffffff, 1) - light.position.set(5, 5, 5) - light.intensity = 2 - this.scene.add(light) - this.scene.add(new THREE.AmbientLight(0xffffff, 0.4)) - - this.controls = new OrbitControls(this.camera, this.renderer.domElement) - this.renderer.render(this.scene, this.camera) - - window.addEventListener('resize', () => { - this.camera.aspect = window.innerWidth / window.innerHeight - this.camera.updateProjectionMatrix() - renderer.setSize(window.innerWidth, window.innerHeight) + buildFromJSON(desc){ + let obj + if(desc.type === 'Mesh') { + const geom = new THREE[desc.geometry.type](...(desc.geometry.args || [])) + const mat = new THREE[desc.material.type]( desc.material.color ? { color: desc.material.color } : {} ) + 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 => { + obj.add(this.buildFromJSON(childDesc)) }) - this.animate() - - this._render() - } + + return obj + } - _resizeRendererToDisplaySize() { - const canvas = this.renderer.domElement - const width = canvas.clientWidth - const height = canvas.clientHeight - if (canvas.width !== width || canvas.height !== height) { - this.renderer.setSize(width, height, false) - return true - } - return false + _resizeRendererToDisplaySize() { + const canvas = this.renderer.domElement + const width = canvas.clientWidth + const height = canvas.clientHeight + if (canvas.width !== width || canvas.height !== height) { + this.renderer.setSize(width, height, false) + return true } + return false + } - _render() { - if (this._resizeRendererToDisplaySize()) { - this.camera.aspect = this.renderer.domElement.clientWidth / this.renderer.domElement.clientHeight - this.camera.updateProjectionMatrix() - } - this.renderer.render(this.scene, this.camera) - requestAnimationFrame(this._render.bind(this)) + render() { + if(this._resizeRendererToDisplaySize()) { + this.camera.aspect = this.renderer.domElement.clientWidth / this.renderer.domElement.clientHeight + this.camera.updateProjectionMatrix() } + this.renderer.render(this.scene, this.camera) + requestAnimationFrame(this.render.bind(this)) + } - - animate() { - requestAnimationFrame(this.animate.bind(this)) - this.cube.rotation.x += 0.01 - this.cube.rotation.y += 0.01 - this.controls.update() - this.renderer.render(this.scene, this.camera) - } } diff --git a/app/views/dashboards/MainDashboardView.js b/app/views/dashboards/MainDashboardView.js index 2a7af6b..6a182eb 100644 --- a/app/views/dashboards/MainDashboardView.js +++ b/app/views/dashboards/MainDashboardView.js @@ -1,23 +1,33 @@ class MainDashboardView extends EICDomContent { + + //TODO should come from the API, from some sprites lib. (allow switching representations) agentTypes = { molecule1:{ - type: 'circle', - attrs: { - r: 10, - fill: '#BFB', - stroke: "#0A0", - strokeWidth: 2, - } + "type": "Mesh", + "geometry": { "type": "BoxGeometry", "args": [1, 1, 1] }, + "material": { "type": "MeshStandardMaterial", "color": "orange" }, + "children": [ + { + "type": "Mesh", + "geometry": { "type": "SphereGeometry", "args": [0.3, 16, 16] }, + "material": { "type": "MeshStandardMaterial", "color": "blue" }, + "position": [0, 0.5, 0] + } + ] }, molecule2:{ - type: 'circle', - attrs: { - r: 10, - fill: '#BBF', - stroke: "#00A", - strokeWidth: 2, - } + "type": "Mesh", + "geometry": { "type": "SphereGeometry", "args": [1, 1, 1] }, + "material": { "type": "MeshStandardMaterial", "color": "green" }, + "children": [ + { + "type": "Mesh", + "geometry": { "type": "SphereGeometry", "args": [0.3, 16, 16] }, + "material": { "type": "MeshStandardMaterial", "color": "red" }, + "position": [0, 1, 0] + } + ] } } @@ -25,41 +35,36 @@ class MainDashboardView extends EICDomContent { constructor() { super() Object.assign(this, app.helpers.activeAttributes) - //this.tileMarkup = app.Assets.Store.html['/app/assets/html/mailing/tile.html'] - } - - DOMContentLoaded(options) { - for(let model in options.models) this[model] = options.models[model] - const components = ui.eicfy(this.el) - this.setupTriggers(components) - this.setupRefs(components) - - this.ttb = new app.LoadedModules.Threetobus(this.outputs.paper43) - this.ttb.init() - } DOMContentFocused(options) { // Avoid 2nd refesh on DomContentLoaded if(this.wasBlured){ - //this.refreshSearch() + //this.refreshyoustuff() } this.wasBlured = false } DOMContentBlured(options) { this.wasBlured = true } - createAgent(agentType, id, x, y){ - if(!Object.keys(this.agentTypes).includes(agentType)) return - this.agentTypes[agentType] - const svgAgent = this.snaptobus.snap[this.agentTypes[agentType].type]().attr(this.agentTypes[agentType].attrs) - svgAgent.attr({ - id: id, - cx: x, - cy:y, - }) + DOMContentLoaded(options) { + for(let model in options.models) this[model] = options.models[model] + const components = ui.eicfy(this.el) + this.setupTriggers(components) + this.setupRefs(components) + + this.ttb = new app.LoadedModules.Threetobus(this.outputs.paper43) + this.ttb.initScene() + this.ttb.changeCamera(options.camName) + this.ttb.startRendering() + + const m1 = this.ttb.buildFromJSON(this.agentTypes.molecule1) + m1.name = 'toto' + this.ttb.scene.add(m1) } + + } app.registerClass('MainDashboardView', MainDashboardView)