Node group colors and toggling (draft)
This commit is contained in:
@@ -34,8 +34,46 @@ export default class extends Controller {
|
||||
*/
|
||||
const id = event?.params.node;
|
||||
const status = event?.target?.checked;
|
||||
ATON.getSceneNode(id).toggle(status);
|
||||
AppState.normalizedNodes.find(n => n.id === id).active = status;
|
||||
const node = AppState.normalizedNodes.find(n => n.id === id);
|
||||
|
||||
if (node.children.length > 0) {
|
||||
this.#toggleGroup(node, status);
|
||||
this.#syncGroupCheckboxes(node, status, this.layersTarget);
|
||||
} else {
|
||||
ATON.getSceneNode(id).toggle(status);
|
||||
node.active = status;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Recursively toggle children in a nodes group
|
||||
* @param {Object} groupNode
|
||||
* @param {Boolean} status
|
||||
*/
|
||||
#toggleGroup(groupNode, status) {
|
||||
for (const child of groupNode.children) {
|
||||
if (child.model) {
|
||||
ATON.getSceneNode(child.id).toggle(status);
|
||||
child.active = status;
|
||||
}
|
||||
if (child.children.length > 0) {
|
||||
this.#toggleGroup(child, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
#syncGroupCheckboxes(groupNode, status, container) {
|
||||
for (const child of groupNode.children) {
|
||||
const checkbox = container.querySelector(
|
||||
`[data-menu-node-param="${child.id}"]`
|
||||
);
|
||||
|
||||
console.debug(checkbox, child.id);
|
||||
|
||||
if (checkbox) checkbox.checked = status;
|
||||
|
||||
if (child.children.length > 0) {
|
||||
this.#syncGroupCheckboxes(child, status, container);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Clone a <template> by id
|
||||
|
||||
@@ -79,6 +79,11 @@ function loadNodes(nodes) {
|
||||
node.load(n.model);
|
||||
node.setRotation(...config.scene.initRotation);
|
||||
|
||||
node.setMaterial(new THREE.MeshPhongMaterial({
|
||||
transparent: false,
|
||||
color: n.color ?? '#fff',
|
||||
}));
|
||||
|
||||
// Apply any transparency before attaching to scene
|
||||
if (n.opacity !== undefined && n.opacity !== null) {
|
||||
node.setMaterial(new THREE.MeshPhongMaterial({
|
||||
|
||||
@@ -28,41 +28,49 @@
|
||||
* @param {Array} flatList
|
||||
* @param {Number} depth
|
||||
*/
|
||||
function traverse(node, flatList, depth = 1) {
|
||||
function traverseTree(node, flatList, depth = 1, inheritedColor = null) {
|
||||
if (!node.label) {
|
||||
console.error("Node missing label:", node);
|
||||
return;
|
||||
}
|
||||
|
||||
const color = node.color ?? inheritedColor;
|
||||
|
||||
const normNode = {
|
||||
...node,
|
||||
id: node.id ?? node.label,
|
||||
isMain: node.isMain ?? false,
|
||||
active: true,
|
||||
color: color ?? null,
|
||||
depth,
|
||||
children: [],
|
||||
};
|
||||
if (node.model) {
|
||||
normNode.model = node.model;
|
||||
}
|
||||
flatList.push({
|
||||
...normNode,
|
||||
depth
|
||||
});
|
||||
|
||||
flatList.push(normNode);
|
||||
|
||||
if (node.children && Array.isArray(node.children)) {
|
||||
for(let child of node.children) {
|
||||
traverse(child, flatList, depth + 1);
|
||||
for(const child of node.children) {
|
||||
normNode.children.push(
|
||||
traverseTree(child, flatList, depth + 1, color)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return normNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a flat list of nodes from
|
||||
* the nested structure in config
|
||||
* @param {Array} nodes
|
||||
* @returns {NormalizedSceneNode[]} A flat list of nodes
|
||||
* @returns {{flat: NormalizedSceneNode[], normNode: object}} A flat list of nodes
|
||||
**/
|
||||
export function normalizeNodes (nodes) {
|
||||
let flatList = [];
|
||||
traverse(nodes, flatList);
|
||||
const normNode = traverseTree(nodes, flatList);
|
||||
|
||||
return flatList;
|
||||
return {flat: flatList, normNode};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user