Example #1
0
    public void SimulateSpringForces(float dt)
    {
        for (int i = 0; i < kGridHeight * kGridWidth; ++i)
        {
            SpringNode node = Nodes[i];

            if (node.Locked)
            {
                continue;
            }

            Spring(node, node.Left, dt, kHorizSpringDist, kSpringForceHoriz);
            Spring(node, node.Right, dt, kHorizSpringDist, kSpringForceHoriz);
            Spring(node, node.Up, dt, kHorizSpringDist, kSpringForceVert);
            Spring(node, node.Down, dt, kHorizSpringDist, kSpringForceVert);
            Spring(node, node.UL, dt, kDiagSpringDist, kSpringForceDiag);
            Spring(node, node.DL, dt, kDiagSpringDist, kSpringForceDiag);
            Spring(node, node.UR, dt, kDiagSpringDist, kSpringForceDiag);
            Spring(node, node.DR, dt, kDiagSpringDist, kSpringForceDiag);

            // Spring force back towards origin
            Vector3 originDelta = node.Origin - node.Pos;
            float   originDist2 = originDelta.sqrMagnitude;

            if (originDist2 > 0.000001f)
            {
                // accel towards origin is proportional to distance^3
                Vector3 accel = originDist2 * (originDelta * dt * kSpringForceOrigin);
                node.Velocity += accel;
            }
        }
    }
Example #2
0
    public void UnlinkRight()
    {
        if (RightGrid == null)
        {
            return;
        }

        // unlink all the nodes
        for (int y = 0; y < kGridHeight; ++y)
        {
            SpringNode otherNode = RightGrid.GetNode(0, y);
            otherNode.Left = null;

            otherNode = RightGrid.GetNode(0, y - 1);
            if (otherNode != null)
            {
                otherNode.UL = null;
            }

            otherNode = RightGrid.GetNode(0, y + 1);
            if (otherNode != null)
            {
                otherNode.DL = null;
            }
        }

        RightGrid.LeftGrid = null;
        RightGrid          = null;
    }
Example #3
0
    public void LinkRight(SpringGrid rightGrid)
    {
        if (RightGrid != null)
        {
            UnlinkRight();
        }

        RightGrid          = rightGrid;
        RightGrid.LeftGrid = this;

        for (int y = 0; y < kGridHeight; ++y)
        {
            // We leave the far-rightmost grid node as a mirror of the leftmost grid node in the next grid
            // So link the left-side nodes from the next grid to the 2nd-from-the-right nodes in this grid
            SpringNode thisNode  = GetNode(kGridWidth - 2, y);
            SpringNode otherNode = RightGrid.GetNode(0, y);
            otherNode.Left = thisNode;

            otherNode = RightGrid.GetNode(0, y - 1);
            if (otherNode != null)
            {
                otherNode.UL = thisNode;
            }

            otherNode = RightGrid.GetNode(0, y + 1);
            if (otherNode != null)
            {
                otherNode.DL = thisNode;
            }
        }
    }
Example #4
0
        public override void Update(TimeSpan elapsed)
        {
            SpringNode tail = skeleton.Nodes[skeleton.Nodes.Count - 1];

            a += tail.Velocity.X + tail.Velocity.Z;

            rotation = Matrix.CreateFromYawPitchRoll(a, a / 2, a / 4);
        }
Example #5
0
 public void UpdateSeams()
 {
     if (RightGrid != null)
     {
         // Stitch right line of this as a copy of the left line of the adjacent mesh
         for (int y = 0; y < kGridHeight; ++y)
         {
             SpringNode node      = GetNode(kGridWidth - 1, y);
             SpringNode otherNode = RightGrid.GetNode(0, y);
             node.Pos      = otherNode.Pos;
             node.Velocity = otherNode.Velocity;
         }
     }
 }
Example #6
0
    public void CalculateVelocity(UndirecteGraph <SpringNode, Edge <SpringNode> > graph, float speed)
    {
        List <Edge <SpringNode> > connectedEdges = graph.GetConnectedEdges(this);
        Vector3 velocity = Vector3.zero;

        foreach (var edge in connectedEdges)
        {
            SpringNode connectedVertex = edge.GetOtherVertex(this);
            float      weight          = (float)edge.Weight;
            Vector3    direction       = connectedVertex.Position - this.Position;
            velocity += direction * (direction.magnitude - weight);
        }
        _velocity = velocity * speed;
    }
