예제 #1
0
    public override void _IntegrateForces(Physics2DDirectBodyState state)
    {
        EmitSignal("_forces_integrated", new object[] { state });

        if (jelly == null)
        {
            return;
        }

        float   damping      = jelly.damping;
        float   stiffness    = jelly.stiffness;
        Vector2 totalImpulse = Vector2.Zero;

        foreach (Neighbour n in neighbours)
        {
            JellyAtom neighbourAtom       = n.jellyAtom;
            Vector2   posNeighbour        = neighbourAtom.GlobalPosition;
            Vector2   selfPos             = state.Transform.origin;
            float     restLength          = n.restLength;
            Vector2   diff                = posNeighbour - selfPos;
            float     distanceToNeighbour = diff.Length();
            Vector2   diffNormalized      = diff / distanceToNeighbour;
            Vector2   selfVelocity        = state.LinearVelocity;
            Vector2   neighbourVelocity   = neighbourAtom.LinearVelocity;
            float     force               = (distanceToNeighbour - restLength) * stiffness
                                            + (diffNormalized).Dot(neighbourVelocity - selfVelocity) * damping;

            totalImpulse += force * diff.Normalized() * state.Step;
        }

        ApplyCentralImpulse(totalImpulse);
    }
예제 #2
0
 public Neighbour(JellyAtom jellyAtom, float restLength)
 {
     this.jellyAtom  = jellyAtom;
     this.restLength = restLength;
 }
예제 #3
0
    private async void UpdateRect()
    {
        edgeBodies = new Array <JellyAtom>();
        if (jellyAtomPacked == null)
        {
            return;
        }
        Vector2 atomSeparation = new Vector2(atomW > 1 ? rect.Size.x / (atomW - 1) : 0, atomH > 1 ? rect.Size.y / (atomH - 1) : 0);
        Vector2 origin         = rect.Position;

        foreach (Node n in GetChildren())
        {
            n.QueueFree();
        }
        mapAtoms = new Dictionary <Vector2, JellyAtom>();
        for (int j = atomH - 1; j >= 0; j--)
        {
            for (int i = atomW - 1; i >= 0; i--)
            {
                JellyAtom jellyAtom = (JellyAtom)jellyAtomPacked.Instance();

                Vector2 gridPos = new Vector2(i, j);
                jellyAtom.Position     = origin + atomSeparation * gridPos;
                jellyAtom.jelly        = this;
                jellyAtom.GravityScale = gravityScale;
                AddChild(jellyAtom);
                mapAtoms.Add(gridPos, jellyAtom);
                Vector2[] neighbours = new Vector2[] {
                    new Vector2(i + 1, j),
                    new Vector2(i, j + 1),
                    new Vector2(i + 1, j + 1),
                    new Vector2(i - 1, j + 1)
                };
                if (i == 3 && j == 3)
                {
                    foreach (Node n in GetTree().GetNodesInGroup("CameraOffset"))
                    {
                        Node2D            cameraOffset = (Node2D)n;
                        RemoteTransform2D rt           = new RemoteTransform2D();
                        rt.UpdateRotation = false;
                        rt.UpdateRotation = false;
                        rt.RemotePath     = cameraOffset.GetPath();
                        jellyAtom.AddChild(rt);
                    }
                }
                foreach (Vector2 neighbour in neighbours)
                {
                    JellyAtom neighbourBody;

                    if (!mapAtoms.TryGetValue(neighbour, out neighbourBody))
                    {
                        continue;
                    }

                    float dist = (neighbourBody.Position - jellyAtom.Position).Length();
                    neighbourBody.AddNeighbour(new Neighbour(jellyAtom, dist));
                    jellyAtom.AddNeighbour(new Neighbour(neighbourBody, dist));
                }
                //await ToSignal(GetTree(), "idle_frame");
            }
        }

        for (int i = 0; i < atomW; i++)
        {
            edgeBodies.Add(mapAtoms[new Vector2(i, 0)]);
        }

        for (int j = 1; j < atomH; j++)
        {
            edgeBodies.Add(mapAtoms[new Vector2(atomW - 1, j)]);
        }

        for (int i = atomW - 2; i >= 0; i--)
        {
            edgeBodies.Add(mapAtoms[new Vector2(i, atomH - 1)]);
        }

        for (int j = atomH - 2; j >= 1; j--)
        {
            edgeBodies.Add(mapAtoms[new Vector2(0, j)]);
        }
    }