// When collision occures, this method is called // public virtual void _on_collision(PhysicsNode _other) { if (Global.IS_DEBUG) { Console.WriteLine("collision occured"); } }
public Spring(PhysicsNode n1, PhysicsNode n2, float length, float k) { Length = length; K = k; this.n1 = n1; this.n2 = n2; }
public void AddRange(IEnumerable <Node> nodes) { (var bottomleft, var topright) = GetBoundingBox(); Console.WriteLine($"bottomleft: {bottomleft}\ntopright: {topright}"); Console.WriteLine($"nodes: {nodes}"); var conns = new List <(PhysicsNode, List <(Connection, Node)>)>(); foreach (Node n in nodes) { if (physicsNodes.ContainsKey(n)) { continue; // throw new Exception("This system already contains the node!" + // " NOTE: this exception only occurs in debug mode"); } var pNode = new PhysicsNode(n, new Vector2(rng, (bottomleft.X, topright.X), (bottomleft.Y, topright.Y))); conns.Add((pNode, InnerGraph.GetOutgoingConnections(n))); physicsNodes.Add(n, pNode); Graph.Add(pNode); } // SelectMany(x => x) flattens the list foreach ((PhysicsNode src, var outgoing, Node dst) in conns.SelectMany(nl => { (var src, var list) = nl; return(list.Select(cn => (src, cn.Item1, cn.Item2))); })) { if (!physicsNodes.ContainsKey(dst)) { continue; } PhysicsNode pDst = physicsNodes[dst]; if (Graph.TryGetDirectedConnection(pDst, src, out var existingSpring)) { Graph.AddConnection(src, pDst, existingSpring); } else { InnerGraph.TryGetDirectedConnection(dst, src.Inner, out var incoming); var s1 = incoming?.Strength(); var s2 = outgoing?.Strength(); s1 ??= s2; s2 ??= s1; var spring = new Spring(src, pDst, (float)(s1 + s2) / 2f, Stiffness); Graph.AddConnection(src, pDst, spring); springs.Add(spring); } } }
public void Reset() { foreach (PhysicsNode pn in Graph.Nodes.Cast <PhysicsNode>()) { pn.Point.Position = PhysicsNode.RandomPosition(rng); pn.Point.Velocity = Vector2.Zero; } }
public void AttachCollidersToTank(NodeAddedEvent e, PhysicsNode node) { Rigidbody rigidbody = node.rigidbody.Rigidbody; BoxCollider boundsCollider = node.tankCollidersUnity.GetBoundsCollider(); this.SetInertiaTensor(ref rigidbody, boundsCollider.size, boundsCollider.center); node.Entity.AddComponent(new TriggerObjectComponent(boundsCollider.gameObject)); rigidbody.maxDepenetrationVelocity = MAX_DEPENETRATION_VELOCITY; node.rigidbody.Rigidbody.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic; rigidbody.WakeUp(); }
public void SanityCheck() { var seen = new HashSet <Vector2>(); foreach (PhysicsNode n in physicsNodes.Values) { while (seen.Contains(n.Point.Position) #pragma warning disable CS1718 // Comparison made to same variable || n.Point.Position.X != n.Point.Position.X || n.Point.Position.Y != n.Point.Position.Y) { #pragma warning restore CS1718 // Comparison made to same variable n.Point.Position = PhysicsNode.RandomPosition(rng); } } }
// handle the collision of the tank // public override void _on_collision(PhysicsNode _other) { base._on_collision(_other); //push apart var collision_direction = _other.get_global_position() - get_global_position(); collision_direction.Normalize(); Vector2 new_pos = collision_direction * delta; set_position(get_local_position() - new_pos); Console.WriteLine("Tank collision result: ------------"); Console.WriteLine(new_pos); Console.WriteLine(get_local_position() - new_pos); speed = -speed; return; }
// ---------------------------------------------------- // // generate game world based on the path to a text file // private void generate_game_world(string _data_file_path) { const int CELL_SIZE = 64; const char CELL_WALL = 'W'; const char CELL_TANK = 'T'; var physics_nodes = new List <PhysicsNode>(); try { StreamReader file = new StreamReader(_data_file_path); string line; int world_width; line = file.ReadLine(); if (line != null) { world_width = line.Length; //The width of the world is the length of the first line } else { Console.WriteLine("Error: the first line of the file is empty"); return; } int current_y = 0; while (line != null) { for (int current_x = 0; current_x < line.Length; ++current_x) { char current_cell = line[current_x]; Vector2 current_pos = new Vector2(current_x * CELL_SIZE + CELL_SIZE / 2, current_y * CELL_SIZE + CELL_SIZE / 2); if (current_cell == CELL_WALL) { PhysicsNode node = new PhysicsNode(root); node.set_texture(Graphics.texture_wall); node.set_position(current_pos); //Add to collision manager physics_nodes.Add(node); } if (current_cell == CELL_TANK) { var tank = new Tank(root); tank.set_position(current_pos); Console.WriteLine("\n\nTank was created at: \n" + current_pos); //Add to collision manager physics_nodes.Add(tank); } } ++current_y; line = file.ReadLine(); } //add nodes to collision_manager foreach (PhysicsNode node in physics_nodes) { collision_manager.add_node(node); } file.Close(); file.Dispose(); } catch (Exception e) { Console.WriteLine("Exception: " + e.Message); } }
// add a node to collision manager for it to be physically included // public void add_node(PhysicsNode _node) { nodes.Add(_node); }
public Simulation(Graph graph, SimulationParams @params, List <Node> includedNodes) { InnerGraph = graph; Stiffness = @params.stiffness; Repulsion = @params.repulsion; Damping = @params.damping; Gravity = @params.gravity; springs = new List <Spring>(); var physicsGraph = new Graph(); var nodeMap = new Dictionary <Node, PhysicsNode>(); foreach (var node in includedNodes) { if (nodeMap.ContainsKey(node)) { Console.WriteLine("wtffffffffffffffffffffffffffff"); } var physicsNode = new PhysicsNode(rng, node); physicsGraph.Add(physicsNode); nodeMap.Add(node, physicsNode); } physicsNodes = nodeMap; rng = new Random(); foreach (PhysicsNode node in nodeMap.Values) { foreach ((var conn1, var conn2, Node other) in graph.GetNeighbors(node.Inner)) { if (!nodeMap.ContainsKey(other)) { continue; } PhysicsNode node2 = nodeMap[other]; if (physicsGraph.TryGetDirectedConnection(node2, node, out Connection conn)) { var spring = (Spring)conn; physicsGraph.AddConnection(node, node2, new Spring(spring.n2, spring.n1, spring.Length, spring.K)); } else { // one of these must be non-null, since we're iterating over all existing connections var s1 = conn1?.Strength(); var s2 = conn2?.Strength(); s1 ??= s2; s2 ??= s1; var spring = new Spring(node, nodeMap[other], (float)(s1 + s2) / 2f, Stiffness); physicsGraph.AddConnection( node, nodeMap[other], spring); springs.Add(spring); } } } var removed = springs.RemoveAll((s) => s.n1 == s.n2); if (removed > 0) { Console.WriteLine($"!!!!!! # Cringe: {removed} !!!!!!"); } Graph = physicsGraph; }
public Simulation(Graph graph, SimulationParams @params) { InnerGraph = graph; springs = new List <Spring>(); Stiffness = @params.stiffness; Repulsion = @params.repulsion; Damping = @params.damping; Gravity = @params.gravity; Threshold = 0f; rng = new Random(); var physicsGraph = new Graph(); var nodeMap = new Dictionary <Node, PhysicsNode>(); foreach (var node in graph.Nodes) { var physicsNode = new PhysicsNode(rng, node); physicsGraph.Add(physicsNode); nodeMap.Add(node, physicsNode); } physicsNodes = nodeMap; foreach (PhysicsNode node in nodeMap.Values) { foreach ((var conn1, var conn2, Node other) in graph.GetNeighbors(node.Inner)) { if (other == node.Inner) { continue; } PhysicsNode node2 = nodeMap[other]; if (physicsGraph.TryGetDirectedConnection(node2, node, out Connection conn)) { var spring = (Spring)conn; physicsGraph.AddConnection(node, node2, new Spring(spring.n2, spring.n1, spring.Length, spring.K)); } else { // one of these must be non-null, since we're iterating over all existing connections var s1 = conn1?.Strength(); var s2 = conn2?.Strength(); s1 ??= s2; s2 ??= s1; var spring = new Spring(node, nodeMap[other], (float)(s1 + s2) / 2f, Stiffness); physicsGraph.AddConnection( node, nodeMap[other], spring ); springs.Add(spring); } } } Graph = physicsGraph; }