UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

127 lines (98 loc) 3.32 kB
import { assert } from "../../../core/assert.js"; import Name from "../../ecs/name/Name.js"; import { BoundQuaternionWriter } from "../curve/binding/BoundQuaternionWriter.js"; import { BoundValueWriter } from "../curve/binding/BoundValueWriter.js"; import { BoundVector3Writer } from "../curve/binding/BoundVector3Writer.js"; /** * * @param {EntityNode} node * @returns {string|undefined} */ function get_node_name(node) { /** * @type {Name} */ const name = node.entity.getComponent(Name); if (name === null) { return undefined; } return name.getValue(); } /** * Following THREE.js PropertyBinding.findNode implementation * @param {EntityNode} root * @param {string} node_name * @returns {EntityNode|undefined} */ function find_node(root, node_name) { assert.isString(node_name, 'node_name'); const root_name = get_node_name(root); if (root_name === node_name) { return root; } // search into node subtree. const children = root.children; const child_count = children.length; for (let j = 0; j < child_count; j++) { /** * @type {EntityNode} */ const child = children[j]; const subtree_result = find_node(child, node_name); if (subtree_result !== undefined) { return subtree_result; } } } /** * * @param {EntityNode} root * @param {string[]} path_parts * @param {number} part_first * @param {number} part_last */ function entity_node_resolve_path(root, path_parts, part_first, part_last) { assert.isNonNegativeInteger(part_first, 'part_first'); assert.isNonNegativeInteger(part_last, 'part_last'); assert.lessThan(part_last, path_parts.length, 'overflow'); let node = root; for (let i = part_first; i <= part_last; i++) { const part = path_parts[i]; const sub_node = find_node(node, part); if (sub_node === undefined) { throw new Error(`Child '${part}' not found, at index ${i} of [${path_parts.join(', ')}]. Valid names at this level: [${node.children.map(get_node_name)}]`); } node = sub_node; } return node; } /** * * @param {EntityNode} node * @param {string[]} path_parts * @returns {BoundValueWriter} */ export function bind_property_writer(node, path_parts) { assert.defined(path_parts, 'path_parts'); assert.isArray(path_parts, 'path_parts'); const part_count = path_parts.length; const property_name = path_parts[part_count - 1]; const parent = entity_node_resolve_path(node, path_parts, 0, part_count - 2); let writer; switch (property_name) { case "position": writer = new BoundVector3Writer(parent.transform.position); break; case "quaternion": writer = new BoundQuaternionWriter(parent.transform.rotation); break; case "scale": writer = new BoundVector3Writer(parent.transform.scale); break; default: console.log(`Unsupported property name: ${property_name}`); // NO-OP writer = new BoundValueWriter(); } return writer; }