Overview

Scene3D Designer

Designer 3D visuale su route #/scene3d_designer. Consente di comporre una scena

tridimensionale (three.js), associarne gli oggetti alle route scaffoldate

dell'app e pubblicarla in sola lettura tramite lo Scene3D Viewer (#/scene3d_viewer/:scene_key).

Scope

  • Authoring di scene 3D con primitive, asset importati e componenti data-driven.
  • Materiali PBR, shader personalizzati, luci, ombre e — opzionale — path tracing.
  • Renderer selezionabile: WebGL (default) o WebGPU (opt-in), con fallback automatico.
  • Binding di ciascun oggetto a una route WUIC (con record opzionale) per pilotare

proprietà visive dai dati e aprire la CRUD della route con doppio click.

  • Persistenza della scena su _wuic_scene3d (scene_json) e riapertura runtime

read-only nel viewer.

Palette

Pannello "Oggetti" (sinistra): trascina/clicca una voce per aggiungere l'oggetto

al centro della scena. Ogni oggetto è un THREE.Object3D con geometria e materiale

serializzabili. Gli helper di viewport (griglia, gizmo, luci) sono marcati

userData.wuicTransient e non vengono mai persistiti.

  • Primitive: cubo, sfera, piano, cilindro, cono, toro.
  • Gruppo: contenitore per raggruppare e trasformare più oggetti insieme.
  • Luci: ambiente, direzionale, puntiforme, faretto (spot).
  • Camera: punto di vista autorabile, usato dal viewer e dall'anteprima.
  • Testo 3D: testo estruso.
  • Mesh Repeater: griglia/anello/carosello di istanze generate dai dati (DATAREPEATER 3D).
  • Import asset: modello esterno (glTF/GLB, OBJ, FBX, STL, DAE).

La palette è estendibile da metadata: i tipi custom definiti nella route

scene3d_object_type compaiono automaticamente accanto ai tipi built-in.

Import asset

Oltre alle primitive di palette, il designer importa modelli esterni tramite gli

asset loader di three.js. Formati supportati:

  • glTF / GLB (.gltf, .glb) — formato di trasporto raccomandato (PBR, animazioni).
  • OBJ (.obj) — geometria + materiali (.mtl) opzionali.
  • FBX (.fbx) — mesh, gerarchie e animazioni.
  • STL (.stl) — mesh solida (tipico CAD / stampa 3D).
  • DAE / COLLADA (.dae) — scene con gerarchia e materiali.

L'asset importato viene inglobato nel gruppo-contenuto della scena e serializzato

con il resto del payload, così la scena resta autoconsistente nel viewer.

Property panel

Pannello "Proprietà" (destra), attivo sull'oggetto selezionato:

  • Nome, Posizione (x/y/z), Rotazione (gradi), Scala, Colore.
  • Materiale (PBR): metalness, roughness, emissivo, opacità, wireframe, flat

shading, facce (fronte/retro/doppie). Per il materiale fisico anche

transmission, IOR, spessore e assorbimento volumetrico (vetro colorato).

  • Gizmo: alla selezione l'oggetto mostra insieme gli handle di traslazione

(frecce) e di rotazione (anelli). Scorciatoie: g = sposta, r = ruota,

s = scala.

Effetti shader

Ogni mesh può ricevere un effetto shader oltre al materiale standard:

  • Effetto JSON (con schema): un piccolo JSON descrive l'effetto (base uv/tinta/normale,

pulsazione, luce, displacement, opacità) e viene compilato per il renderer attivo —

GLSL su WebGL, node-material su WebGPU. Si edita con un editor JSON dotato di

autocompletamento e validazione, con vista alternativa "a struttura".

  • Shader GLSL custom: vertex/fragment shader scritti a mano (uniform uTime

animata). Disponibile solo col renderer WebGL.

Renderer WebGL / WebGPU

  • WebGL (default): rendering three.js classico, massima compatibilità.
  • WebGPU (opt-in dalla toolbar): renderer a node-materials, attivo se il

