//loop through all rigidbodies and add each one to the graph public static void PopulateGraph(Physics.PhysicsEngine physEng, Node topNode) { foreach (var rb in physEng.staticPhysicsObjects) { //create the rigibody's node topNode.AddNode(GraphBuilder.CreateNodesFromRB(rb, topNode.index, topNode.internalNodes.Count)); AddInternalConnections(topNode.internalNodes[topNode.internalNodes.Count - 1]); //connect the new node to the previous nodes for (int i = 0; i < topNode.internalNodes.Count - 1; ++i) { GraphBuilder.AddConnections(topNode.internalNodes[topNode.internalNodes.Count - 1], topNode.internalNodes[i]); } } foreach (Physics.MovingPlatform mp in physEng.movingPlatforms) { //create the rigibody's node topNode.AddNode(new NodeOnRails(GraphBuilder.CreateNodesFromRB(mp.platform, topNode.index, topNode.internalNodes.Count), mp.point1, mp.point2)); AddInternalConnections(topNode.internalNodes[topNode.internalNodes.Count - 1]); //connect the new node to the previous nodes for (int j = 0; j < topNode.internalNodes.Count - 1; ++j) { GraphBuilder.AddConnections(topNode.internalNodes[topNode.internalNodes.Count - 1], topNode.internalNodes[j]); } } //Note: this method does not cull connections that get blocked by new rigidbodies. //The naive solution to this would increase an already long graph generation time, and as such has not been implemented. }
//given a rigidbody, create its node and its child nodes, then return its node public static Node CreateNodesFromRB(Physics.RigidBody theRB, NodeIndex parentIndex, int localIndex) { //create the node for the rigidbody Node rigidBody = new Node(theRB.Position, new NodeIndex(parentIndex, localIndex), NODE_TYPE.RIGIDBODY); //this temporary position is used to place the child nodes Physics.Vector2D nodePosition = new Physics.Vector2D(); nodePosition.Y = theRB.Shape.ComputeAABB().MIN.Y - (Physics.Player.playerRadius + 1); //Create the leftmost fall node nodePosition.X = theRB.Shape.ComputeAABB().MIN.X - (Physics.Player.playerRadius + 1); rigidBody.AddNode(new Node(new Physics.Vector2D(nodePosition), new NodeIndex(rigidBody.index, rigidBody.internalNodes.Count), NODE_TYPE.FALL)); //Move the node position so it is not above a sheer drop nodePosition.X = theRB.Shape.ComputeAABB().MIN.X + (Physics.Player.playerRadius / 2); //Create the regular nodes an even distance apart float surfaceWidth = theRB.Shape.ComputeAABB().MAX.X - theRB.Shape.ComputeAABB().MIN.X; int numberOfNodes = (int)(surfaceWidth / (Physics.Player.playerRadius * 2) + 0.5); float step = (surfaceWidth - Physics.Player.playerRadius) / numberOfNodes; for (int i = 0; i <= numberOfNodes; ++i) { rigidBody.AddNode(new Node(new Physics.Vector2D(nodePosition), new NodeIndex(rigidBody.index, rigidBody.internalNodes.Count), NODE_TYPE.FLOOR)); nodePosition.X += step; } //Create the rightmost fall node nodePosition.X = theRB.Shape.ComputeAABB().MAX.X + (Physics.Player.playerRadius + 1); rigidBody.AddNode(new Node(new Physics.Vector2D(nodePosition), new NodeIndex(rigidBody.index, rigidBody.internalNodes.Count), NODE_TYPE.FALL)); return(rigidBody); }