Example #7
0
    public void SeaLevel(float thetaRadians, ref float prevBest)
    {
        // TODO: check if this should be 0 or kGridHeight-1
        const int y = kGridHeight - 1;

        SpringNode prevNode  = Nodes[GridIdx(0, y)];
        Vector2    prevPolar = World.GetPolarCoordinate(prevNode.Pos);

        for (int x = 1; x < kGridWidth; ++x)
        {
            SpringNode curNode  = Nodes[GridIdx(x, y)];
            Vector2    curPolar = World.GetPolarCoordinate(curNode.Pos);

            // Check if this segment is forward facing
            float polarDiff = curPolar.y - prevPolar.y;
            if (polarDiff < -Mathf.PI)
            {
                polarDiff += Mathf.PI * 2;
            }

            if (polarDiff >= 0 && polarDiff < Mathf.PI)
            {
                // Check if the selected point is inside this line segment
                float pointDiff = thetaRadians - prevPolar.y;
                if (pointDiff < -Mathf.PI)
                {
                    pointDiff += Mathf.PI * 2;
                }

                if (pointDiff >= 0 && pointDiff <= polarDiff)
                {
                    // point is inside forward facing line segment, get sea level at that point
                    float newSeaLevel = curPolar.x;
                    if (polarDiff > 0.001f)
                    {
                        newSeaLevel = Mathf.Lerp(prevPolar.x, curPolar.x, pointDiff / polarDiff);
                    }

                    if (newSeaLevel > prevBest)
                    {
                        prevBest = newSeaLevel;
                    }
                }
            }

            prevPolar = curPolar;
        }
    }
Example #8
0
    public void CreateNodes()
    {
        Nodes = new SpringNode[kGridHeight * kGridWidth];

        // create nodes
        for (int y = 0; y < kGridHeight; ++y)
        {
            for (int x = 0; x < kGridWidth; ++x)
            {
                Nodes[GridIdx(x, y)] = new SpringNode();
            }
        }

        const float xScale = 1.0f / (kGridWidth - 1);
        const float yScale = 1.0f / (kGridHeight - 1);

        for (int y = 0; y < kGridHeight; ++y)
        {
            for (int x = 0; x < kGridWidth; ++x)
            {
                SpringNode thisNode = GetNode(x, y);

                // Calculate position
                float theta  = Mathf.Lerp(Theta, Theta + kThetaDelta, x * xScale);
                float height = Mathf.Lerp(kInnerRadius, kOuterRadius, y * yScale);

                Vector3 pos = World.GetWorldCoordinate(new Vector2(height, theta * Mathf.Deg2Rad));

                thisNode.Pos      = thisNode.Origin = pos;
                thisNode.Velocity = Vector3.zero;

                thisNode.Down  = GetNode(x, y - 1);
                thisNode.Up    = GetNode(x, y + 1);
                thisNode.Left  = GetNode(x - 1, y);
                thisNode.Right = GetNode(x + 1, y);

                thisNode.DR = GetNode(x + 1, y - 1);
                thisNode.DL = GetNode(x - 1, y - 1);
                thisNode.UR = GetNode(x + 1, y + 1);
                thisNode.UL = GetNode(x - 1, y + 1);

                thisNode.Locked = (y == 0);
            }
        }
    }
Example #9
0
    public void AddOutwardForce(Vector2 center, float dist, float power)
    {
        Vector3 center3 = new Vector3(center.x, center.y, 0);
        float   distSq  = dist * dist;

        // TODO: Don't visit every node
        for (int i = 0; i < kGridHeight * kGridWidth; ++i)
        {
            SpringNode node      = Nodes[i];
            Vector3    diff      = node.Pos - center3;
            float      diffMagSq = diff.sqrMagnitude;

            if (diffMagSq > 0.01f && diffMagSq < distSq)
            {
                //power *= 1 - (diff.magnitude / dist);
                node.Velocity += power * diff.normalized;
            }
        }
    }
Example #10
0
    private static void Spring(SpringNode node, SpringNode other, float dt, float dist, float force)
    {
        if (other == null)
        {
            return;
        }

        Vector3 posDelta    = other.Pos - node.Pos;
        float   lengthDelta = posDelta.magnitude;
        float   springError = lengthDelta - dist;

        if (springError < 0)
        {
            // TODO: force to counteract compression is higher than force to counteract expansion?
            springError *= 1;
        }

        Vector3 accel = posDelta * ((springError / lengthDelta) * force * dt);

        node.Velocity += accel;
    }
