ageent preview & select in KF editor
This commit is contained in:
@@ -137,7 +137,7 @@ menu[eicmenu] [menuitem] > a > button, menu[eicmenu] [menuitem] > .nolink button
|
||||
[eicapp] .app-workspace .window > header .controls button.shrink { display: none; }
|
||||
[eicapp] .app-workspace .window > section {
|
||||
cursor: default;
|
||||
overflow: auto;
|
||||
overflow: hidden;
|
||||
transition: all 0.5s;
|
||||
flex: 1 1 auto;
|
||||
width: 100%;
|
||||
@@ -271,6 +271,25 @@ article[eiccard][media] > header {
|
||||
padding: var(--eicui-base-spacing-l) var(--eicui-base-spacing-m) var(--eicui-base-spacing-s) var(--eicui-base-spacing-m);
|
||||
}
|
||||
|
||||
[eicapp] select {
|
||||
width: 100%;
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
color: #DDD;
|
||||
border: 1px solid #444;
|
||||
border-radius: 2rem;
|
||||
padding: .3rem 2rem .3rem 1rem;
|
||||
font-size: 15px;
|
||||
cursor: pointer;
|
||||
margin: 0.5rem 0 0.5rem 0;
|
||||
background:
|
||||
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpolyline points='4 8 12 16 20 8' stroke='green' stroke-width='3' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")
|
||||
no-repeat right 12px center / 12px 12px,
|
||||
linear-gradient(0deg, #353, #222) no-repeat padding-box;
|
||||
|
||||
}
|
||||
|
||||
.eic-session {
|
||||
padding: 0;
|
||||
display: grid;
|
||||
|
||||
@@ -16,24 +16,6 @@ class EditorsController extends WindozController {
|
||||
agents : new AgentsModel('/agents')
|
||||
}
|
||||
|
||||
// const ttb = new app.LoadedModules.Threetobus({
|
||||
// eventsMapping: this.eventsMapping,
|
||||
// sceneSize: this.arenaConfig.arenaSize,
|
||||
// })
|
||||
// ttb.initScene({
|
||||
// axes: true,
|
||||
// grid: true,
|
||||
// })
|
||||
|
||||
// this.agentDefs = await models.agents.getSprites('Basic 3D')
|
||||
// const a1 = ttb.agentFromJSON('agent42', this.agentDefs.nocode1)
|
||||
// const a2 = ttb.agentFromJSON('agent42', this.agentDefs.nocode2)
|
||||
// ttb.scene.add(a1)
|
||||
// ttb.scene.add(a2)
|
||||
|
||||
//TODO: eventsMapping: address child by suffix in assignations
|
||||
|
||||
|
||||
this.loadWindow(
|
||||
'editors/KeyframeView',
|
||||
{
|
||||
@@ -45,8 +27,6 @@ class EditorsController extends WindozController {
|
||||
},
|
||||
{
|
||||
models: models,
|
||||
agentDefs: this.agentDefs,
|
||||
//ttb: ttb,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -23,16 +23,16 @@
|
||||
"AgentsModel"
|
||||
],
|
||||
"views": [
|
||||
"editors/KeyframeView"
|
||||
{"view":"editors/KeyframeView", "dependencies": ["editors/modules/agentPreview.module"]}
|
||||
],
|
||||
"controllerDependencies": [
|
||||
"/helpers/basicDialogs",
|
||||
"/helpers/validators",
|
||||
"/helpers/activeAttributes",
|
||||
"/thirdparty/Threetobus/three.module",
|
||||
"/thirdparty/Threetobus/OrbitControls.module",
|
||||
"/thirdparty/Threetobus/tween.module",
|
||||
"/thirdparty/Threetobus/threetobus.module"
|
||||
"/helpers/helpers3D.module",
|
||||
"/thirdparty/Three/three.module",
|
||||
"/thirdparty/Three/OrbitControls.module",
|
||||
"/thirdparty/Three/tween.module"
|
||||
],
|
||||
"assets": {
|
||||
"styles": [
|
||||
|
||||
@@ -3,7 +3,6 @@ class DashboardsController extends WindozController {
|
||||
constructor(params) {
|
||||
super(params)
|
||||
this.arenaConfig = app.Assets.Store.json.arenaConfig
|
||||
this.agentDefs = app.Assets.Store.json.agentDefs
|
||||
this.eventsMapping = app.Assets.Store.json.eventsMapping
|
||||
}
|
||||
|
||||
@@ -28,8 +27,8 @@ class DashboardsController extends WindozController {
|
||||
})
|
||||
|
||||
this.agentDefs = await models.agents.getSprites('Basic 3D')
|
||||
const a1 = ttb.agentFromJSON('agent42', this.agentDefs.nocode1)
|
||||
const a2 = ttb.agentFromJSON('agent42', this.agentDefs.nocode2)
|
||||
const a1 = ttb.createAgent('agent42', this.agentDefs.nocode1)
|
||||
const a2 = ttb.createAgent('agent42', this.agentDefs.nocode2)
|
||||
ttb.scene.add(a1)
|
||||
ttb.scene.add(a2)
|
||||
|
||||
|
||||
@@ -22,9 +22,10 @@
|
||||
"/helpers/basicDialogs",
|
||||
"/helpers/validators",
|
||||
"/helpers/activeAttributes",
|
||||
"/thirdparty/Threetobus/three.module",
|
||||
"/thirdparty/Threetobus/OrbitControls.module",
|
||||
"/thirdparty/Threetobus/tween.module",
|
||||
"/helpers/helpers3D.module",
|
||||
"/thirdparty/Three/three.module",
|
||||
"/thirdparty/Three/OrbitControls.module",
|
||||
"/thirdparty/Three/tween.module",
|
||||
"/thirdparty/Threetobus/threetobus.module"
|
||||
],
|
||||
"assets": {
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+6
-43
@@ -1,10 +1,11 @@
|
||||
import * as THREE from './three.module.js'
|
||||
import { OrbitControls } from './OrbitControls.module.js'
|
||||
import * as TWEEN from './tween.module.js'
|
||||
import * as THREE from '../Three/three.module.js'
|
||||
import { OrbitControls } from '../Three/OrbitControls.module.js'
|
||||
import * as TWEEN from '../Three/tween.module.js'
|
||||
|
||||
export class Threetobus{
|
||||
|
||||
constructor(options){
|
||||
Object.assign(this, app.helpers.helpers3D)
|
||||
this._curEventsMapping = []
|
||||
this._stagedEventsMapping = options.eventsMapping
|
||||
this.sceneSize = options.sceneSize
|
||||
@@ -214,47 +215,9 @@ export class Threetobus{
|
||||
return(renderEngine)
|
||||
}
|
||||
|
||||
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
|
||||
createAgent(id, desc){
|
||||
this.tweensRegistry[id] = { 'move': null, 'rotate': null }
|
||||
return obj
|
||||
return(this.agentFromJSON(id, desc))
|
||||
}
|
||||
|
||||
smoothMove(options){
|
||||
|
||||
@@ -1,16 +1,25 @@
|
||||
<style>
|
||||
canvas[data-output="kfeCanvas"]{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.kf-editor{
|
||||
grid-template-columns: 15% auto 20%;
|
||||
grid-gap:0;
|
||||
height: 100%;
|
||||
}
|
||||
.kf-editor > article{
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
.kf-editor > article, .kf-editor > article header{ border-color: #473; }
|
||||
.kf-editor article.agent-preview header { padding:0; }
|
||||
.kf-editor article.agent-preview canvas{ width:100%; height:100%; }
|
||||
|
||||
</style>
|
||||
<div class="kf-editor cols-3">
|
||||
<article eiccard="">
|
||||
<header>Agent show</header>
|
||||
<section>agents selector</section>
|
||||
<article eiccard class="agent-preview">
|
||||
<header><canvas data-output="agentSampleCanvas"></canvas></header>
|
||||
<section>
|
||||
agents selector
|
||||
<select data-output="agentsSelector"></select>
|
||||
</section>
|
||||
</article>
|
||||
<article eiccard="" data-eicui-id="d9aace9b-9e60-4cfc-ad7c-98b9693d05f3" aria-enabled="true">
|
||||
<section>
|
||||
@@ -25,5 +34,3 @@
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- <canvas data-output="kfeCanvas"></canvas> -->
|
||||
|
||||
@@ -3,7 +3,6 @@ class KeyframeView extends WindozDomContent {
|
||||
constructor() {
|
||||
super()
|
||||
Object.assign(this, app.helpers.activeAttributes)
|
||||
//this.tileMarkup = app.Assets.Store.html['/app/assets/html/mailing/tile.html']
|
||||
}
|
||||
|
||||
DOMContentFocused(options) {
|
||||
@@ -15,34 +14,29 @@ class KeyframeView extends WindozDomContent {
|
||||
|
||||
DOMContentBlured(options) { this.wasBlured = true }
|
||||
|
||||
DOMContentLoaded(options) {
|
||||
async DOMContentLoaded(options) {
|
||||
this.windowPrefsId = `editors.keyframeview`
|
||||
for(let model in options.models) this[model] = options.models[model]
|
||||
// this.kfe = options.kfe
|
||||
this.models = options.models
|
||||
const components = ui.eicfy(this.el)
|
||||
this.setupTriggers(components)
|
||||
this.setupRefs(components)
|
||||
// this.renderingEngine = this.kfe.startRendering(this.outputs.kfeCanvas, options.mode)
|
||||
this.output('settingsMenu',app.Assets.Store.html.spaceViewSetting)
|
||||
this.outputs.settingsMenu.querySelectorAll('input[type="toggler"]').forEach(el => {
|
||||
const tog = new InputToggler(el)
|
||||
// if(this.kfe[tog._el.name].layers){
|
||||
// tog.value = this.renderingEngine.camera.layers.test(this.kfe[tog._el.name].layers) ? 'yes' : 'no'
|
||||
// }
|
||||
tog.onToggle = this.settingsToggle.bind(this)
|
||||
})
|
||||
|
||||
|
||||
this.agentDefs = await this.models.agents.getSprites('Basic 3D')
|
||||
for(const agentType in this.agentDefs){
|
||||
const opt = new Option(agentType, agentType)
|
||||
this.outputs.agentsSelector.add(opt)
|
||||
}
|
||||
this.outputs.agentsSelector.addEventListener('change',this.onChangeAgent.bind(this))
|
||||
|
||||
this.agentPreview = new app.LoadedModules.AgentPreview(this.outputs.agentSampleCanvas, this.agentDefs)
|
||||
this.onChangeAgent()
|
||||
this.agentPreview.startRendering()
|
||||
this.agentPreview.animation = true
|
||||
}
|
||||
|
||||
settingsToggle(value, object){
|
||||
if(['grid','axes'].includes(object._el.name)){
|
||||
const layerId = {'grid':1,'axes':2}[object._el.name]
|
||||
if(value=='yes'){
|
||||
this.renderingEngine.camera.layers.enable(layerId)
|
||||
} else {
|
||||
this.renderingEngine.camera.layers.disable(layerId)
|
||||
}
|
||||
}
|
||||
//TODO save & restore in prefs
|
||||
onChangeAgent(event){
|
||||
this.agentPreview.setAgent(this.outputs.agentsSelector.value)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
import * as THREE from '/app/thirdparty/Three/three.module.js'
|
||||
import { OrbitControls } from '/app/thirdparty/Three/OrbitControls.module.js'
|
||||
import * as TWEEN from '/app/thirdparty/Three/tween.module.js'
|
||||
|
||||
export class AgentPreview{
|
||||
|
||||
constructor(canvasEl, agentDefs){
|
||||
Object.assign(this, app.helpers.helpers3D)
|
||||
this.agentDefs = app.Assets.Store.json.agentDefs
|
||||
this.canvasEl = canvasEl
|
||||
this.agentDefs = agentDefs
|
||||
this.currentAgentObj = null
|
||||
this.renderer = null
|
||||
this._animation = false
|
||||
this.initScene()
|
||||
}
|
||||
|
||||
initScene(){
|
||||
// Scene
|
||||
this.scene = new THREE.Scene()
|
||||
|
||||
// Camera
|
||||
this.camera = new THREE.PerspectiveCamera(75, this.canvasEl.clientWidth / this.canvasEl.clientHeight, 0.1, 1000)
|
||||
this.camera.position.set(3, 3, 5)
|
||||
this.camera.lookAt(0, 0, 0)
|
||||
this.camera.layers.enable(1)
|
||||
this.camera.layers.enable(2)
|
||||
|
||||
// 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))
|
||||
|
||||
this.renderer = new THREE.WebGLRenderer({ antialias: true, canvas: this.canvasEl })
|
||||
}
|
||||
|
||||
startRendering(){
|
||||
//this.renderer.addControls()
|
||||
this.renderer.render(this.scene, this.camera)
|
||||
}
|
||||
|
||||
setAgent(atype){
|
||||
if(this.currentAgentObj && (this.scene.children.includes(this.currentAgentObj))){
|
||||
this.scene.remove(this.currentAgentObj)
|
||||
}
|
||||
this.currentAgentObj = this.agentFromJSON('previewedAgent', this.agentDefs[atype])
|
||||
this.currentAgentObj.position.set(0, 0, 0)
|
||||
this.scene.add(this.currentAgentObj)
|
||||
|
||||
this.cameraAutoFrame(this.currentAgentObj, this.camera)
|
||||
}
|
||||
|
||||
set animation(value){
|
||||
this._animation = value
|
||||
if(value) this._animate()
|
||||
}
|
||||
|
||||
get animation(){
|
||||
return(this._animation)
|
||||
}
|
||||
|
||||
_animate = () => { // to avoid havind to bind(this) in requestAnimationFrame, because one bound fn per frame = continuous GC load
|
||||
if(!this.animation) return
|
||||
requestAnimationFrame(this._animate)
|
||||
this.currentAgentObj.rotation.x += 0.005
|
||||
this.currentAgentObj.rotation.y += 0.01
|
||||
this.renderer.render(this.scene, this.camera)
|
||||
}
|
||||
}
|
||||
|
||||
// Make this module available to common JS
|
||||
if(!app.LoadedModules) app.LoadedModules = {}
|
||||
app.LoadedModules.AgentPreview = AgentPreview
|
||||
|
||||
Reference in New Issue
Block a user