browser lo supporta; in caso contrario resta automaticamente su WebGL. La

modalità scelta viene salvata con la scena e ripristinata all'apertura.

  • Alcune funzioni restano WebGL-only e vengono segnalate quando il renderer

WebGPU è attivo: gli shader GLSL custom (sostituiti da un materiale di fallback

e ripristinati tornando a WebGL) e il path tracing.

  • Designer e viewer sono caricati lazy (import(...)): three.js resta

code-split e non entra nel bundle iniziale né nel barrel della libreria.

Illuminazione

  • Luci di scena: direzionali, puntiformi, spot e ambiente, con ombre morbide.
  • Bake luci (per-vertice): cuoce l'illuminazione statica nei vertex color e

passa a un materiale unlit — luce "fissa" indipendente dalle luci runtime. Con

il renderer WebGPU il bake gira su compute shader (ombre incluse), molto più

veloce sulle scene dense.

  • Path tracing (renderer WebGL): modalità di anteprima fotorealistica

progressiva con illuminazione globale, ombre morbide e ombre colorate

attraverso i materiali in transmission.

Animazioni e fisica

  • Animazioni / timeline: le clip degli asset importati (glTF/GLB) hanno un

transport (play/pausa/stop/scrubber) nel designer e vanno in autoplay nel viewer.

  • Fisica (opzionale): authoring per-oggetto (statico/dinamico/kinematico,

forma di collisione, massa, attrito, rimbalzo) con simulazione Play/Stop nel

designer e autoplay opzionale nel viewer.

Camera e anteprima

  • Camera autorata: la si posiziona come qualsiasi oggetto; il viewer può

aprirsi dal suo punto di vista (#/scene3d_viewer/:scene_key/:camera_id).

  • Anteprima camera: popup real-time con la vista della camera selezionata,

utile per inquadrare prima di pubblicare.

Route binding + click → CRUD

Sezione "Binding rotta" del property panel:

  • Rotta: la route metadata WUIC a cui l'oggetto è legato (es. prodotti).
  • Record ID (opzionale): binding a un record specifico; vuoto = binding di rotta.
  • Mappa campi: associa proprietà visive (etichetta, colore, visibilità) alle

colonne della route, così il viewer applica i dati reali agli oggetti.

  • Doppio click su un oggetto bindato nel viewer apre la CRUD della route

(parametric-dialog di edit/detail del record collegato).

Mesh Repeater

Il Mesh Repeater (DATAREPEATER 3D) è un oggetto di palette che, invece di

rappresentare un singolo mesh, genera N istanze dai dati di una route: una

mesh per record, disposte secondo un archetipo di layout (carosello su disco

con frecce di navigazione, griglia, anello). È l'equivalente 3D di una

list-grid: le istanze sono ricostruite dai dati e non vengono serializzate nel

JSON della scena — il viewer le rigenera al caricamento. Il repeater si

sposta/ruota come un gruppo con i gizmo; il pulsante Rigenera (o il toggle

Auto-rigenera) rifà il fetch e ricostruisce le mesh.

Sorgente dati e mappatura

  • Rotta + Max record: la route WUIC che alimenta il repeater e quanti

record caricare (prima pagina).

  • Sorgente mesh: come si ottiene la mesh di ogni istanza —

- Fisso: la stessa primitiva/asset per tutti i record;

- Colonna: il tipo di primitiva è deciso da una colonna;

- Asset (colonna): modello reale per record, caricato da una colonna di

upload che contiene un file GLB/OBJ/STL (mesh product-like anziché box generici).

  • Mappa campi → colonne: binding per-istanza di posizione (Pos X/Y/Z),

rotazione (Rot X/Y/Z), scala, etichetta e colore alle colonne della route.

Layout e trasformazioni

  • Archetipo: carosello (disco con frecce avanti/indietro), griglia, anello. Il

carosello espone raggio del disco, colore disco e dimensione delle frecce.

  • Scala: normalizzazione automatica (ogni asset portato a dimensione unitaria)

più una scala di layout applicata dall'archetipo — così modelli di dimensioni

molto diverse risultano uniformi.

  • Offset verticale (meshYOffset) e rotazione X/Y/Z (meshRotX/Y/Z) per

ritoccare posa e altezza rispetto al disco; le mesh sono ancorate alla base per

non compenetrare la superficie del carosello.

  • Auto-rigenera: toggle di toolbar che rigenera automaticamente (con debounce)

a ogni cambio di proprietà, senza premere Rigenera.

Interazioni (callback JS)

Sezione collassabile in fondo al pannello del repeater: per gli eventi click,

doppio-click e tasto destro su un'istanza si scrive un callback JS (editor

Monaco). Vale sia nel designer sia nel viewer. Il contesto espone:

  • record — il record dell'istanza colpita (raycast), coi campi già unwrappati;
  • mesh — l'Object3D cliccato; oltre a event, scene, camera, THREE;
  • wuic.showItemPopup(opts) — helper per un popup "campi + anteprima mesh";

