diff --git a/config.js b/config.js index f8209e0..f5d4ca5 100644 --- a/config.js +++ b/config.js @@ -16,7 +16,7 @@ const theater2Popup = ` export const config = { scene : { - initialExposure: 0.85, + initialExposure: 0.95, autoLP: false, shadows: false, initLightDir: [0.2,-0.3,-0.7], @@ -111,6 +111,7 @@ export const config = { { label: 'Palcoscenico', model: 'models/ssgp/Teatro_SSGP_Palcoscenico.glb', + isSemantic: true, }, { label: 'Boccascena / Proscenio', diff --git a/js/scene.js b/js/scene.js index ae7c4e2..9abc68c 100644 --- a/js/scene.js +++ b/js/scene.js @@ -37,7 +37,6 @@ function init () { ATON.setMainLightDirection(new THREE.Vector3(...config.scene.initLightDir)); ATON.toggleShadows(config.scene.shadows); ATON.setExposure(config.scene.initialExposure); - // Open settings side panel when clicking on settings btn AppState.camera = ATON.Nav._camera; AppState.renderer = ATON._renderer; @@ -106,10 +105,63 @@ function loadNodes(nodes) { AppState.clipping.boundingSphere = node.getBound(); } - AppState.nodes.push({id: n.label, active: n.isInvisible ? false: true}); + if (n.isSemantic) { + createSemanticNode(n.model, n.label); + //ATON.getSemanticRoot().attach(semNode); + } + + AppState.nodes.push({ + id: n.label, + active: n.isInvisible ? false: true, + isSemantic: n.isSemantic + }); }); if (!AppState.clipping.boundingSphere) { console.error("No bounding sphere computed, clipping will fail. Ensure one node has 'isMain: true'."); } } +/** + * Uses a generic sphere shape as semantic annotation + * @param {Sphere} bound The scene node's bounding sphere + * @param {string} id The original scene node ID (3D object) + * @returns {ATON.SceneNode} +function createSemanticNode(bound, id) { + // Default/highlight materials for semantic node + let matSemDef = ATON.MatHub.materials.semanticShape; + let matSemHL = ATON.MatHub.materials.semanticShapeHL; + + const semNode = ATON.createSemanticNode(id) + .setDefaultAndHighlightMaterials(matSemDef, matSemHL) + .attachToRoot(); + + const sphereCenter = bound.center; + const sphereRadius = bound.radius * 0.2; + + let sphere = ATON.SemFactory.createSphere(id, sphereCenter, sphereRadius); + + console.debug('Bound:', bound); + console.debug('Semantic sphere:', sphere); +} +*/ + +/** + * Creates a semantic annotation from a model + * @param {string} model The model's path to load + * @param {string} id The original scene node ID (3D object) + * @returns {ATON.SceneNode} + */ +function createSemanticNode(model, id) { + // Default/highlight materials for semantic node + let matSemDef = ATON.MatHub.materials.semanticShape; + let matSemHL = ATON.MatHub.materials.semanticShapeHL; + + const semNode = ATON.createSemanticNode(id) + .load(model) + .setDefaultAndHighlightMaterials(matSemDef, matSemHL) + .attachToRoot(); + + semNode.setRotation(...config.scene.initRotation); + + return semNode; +} diff --git a/scenes/ssgp/index.js b/scenes/ssgp/index.js index b05f4b8..ac959f8 100644 --- a/scenes/ssgp/index.js +++ b/scenes/ssgp/index.js @@ -15,3 +15,17 @@ AppState.treeNodes = tree; // TODO: add Map object for lookup optimization openScene(marker, AppState.normalizedNodes); + +// General hover/leave events handling for all semantic nodes. +ATON.on("SemanticNodeHover", (semid) => { + let node = ATON.getSemanticNode(semid); + + console.debug('Sem node:', semid); + + if (node) node.highlight(); + }); + +ATON.on("SemanticNodeLeave", (semid) => { + let node = ATON.getSemanticNode(semid); + if (node) node.restoreDefaultMaterial(); +}); \ No newline at end of file