Example #11
0
    private static void Spring(SpringNode node, SpringNode other, float dt, float dist, float force)
    {
        if (other == null)
            return;

        Vector3 posDelta = other.Pos - node.Pos;
        float lengthDelta = posDelta.magnitude;
        float springError = lengthDelta - dist;
        if(springError < 0)
        {
            // TODO: force to counteract compression is higher than force to counteract expansion?
            springError *= 1;
        }

        Vector3 accel = posDelta * ((springError / lengthDelta) * force * dt);
        node.Velocity += accel;
    }
Example #12
0
    public void CreateNodes()
    {
        Nodes = new SpringNode[kGridHeight * kGridWidth];

        // create nodes
        for(int y = 0; y < kGridHeight; ++y)
        {
            for(int x = 0; x < kGridWidth; ++x)
            {
                Nodes[GridIdx(x, y)] = new SpringNode();
            }
        }

        const float xScale = 1.0f / (kGridWidth - 1);
        const float yScale = 1.0f / (kGridHeight - 1);

        for(int y = 0; y < kGridHeight; ++y)
        {
            for(int x = 0; x < kGridWidth; ++x)
            {
                SpringNode thisNode = GetNode(x,y);

                // Calculate position
                float theta = Mathf.Lerp(Theta, Theta + kThetaDelta, x * xScale);
                float height = Mathf.Lerp(kInnerRadius, kOuterRadius, y * yScale);

                Vector3 pos = World.GetWorldCoordinate(new Vector2(height, theta * Mathf.Deg2Rad));

                thisNode.Pos = thisNode.Origin = pos;
                thisNode.Velocity = Vector3.zero;

                thisNode.Down = GetNode(x, y-1);
                thisNode.Up = GetNode(x, y+1);
                thisNode.Left = GetNode(x-1, y);
                thisNode.Right = GetNode(x+1, y);

                thisNode.DR = GetNode(x + 1, y - 1);
                thisNode.DL = GetNode(x - 1, y - 1);
                thisNode.UR = GetNode(x + 1, y + 1);
                thisNode.UL = GetNode(x - 1, y + 1);

                thisNode.Locked = (y == 0);
            }
        }
    }
