diff --git a/lib/network/modules/PhysicsEngine.js b/lib/network/modules/PhysicsEngine.js index 93065b8d..d4d7c6d9 100644 --- a/lib/network/modules/PhysicsEngine.js +++ b/lib/network/modules/PhysicsEngine.js @@ -251,9 +251,14 @@ class PhysicsEngine { this.physicsUpdateHandler = (properties) => { if (properties.options.physics !== undefined) { if (properties.options.physics) { + let nodes = {}; + nodes[properties.id] = this.createPhysicsNode(properties.id); this.physicsWorker.postMessage({ type: 'addElements', - data: this.createPhysicsNode(properties.id) + data: { + nodes: nodes, + edges: {} + } }); } else { this.physicsWorker.postMessage({type: 'removeElements', data: { @@ -480,9 +485,7 @@ class PhysicsEngine { createPhysicsNode(nodeId) { let node = this.body.nodes[nodeId]; - if (node && node.options.physics === true) { - // for updating fixed later - this.physicsBody.physicsNodeIndices.push(nodeId); + if (node) { return { id: node.id.toString(), x: node.x, @@ -498,6 +501,36 @@ class PhysicsEngine { } } + createPhysicsEdge(edgeId) { + let edge = this.body.edges[edgeId]; + if (edge && edge.options.physics === true && edge.connected === true) { + let physicsEdge = { + connected: edge.connected, + id: edge.id, + edgeType: {}, + toId: edge.toId, + fromId: edge.fromId, + to: { + id: edge.to.id + }, + from: { + id: edge.from.id + }, + options: { + length: edge.length + } + }; + if (edge.edgeType.via) { + physicsEdge.edgeType = { + via: { + id: edge.edgeType.via.id + } + } + } + return physicsEdge; + } + } + /** * Nodes and edges can have the physics toggles on or off. A collection of indices is created here so we can skip the check all the time. * @@ -510,91 +543,60 @@ class PhysicsEngine { this.physicsBody.forces = {}; this.physicsBody.physicsNodeIndices = []; this.physicsBody.physicsEdgeIndices = []; + let physicsWorkerNodes = {}; + let physicsWorkerEdges = {}; - if (this.physicsWorker) { - let physicsWorkerNodes = {}; - let physicsWorkerEdges = {}; - for (let nodeId in nodes) { - if (nodes.hasOwnProperty(nodeId)) { - physicsWorkerNodes[nodeId] = this.createPhysicsNode(nodeId); - } - } - - for (let edgeId in edges) { - if (edges.hasOwnProperty(edgeId)) { - let edge = edges[edgeId]; - if (edge.options.physics === true && edge.connected === true) { - physicsWorkerEdges[edgeId] = { - connected: edge.connected, - id: edge.id, - edgeType: {}, - toId: edge.toId, - fromId: edge.fromId, - to: { - id: edge.to.id - }, - from: { - id: edge.from.id - }, - options: { - length: edge.length - } - }; - if (edge.edgeType.via) { - physicsWorkerEdges[edgeId].edgeType = { - via: { - id: edge.edgeType.via.id - } - } - } + // get node indices for physics + for (let nodeId in nodes) { + if (nodes.hasOwnProperty(nodeId)) { + if (nodes[nodeId].options.physics === true) { + this.physicsBody.physicsNodeIndices.push(nodeId); + if (this.physicsWorker) { + physicsWorkerNodes[nodeId] = this.createPhysicsNode(nodeId); } } } + } - this.physicsWorker.postMessage({ - type: 'physicsObjects', - data: { - nodes: physicsWorkerNodes, - edges: physicsWorkerEdges - } - }); - } else { - // get node indices for physics - for (let nodeId in nodes) { - if (nodes.hasOwnProperty(nodeId)) { - if (nodes[nodeId].options.physics === true) { - this.physicsBody.physicsNodeIndices.push(nodeId); + // get edge indices for physics + for (let edgeId in edges) { + if (edges.hasOwnProperty(edgeId)) { + if (edges[edgeId].options.physics === true) { + this.physicsBody.physicsEdgeIndices.push(edgeId); + if (this.physicsWorker) { + physicsWorkerEdges[edgeId] = this.createPhysicsEdge(edgeId); } } } + } - // get edge indices for physics - for (let edgeId in edges) { - if (edges.hasOwnProperty(edgeId)) { - if (edges[edgeId].options.physics === true) { - this.physicsBody.physicsEdgeIndices.push(edgeId); - } - } - } + // get the velocity and the forces vector + for (let i = 0; i < this.physicsBody.physicsNodeIndices.length; i++) { + let nodeId = this.physicsBody.physicsNodeIndices[i]; + this.physicsBody.forces[nodeId] = {x: 0, y: 0}; - // get the velocity and the forces vector - for (let i = 0; i < this.physicsBody.physicsNodeIndices.length; i++) { - let nodeId = this.physicsBody.physicsNodeIndices[i]; - this.physicsBody.forces[nodeId] = {x: 0, y: 0}; + // forces can be reset because they are recalculated. Velocities have to persist. + if (this.physicsBody.velocities[nodeId] === undefined) { + this.physicsBody.velocities[nodeId] = {x: 0, y: 0}; + } + } - // forces can be reset because they are recalculated. Velocities have to persist. - if (this.physicsBody.velocities[nodeId] === undefined) { - this.physicsBody.velocities[nodeId] = {x: 0, y: 0}; - } + // clean deleted nodes from the velocity vector + for (let nodeId in this.physicsBody.velocities) { + if (nodes[nodeId] === undefined) { + delete this.physicsBody.velocities[nodeId]; } + } - // clean deleted nodes from the velocity vector - for (let nodeId in this.physicsBody.velocities) { - if (nodes[nodeId] === undefined) { - delete this.physicsBody.velocities[nodeId]; + if (this.physicsWorker) { + this.physicsWorker.postMessage({ + type: 'initPhysicsData', + data: { + nodes: physicsWorkerNodes, + edges: physicsWorkerEdges } - } + }); } } diff --git a/lib/network/modules/PhysicsWorker.js b/lib/network/modules/PhysicsWorker.js index d379d920..f0f5b868 100644 --- a/lib/network/modules/PhysicsWorker.js +++ b/lib/network/modules/PhysicsWorker.js @@ -53,10 +53,8 @@ class PhysicsWorker { this.toRemove.nodes.push.apply(this.toRemove.nodes, msg.data.nodes); this.toRemove.edges.push.apply(this.toRemove.edges, msg.data.edges); break; - case 'physicsObjects': - this.body.nodes = msg.data.nodes; - this.body.edges = msg.data.edges; - this.initPhysicsData(); + case 'initPhysicsData': + this.initPhysicsData(msg.data); break; case 'options': this.options = msg.data; @@ -137,31 +135,43 @@ class PhysicsWorker { } } - addElements(data) { - // TODO expand to handle multiple and edges - let newNode = data; - let nodeId = newNode.id; - this.body.nodes[nodeId] = newNode; - this.positions[nodeId] = { - x: newNode.x, - y: newNode.y - }; - this.physicsBody.forces[nodeId] = {x: 0, y: 0}; - this.physicsBody.velocities[nodeId] = {x: 0, y: 0}; - if (this.physicsBody.physicsNodeIndices.indexOf(nodeId) === -1) { - this.physicsBody.physicsNodeIndices.push(nodeId); + addElements(data, replaceElements = true) { + let nodeIds = Object.keys(data.nodes); + for (let i = 0; i < nodeIds.length; i++) { + let nodeId = nodeIds[i]; + let newNode = data.nodes[nodeId]; + if (replaceElements) { + this.body.nodes[nodeId] = newNode; + } + this.positions[nodeId] = { + x: newNode.x, + y: newNode.y + }; + this.physicsBody.forces[nodeId] = {x: 0, y: 0}; + // forces can be reset because they are recalculated. Velocities have to persist. + if (this.physicsBody.velocities[nodeId] === undefined) { + this.physicsBody.velocities[nodeId] = {x: 0, y: 0}; + } + if (this.physicsBody.physicsNodeIndices.indexOf(nodeId) === -1) { + this.physicsBody.physicsNodeIndices.push(nodeId); + } + } + let edgeIds = Object.keys(data.edges); + for (let i = 0; i < edgeIds.length; i++) { + let edgeId = edgeIds[i]; + if (replaceElements) { + this.body.edges[edgeId] = data.edges[edgeId]; + } + if (this.physicsBody.physicsEdgeIndices.indexOf(edgeId) === -1) { + this.physicsBody.physicsEdgeIndices.push(edgeId); + } } - console.log('added node', nodeId); } processRemovals() { while (this.toRemove.nodes.length > 0) { let nodeId = this.toRemove.nodes.pop(); - // TODO any optimization here? let index = this.physicsBody.physicsNodeIndices.indexOf(nodeId); - if (index === -1 && typeof nodeId === 'number') { - index = this.physicsBody.physicsNodeIndices.indexOf(nodeId.toString()); - } if (index > -1) { this.physicsBody.physicsNodeIndices.splice(index,1); } @@ -169,7 +179,6 @@ class PhysicsWorker { delete this.physicsBody.velocities[nodeId]; delete this.positions[nodeId]; delete this.body.nodes[nodeId]; - console.log('removed node', nodeId); } while (this.toRemove.edges.length > 0) { let edgeId = this.toRemove.edges.pop(); @@ -186,49 +195,22 @@ class PhysicsWorker { * * @private */ - initPhysicsData() { + initPhysicsData(data) { this.physicsBody.forces = {}; this.physicsBody.physicsNodeIndices = []; this.physicsBody.physicsEdgeIndices = []; - let nodes = this.body.nodes; - let edges = this.body.edges; - - // get node indices for physics - for (let nodeId in nodes) { - if (nodes.hasOwnProperty(nodeId)) { - this.physicsBody.physicsNodeIndices.push(nodeId); - this.positions[nodeId] = { - x: nodes[nodeId].x, - y: nodes[nodeId].y - } - } - } - - // get edge indices for physics - for (let edgeId in edges) { - if (edges.hasOwnProperty(edgeId)) { - this.physicsBody.physicsEdgeIndices.push(edgeId); - } - } - - // get the velocity and the forces vector - for (let i = 0; i < this.physicsBody.physicsNodeIndices.length; i++) { - let nodeId = this.physicsBody.physicsNodeIndices[i]; - this.physicsBody.forces[nodeId] = {x: 0, y: 0}; + this.positions = {}; - // forces can be reset because they are recalculated. Velocities have to persist. - if (this.physicsBody.velocities[nodeId] === undefined) { - this.physicsBody.velocities[nodeId] = {x: 0, y: 0}; - } - } + this.body.nodes = data.nodes; + this.body.edges = data.edges; + this.addElements(data, false); // clean deleted nodes from the velocity vector for (let nodeId in this.physicsBody.velocities) { - if (nodes[nodeId] === undefined) { + if (this.body.nodes[nodeId] === undefined) { delete this.physicsBody.velocities[nodeId]; } } - // console.log(this.physicsBody); } /** diff --git a/lib/network/modules/components/Node.js b/lib/network/modules/components/Node.js index 787520c9..3c0d38a1 100644 --- a/lib/network/modules/components/Node.js +++ b/lib/network/modules/components/Node.js @@ -210,6 +210,7 @@ class Node { this.body.emitter.emit('_physicsUpdate', {id: this.id, options: physOpts}); } + // TODO make embedded physics trigger this or handle _physicsUpdate messages if (options.hidden !== undefined) { return true; }