wuic.closePopup() per chiuderlo.

showItemPopup accetta: mode (1 overlay HTML con anteprima 3D live / 2

pannello 3D nella scena, billboard verso la camera), fields (colonne da mostrare),

title, dimensioni width/height (px o %), panelBg, swap (inverte i lati

mesh/campi), maximizable, verticalPosition/horizontalPosition e

autorotateMesh (false = ruoti il modello col mouse). Nell'anteprima overlay la

rotella fa zoom.

Snippet 1js
// Callback "click": popup con l'anteprima del modello + alcuni campi del record.
wuic.showItemPopup({
  mode: 1,
  title: record.StockItemName,
  fields: ['StockItemName', 'UnitPrice', 'Brand'],
  maximizable: true,
  autorotateMesh: false // ispeziona il modello ruotandolo col mouse

Anteprime automatiche

Al salvataggio, il designer cattura il canvas GPU già renderizzato e genera

un'anteprima della scena (in modo asincrono, senza rallentare il salvataggio).

L'anteprima compare nell'elenco "Carica scena" accanto al nome, così le scene si

riconoscono a colpo d'occhio. Non serve alcuna configurazione né processo esterno.

Permessi

  • Le route designer/viewer richiedono la feature scene3d-designer

(requireFeature sul route guard): senza la feature abilitata la route non è

raggiungibile.

  • Il binding rispetta i permessi della route target: l'apertura CRUD dal viewer

passa dal normale controllo di autorizzazione della route bindata.

  • La persistenza usa i metodi MetaService.saveScene3d / getScene3ds /

loadScene3d (metadata DB, tabella _wuic_scene3d), soggetti all'autenticazione

standard (cookie k-user).

Integrazione client/server

  • Client:

- authoring scena, interazioni viewport, gizmo, property panel e binding;

- serializzazione THREE.Object3D.toJSON() in { version:1, scene, bindings?, viewport?, physics? };

- cattura dell'anteprima dal canvas al salvataggio.

  • Server:

- upsert/lettura scena su _wuic_scene3d.s3d_scene_json (schema creato/aggiornato

automaticamente al primo uso, cross-DBMS);

- risoluzione dati delle route bindate lato viewer.

Note operative

  • Salvare prima di navigare via: un guard canDeactivate avvisa in presenza di

modifiche non salvate.

  • Mantenere nomi oggetto stabili per binding e debugging.
  • Verificare che le route bindate esistano nei metadata prima di pubblicare la

scena nel viewer.

  • WebGPU richiede un browser recente con supporto attivo; in mancanza, il designer

resta su WebGL senza alcun intervento.

Screenshot

scene3d-designer / Mesh Repeater carousel (asset per-record)
scene3d-designer / Mesh Repeater carousel (asset per-record)
scene3d-designer / Popup item da callback click (campi + preview mesh)
scene3d-designer / Popup item da callback click (campi + preview mesh)