Example #13
0
        LookAtCamera camera = null;//Camera camera = null;

        public override void Initialize()
        {
            base.Initialize();

            skeleton.Enabled = true;

            skeleton.Coefficient = 0.3f;
            skeleton.Elasticity  = 0.01f;
            skeleton.EnergyLoss  = 0.86f;

            float width  = 2;
            float height = 2;
            float depth  = 3;
            float w      = width / 2;
            float h      = height / 2;
            float d      = depth / 2;

            Vector3 offset = Vector3.Zero;//transform.Position;

            PlayingField field = GameContainer.Scene.Coordinator.Select("Playing Field")[0].Get <PlayingField>();


            if (goal.PlayerIndex == PlayerIndex.One)
            {
                offset = new Vector3(-(field.Width / 2) - (goal.Extents.X / 2) + 1.5f, 1, 0);
            }
            else if (goal.PlayerIndex == PlayerIndex.Two)
            {
                // hacky, i've messed something up with positioning, so the right goal seems further away..
                offset = new Vector3((field.Width / 2) + (goal.Extents.X / 2) - 3.5f, 1, 0);
            }

            // goal

            SpringNode a1 = null;

            // :>
            if (goal.PlayerIndex == PlayerIndex.One)
            {
                a1 = new SpringNode(offset + new Vector3(-w, -h, d));
            }
            else if (goal.PlayerIndex == PlayerIndex.Two)
            {
                a1 = new SpringNode(offset + new Vector3(w * 3, -h, d));
            }

            SpringNode a2 = new SpringNode(offset + new Vector3(w, -h, d));
            SpringNode a3 = new SpringNode(offset + new Vector3(w, h, d));

            SpringNode b1 = null;

            // :>
            if (goal.PlayerIndex == PlayerIndex.One)
            {
                b1 = new SpringNode(offset + new Vector3(-w, -h, -d));
            }
            else if (goal.PlayerIndex == PlayerIndex.Two)
            {
                b1 = new SpringNode(offset + new Vector3(w * 3, -h, -d));
            }

            SpringNode b2 = new SpringNode(offset + new Vector3(w, -h, -d));
            SpringNode b3 = new SpringNode(offset + new Vector3(w, h, -d));

            SpringNodeAnchor a1Anchor = new SpringNodeAnchor(a1);
            SpringNodeAnchor a2Anchor = new SpringNodeAnchor(a2);
            SpringNodeAnchor a3Anchor = new SpringNodeAnchor(a3);

            SpringNodeAnchor b1Anchor = new SpringNodeAnchor(b1);
            SpringNodeAnchor b2Anchor = new SpringNodeAnchor(b2);
            SpringNodeAnchor b3Anchor = new SpringNodeAnchor(b3);

            a1.Neighbors.Add(a2, Vector3.Distance(a1.Position, a2.Position));
            a1.Neighbors.Add(a3, Vector3.Distance(a1.Position, a3.Position));
            a1.Neighbors.Add(b1, Vector3.Distance(a1.Position, b1.Position));

            a2.Neighbors.Add(a1, Vector3.Distance(a2.Position, a1.Position));
            a2.Neighbors.Add(a3, Vector3.Distance(a2.Position, a3.Position));

            a3.Neighbors.Add(a1, Vector3.Distance(a3.Position, a1.Position));
            a3.Neighbors.Add(a2, Vector3.Distance(a3.Position, a2.Position));
            a3.Neighbors.Add(b3, Vector3.Distance(a3.Position, b3.Position));

            b1.Neighbors.Add(b2, Vector3.Distance(b1.Position, b2.Position));
            b1.Neighbors.Add(b3, Vector3.Distance(b1.Position, b3.Position));
            b1.Neighbors.Add(a1, Vector3.Distance(b1.Position, a1.Position));

            b2.Neighbors.Add(b1, Vector3.Distance(b2.Position, b1.Position));
            b2.Neighbors.Add(b3, Vector3.Distance(b2.Position, b3.Position));

            b3.Neighbors.Add(b1, Vector3.Distance(b3.Position, b1.Position));
            b3.Neighbors.Add(b2, Vector3.Distance(b3.Position, b2.Position));
            b3.Neighbors.Add(a3, Vector3.Distance(b3.Position, a3.Position));

            // net
            float dist = 0.5f;

            SpringNode na1 = new SpringNode(new Vector3(0, 0, 0));
            SpringNode na2 = new SpringNode(new Vector3(dist, 0, 0));
            SpringNode na3 = new SpringNode(new Vector3(dist * 2, 0, 0));
            SpringNode na4 = new SpringNode(new Vector3(dist * 3, 0, 0));
            SpringNode na5 = new SpringNode(new Vector3(0, dist, 0));
            SpringNode na6 = new SpringNode(new Vector3(dist, dist, 0));
            SpringNode na7 = new SpringNode(new Vector3(dist * 2, dist, 0));
            SpringNode na8 = new SpringNode(new Vector3(dist * 3, dist, 0));

            na1.Neighbors.Add(na2, dist);
            na1.Neighbors.Add(na5, dist);

            na2.Neighbors.Add(na1, dist);
            na2.Neighbors.Add(na6, dist);
            na2.Neighbors.Add(na3, dist);

            na3.Neighbors.Add(na2, dist);
            na3.Neighbors.Add(na4, dist);
            na3.Neighbors.Add(na7, dist);

            na4.Neighbors.Add(na3, dist);
            na4.Neighbors.Add(na8, dist);

            na5.Neighbors.Add(na1, dist);
            na5.Neighbors.Add(na6, dist);

            na6.Neighbors.Add(na5, dist);
            na6.Neighbors.Add(na2, dist);
            na6.Neighbors.Add(na7, dist);

            na7.Neighbors.Add(na6, dist);
            na7.Neighbors.Add(na3, dist);
            na7.Neighbors.Add(na8, dist);

            na8.Neighbors.Add(na7, dist);
            na8.Neighbors.Add(na4, dist);

            a1.Neighbors.Add(na4, dist);
            na4.Neighbors.Add(a1, dist);

            b1.Neighbors.Add(na1, dist);
            na1.Neighbors.Add(b1, dist);

            a3.Neighbors.Add(na8, dist);
            na8.Neighbors.Add(a3, dist);

            b3.Neighbors.Add(na5, dist);
            na5.Neighbors.Add(b3, dist);

            skeleton.Nodes.AddRange(
                new SpringNode[] {
                a1, a2, a3, b1, b2, b3,
                na1, na2, na3, na4, na5, na6, na7, na8
            });
            skeleton.Anchors.AddRange(new SpringNodeAnchor[] { a1Anchor, a2Anchor, a3Anchor, b1Anchor, b2Anchor, b3Anchor });
        }