agent def + windows fixes + 2d view + 3d view

This commit is contained in:
STEINNI
2025-09-26 21:02:32 +00:00
parent 73e2b5a762
commit dd860b45a9
5 changed files with 177 additions and 107 deletions
+11 -7
View File
@@ -37,7 +37,7 @@ body[eicapp] {
grid-template-columns: min-content auto; grid-template-columns: min-content auto;
min-height: 100vh; min-height: 100vh;
box-sizing: border-box; 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] { [eicapp] [eicapptoolbar] {
@@ -95,17 +95,20 @@ body[eicapp] {
bottom: auto; bottom: auto;
overflow: hidden; overflow: hidden;
z-index: 2; z-index: 2;
display: block;
grid-template-rows: min-content 1fr; grid-template-rows: min-content 1fr;
max-height: 90vh; max-height: 90vh;
max-width: 90vw; max-width: 90vw;
display: flex;
flex-direction: column;
} }
[eicapp] .app-workspace .window.active { [eicapp] .app-workspace .window.active {
z-index: 3; z-index: 3;
background: var(--app-color-primary); background: var(--app-color-primary);
border-radius: .3rem; 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 { [eicapp] .app-workspace .window > header h1 {
padding: var(--eicui-base-spacing-xs); padding: var(--eicui-base-spacing-xs);
color: var(--app-color-white); 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.expand { display: inline-flex; }
[eicapp] .app-workspace .window > header .controls button.shrink { display: none; } [eicapp] .app-workspace .window > header .controls button.shrink { display: none; }
[eicapp] .app-workspace .window > section { [eicapp] .app-workspace .window > section {
padding: var(--eicui-base-spacing-xs) var(--eicui-base-spacing-s); padding: var(--eicui-base-spacing-2xs) var(--eicui-base-spacing-2xs);
/*background: var(--app-bg-color);*/
cursor: default; cursor: default;
margin: 0; margin: 0;
overflow: auto; overflow: auto;
transition: all 0.5s; transition: all 0.5s;
flex: 1 1 auto;
} }
[eicapp] .app-workspace .window[device="tablet"] > section { [eicapp] .app-workspace .window[device="tablet"] > section {
padding: 0; padding: 0;
@@ -142,8 +146,8 @@ body[eicapp] {
box-shadow: none; box-shadow: none;
width: 100%; width: 100%;
max-width:none; max-width:none;
padding: 0 var(--eicui-base-spacing-2xs) var(--eicui-base-spacing-3xl) var(--eicui-base-spacing-2xs); padding: 0 var(--eicui-base-spacing-2xs) 0 var(--eicui-base-spacing-2xs);
background: repeating-linear-gradient( -45deg, #000, #555 10px, #000 10px, #555 20px ); background: repeating-linear-gradient( -45deg, #000, #333 10px, #000 10px, #333 20px );
cursor: default; cursor: default;
margin: 0; margin: 0;
overflow: visible; overflow: visible;
@@ -17,14 +17,39 @@ class DashboardsController extends EICController {
this.loadWindow( this.loadWindow(
'dashboards/MainDashboardView', 'dashboards/MainDashboardView',
{ {
title: 'Main dashboard', title: '3D view',
static: true, 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'
}
)
} }
} }
+7 -1
View File
@@ -103,6 +103,11 @@ class EICController extends Controller {
<section></section> <section></section>
</div>`); </div>`);
if(options.expanded) content.setAttribute('expanded',''); 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'); let container = content.querySelector('section');
container.innerHTML = Controller.processTemplate(options.name, html, data); container.innerHTML = Controller.processTemplate(options.name, html, data);
@@ -291,7 +296,8 @@ class EICController extends Controller {
} }
attach(content) { 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; content.visible = true;
} }
+90 -60
View File
@@ -5,79 +5,109 @@ export class Threetobus{
constructor(canvasEl){ constructor(canvasEl){
this.canvasEl = canvasEl this.canvasEl = canvasEl
this.cameras = {}
} }
init(){ initScene(){
// Scene // Scene
this.scene = new THREE.Scene() this.scene = new THREE.Scene()
//scene.background = new THREE.Color(0x202080)
// 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.render()
this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000) }
this.camera.position.set(3, 3, 5)
// Renderer changeCamera(camName){
this.renderer = new THREE.WebGLRenderer({ antialias: true, canvas: this.canvasEl }) if(camName in this.cameras){
this.camera = this.cameras[camName]
}
}
//renderer.setSize(window.innerWidth, window.innerHeight) buildFromJSON(desc){
let obj
// Cube if(desc.type === 'Mesh') {
const geometry = new THREE.BoxGeometry() const geom = new THREE[desc.geometry.type](...(desc.geometry.args || []))
const material = new THREE.MeshStandardMaterial({ color: 'red' }) const mat = new THREE[desc.material.type]( desc.material.color ? { color: desc.material.color } : {} )
this.cube = new THREE.Mesh(geometry, material) obj = new THREE.Mesh(geom, mat)
this.scene.add(this.cube) } else if(desc.type === 'Group') {
this.cube.position.x+=2 obj = new THREE.Group()
} else {
throw new Error("Unknown type: " + desc.type)
// Light }
const light = new THREE.DirectionalLight(0xffffff, 1)
light.position.set(5, 5, 5) // Apply transforms
light.intensity = 2 if(desc.position) obj.position.set(...desc.position)
this.scene.add(light) if(desc.rotation) obj.rotation.set(...desc.rotation)
this.scene.add(new THREE.AmbientLight(0xffffff, 0.4)) if(desc.scale) obj.scale.set(...desc.scale)
this.controls = new OrbitControls(this.camera, this.renderer.domElement) // Recursively add children
this.renderer.render(this.scene, this.camera) if(desc.children) {
desc.children.forEach(childDesc => {
window.addEventListener('resize', () => { obj.add(this.buildFromJSON(childDesc))
this.camera.aspect = window.innerWidth / window.innerHeight
this.camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
}) })
this.animate()
this._render()
} }
return obj
}
_resizeRendererToDisplaySize() { _resizeRendererToDisplaySize() {
const canvas = this.renderer.domElement const canvas = this.renderer.domElement
const width = canvas.clientWidth const width = canvas.clientWidth
const height = canvas.clientHeight const height = canvas.clientHeight
if (canvas.width !== width || canvas.height !== height) { if (canvas.width !== width || canvas.height !== height) {
this.renderer.setSize(width, height, false) this.renderer.setSize(width, height, false)
return true return true
}
return false
} }
return false
}
_render() { render() {
if (this._resizeRendererToDisplaySize()) { if(this._resizeRendererToDisplaySize()) {
this.camera.aspect = this.renderer.domElement.clientWidth / this.renderer.domElement.clientHeight this.camera.aspect = this.renderer.domElement.clientWidth / this.renderer.domElement.clientHeight
this.camera.updateProjectionMatrix() this.camera.updateProjectionMatrix()
}
this.renderer.render(this.scene, this.camera)
requestAnimationFrame(this._render.bind(this))
} }
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)
}
} }
+41 -36
View File
@@ -1,23 +1,33 @@
class MainDashboardView extends EICDomContent { class MainDashboardView extends EICDomContent {
//TODO should come from the API, from some sprites lib. (allow switching representations)
agentTypes = { agentTypes = {
molecule1:{ molecule1:{
type: 'circle', "type": "Mesh",
attrs: { "geometry": { "type": "BoxGeometry", "args": [1, 1, 1] },
r: 10, "material": { "type": "MeshStandardMaterial", "color": "orange" },
fill: '#BFB', "children": [
stroke: "#0A0", {
strokeWidth: 2, "type": "Mesh",
} "geometry": { "type": "SphereGeometry", "args": [0.3, 16, 16] },
"material": { "type": "MeshStandardMaterial", "color": "blue" },
"position": [0, 0.5, 0]
}
]
}, },
molecule2:{ molecule2:{
type: 'circle', "type": "Mesh",
attrs: { "geometry": { "type": "SphereGeometry", "args": [1, 1, 1] },
r: 10, "material": { "type": "MeshStandardMaterial", "color": "green" },
fill: '#BBF', "children": [
stroke: "#00A", {
strokeWidth: 2, "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() { constructor() {
super() super()
Object.assign(this, app.helpers.activeAttributes) 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) { DOMContentFocused(options) {
// Avoid 2nd refesh on DomContentLoaded // Avoid 2nd refesh on DomContentLoaded
if(this.wasBlured){ if(this.wasBlured){
//this.refreshSearch() //this.refreshyoustuff()
} }
this.wasBlured = false this.wasBlured = false
} }
DOMContentBlured(options) { this.wasBlured = true } DOMContentBlured(options) { this.wasBlured = true }
createAgent(agentType, id, x, y){ DOMContentLoaded(options) {
if(!Object.keys(this.agentTypes).includes(agentType)) return for(let model in options.models) this[model] = options.models[model]
this.agentTypes[agentType] const components = ui.eicfy(this.el)
const svgAgent = this.snaptobus.snap[this.agentTypes[agentType].type]().attr(this.agentTypes[agentType].attrs) this.setupTriggers(components)
svgAgent.attr({ this.setupRefs(components)
id: id,
cx: x, this.ttb = new app.LoadedModules.Threetobus(this.outputs.paper43)
cy:y, 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) app.registerClass('MainDashboardView', MainDashboardView)