Ejemplo n.º 1
0
        }//eom

        public static Tuple <List <Node2D>, List <Spring2D> > CreateMesh(float px, float py, int w, int h, float dx, float dy, float m, float restD1 = -1, float restD2 = -1, float k = -3)
        {
            List <Node2D>   meshNodes = new List <Node2D>();
            List <Spring2D> springs   = new List <Spring2D>();

            // Creating nodes
            for (int y = 1; y <= h; y++)
            {
                for (int x = 1; x <= w; x++)
                {
                    Node2D node = new Node2D(new Vector2(px + x * dx, py + y * dy), m);
                    meshNodes.Add(node);
                } //end for
            }     //end for

            for (int i = 0; i < w - 1; i++)
            {
                for (int j = 0; j < h; j++)
                {
                    Spring2D spr = new Spring2D(meshNodes[i + w * j], meshNodes[i + 1 + w * j], restD1, k);
                    springs.Add(spr);
                } //end for
            }     //end for

            for (int i = 0; i < h - 1; i++)
            {
                for (int j = 0; j < w; j++)
                {
                    Spring2D spr = new Spring2D(meshNodes[i * w + j], meshNodes[(i + 1) * w + j], restD1, k);
                    springs.Add(spr);
                } //end for
            }     //end for

            // Diagonally
            //      \
            for (int y = 0; y < h - 1; y++)
            {
                for (int x = 0; x < w - 1; x++)
                {
                    Spring2D spr = new Spring2D(meshNodes[x + y * w], meshNodes[x + (y + 1) * w + 1], restD2, k);
                    springs.Add(spr);
                } //end for
            }     //end for

            //      /
            for (int y = 0; y < h - 1; y++)
            {
                for (int x = 1; x < w; x++)
                {
                    Spring2D spr = new Spring2D(meshNodes[x + y * w], meshNodes[x + (y + 1) * w - 1], restD2, k);
                    springs.Add(spr);
                } //end for
            }     //end for

            return(new Tuple <List <Node2D>, List <Spring2D> >(meshNodes, springs));
        }//eom
Ejemplo n.º 2
0
        public static Tuple <List <Node2D>, List <Spring2D> > CreatePendulum(float x1, float y1, float m1, float x2, float y2, float m2, float restD = -1, float k = -3)
        {
            List <Node2D>   nodes   = new List <Node2D>();
            List <Spring2D> springs = new List <Spring2D>();

            Node2D node1 = new Node2D(new Vector2(x1, y1), m1);
            Node2D node2 = new Node2D(new Vector2(x2, y2), m2);

            nodes.Add(node1);
            nodes.Add(node2);

            Spring2D spring = new Spring2D(node1, node2, restD, k);

            springs.Add(spring);

            return(new Tuple <List <Node2D>, List <Spring2D> >(nodes, springs));
        }//eom
Ejemplo n.º 3
0
        public MainWindow()
        {
            InitializeComponent();

            EasingList.ItemsSource       = easings.Keys;
            EasingList.SelectionChanged += (sender, e) => Animate(Ball);

            MouseLeftButtonDown += async(sender, e) =>
            {
                // Ball.Tween().FadeTo(0.5);
                // Ball.Tween().FadeOut();

                // TODO: Spring end detection.
                await Ball.Spring().Duration(500).Out()
                .MoveBy(e.GetPosition(Ball).X, e.GetPosition(Ball).Y)
                .FadeIn().OnStart(() => Title += "+");

                await EasingList.SpringAll(t => t.FadeIn(), 50);

                //await EasingList.TweenAll(t => t.FadeIn(), 50);

                // Ball.Tween().RotateBy(Math.PI);
                // Ball.Tween().SpinOnce();
                // Ball.Tween().Spin();
                // Ball.Tween().ScaleBy(1.5, 2.0);
            };

            var spring = new Spring2D();

            Ball.GetAnimatable().FrameTimer.OnTick(dt =>
            {
                spring.Update(dt);
                //Ball.GetAnimatable().Position = spring.Value;
                return(false);
            });

            MouseMove += (sender, e) =>
            {
                spring.Target = new Vector2(
                    e.GetPosition(this).X - 500,
                    e.GetPosition(this).Y - 200);
            };
        }
Ejemplo n.º 4
0
        }//eom

        public static Tuple <List <Node2D>, List <Spring2D> > CreateCircle(float cx, float cy, float r, int count, float cm, float m, float restD1 = -1, float restD2 = -1, float k = -3)
        {
            List <Node2D>   circleNodes = new List <Node2D>();
            List <Spring2D> springs     = new List <Spring2D>();

            Vector2 center     = new Vector2(cx, cy);
            Node2D  centerNode = new Node2D(center, cm);

            float step = (float)(Math.PI * 2f) / count;

            for (var i = 0; i < count; i++)
            {
                var t    = i * step;
                var temp = new Node2D(cx + r * (float)Math.Sin(t), cy + r * (float)Math.Cos(t), m);
                circleNodes.Add(temp);
            }//end for

            for (int i = 0; i < circleNodes.Count - 1; i++)
            {
                Spring2D spr = new Spring2D(circleNodes[i], circleNodes[i + 1], restD2, k);
                springs.Add(spr);
            }//end for

            foreach (Node2D b in circleNodes)
            {
                Spring2D spr2 = new Spring2D(b, centerNode, restD1, k);
                springs.Add(spr2);
            }//end for

            Spring2D sprr = new Spring2D(circleNodes.First(), circleNodes.Last(), restD2, k);

            springs.Add(sprr);

            circleNodes.Add(centerNode);

            return(new Tuple <List <Node2D>, List <Spring2D> >(circleNodes, springs));
        } //eom
Ejemplo n.º 5
0
    public void Init()
    {
        if (soft.masses == null)
        {
            soft.masses = new List <Mass2D>();
        }

        soft.masses.Clear();
        float ms = Mass / (float)(NumMasses);

        int ax = (int)axis;

        Vector2 pos = Vector2.zero;

        //DampingRatio = Mathf.Clamp01(DampingRatio);

        damp = (DampingRatio * 0.45f) * (2.0f * Mathf.Sqrt(ms * spring));

        for (int i = 0; i < NumMasses; i++)
        {
            float alpha = (float)i / (float)(NumMasses - 1);

            pos.x = Mathf.Lerp(bbox.min[ax], bbox.max[ax], alpha);
            //Debug.Log("m[" + i + "] alpha " + alpha + " " + pos.x);

            Mass2D rm = new Mass2D(ms, pos);
            soft.masses.Add(rm);
        }

        masspos = new Vector2[soft.masses.Count + 2];

        for (int i = 0; i < soft.masses.Count; i++)
        {
            masspos[i + 1] = soft.masses[i].pos;
        }

        if (soft.springs == null)
        {
            soft.springs = new List <Spring2D>();
        }

        soft.springs.Clear();

        if (soft.constraints == null)
        {
            soft.constraints = new List <Constraint2D>();
        }

        soft.constraints.Clear();

        for (int i = 0; i < soft.masses.Count - 1; i++)
        {
            Spring2D spr = new Spring2D(i, i + 1, spring, damp, soft);

            //float len = spr.restLen;
            spr.restLen *= SpringCompress;
            soft.springs.Add(spr);

            if (Constraints)
            {
                // Do we use restLen or len here?
                Constraint2D lcon = Constraint2D.CreateLenCon(i, i + 1, spr.restLen);
                soft.constraints.Add(lcon);
            }
        }
#if true
        if (BendSprings)
        {
            int gap = 2;
            for (int i = 0; i < soft.masses.Count - gap; i++)
            {
                float    alpha = (float)i / (float)soft.masses.Count;
                Spring2D spr   = new Spring2D(i, i + gap, stiffspring * stiffnessCrv.Evaluate(alpha), stiffdamp * stiffnessCrv.Evaluate(alpha), soft);
                soft.springs.Add(spr);

                Constraint2D lcon = Constraint2D.CreateLenCon(i, i + gap, spr.restLen);
                soft.constraints.Add(lcon);
            }
        }
#endif
        // Apply fixed end constraints
        Constraint2D pcon;

        //if ( left )
        //{
        //	pcon = Constraint2D.CreatePointTargetCon(0, left);
        //}
        //else
        {
            pos.x = bbox.min[ax];
            pos.y = 0.0f;
            pcon  = Constraint2D.CreatePointCon(0, pos);
        }
        pconl = soft.constraints.Count;
        soft.constraints.Add(pcon);

        //if ( right )
        //{
        //	pcon = Constraint2D.CreatePointTargetCon(soft.masses.Count - 1, left);
        //}
        //else
        {
            pos.x = bbox.max[ax];
            pcon  = Constraint2D.CreatePointCon(soft.masses.Count - 1, pos);
        }
        pconr = soft.constraints.Count;
        soft.constraints.Add(pcon);

        soft.DoConstraints();
    }
Ejemplo n.º 6
0
    public void Init()
    {
        if ( soft.masses == null )
            soft.masses = new List<Mass2D>();

        soft.masses.Clear();
        float ms = Mass / (float)(NumMasses);

        int ax = (int)axis;

        Vector2 pos = Vector2.zero;

        //DampingRatio = Mathf.Clamp01(DampingRatio);

        damp = (DampingRatio * 0.45f) * (2.0f * Mathf.Sqrt(ms * spring));

        for ( int i = 0; i < NumMasses; i++ )
        {
            float alpha = (float)i / (float)(NumMasses - 1);

            pos.x = Mathf.Lerp(bbox.min[ax], bbox.max[ax], alpha);
            //Debug.Log("m[" + i + "] alpha " + alpha + " " + pos.x);

            Mass2D rm = new Mass2D(ms, pos);
            soft.masses.Add(rm);
        }

        masspos = new Vector2[soft.masses.Count + 2];

        for ( int i = 0; i < soft.masses.Count; i++ )
            masspos[i + 1] = soft.masses[i].pos;

        if ( soft.springs == null )
            soft.springs = new List<Spring2D>();

        soft.springs.Clear();

        if ( soft.constraints == null )
            soft.constraints = new List<Constraint2D>();

        soft.constraints.Clear();

        for ( int i = 0; i < soft.masses.Count - 1; i++ )
        {
            Spring2D spr = new Spring2D(i, i + 1, spring, damp, soft);

            //float len = spr.restLen;
            spr.restLen *= SpringCompress;
            soft.springs.Add(spr);

            if ( Constraints )
            {
                // Do we use restLen or len here?
                Constraint2D lcon = Constraint2D.CreateLenCon(i, i + 1, spr.restLen);
                soft.constraints.Add(lcon);
            }
        }
        #if true
        if ( BendSprings )
        {
            int gap = 2;
            for ( int i = 0; i < soft.masses.Count - gap; i++ )
            {
                float alpha = (float)i / (float)soft.masses.Count;
                Spring2D spr = new Spring2D(i, i + gap, stiffspring * stiffnessCrv.Evaluate(alpha), stiffdamp * stiffnessCrv.Evaluate(alpha), soft);
                soft.springs.Add(spr);

                Constraint2D lcon = Constraint2D.CreateLenCon(i, i + gap, spr.restLen);
                soft.constraints.Add(lcon);
            }
        }
        #endif
        // Apply fixed end constraints
        Constraint2D pcon;

        //if ( left )
        //{
        //	pcon = Constraint2D.CreatePointTargetCon(0, left);
        //}
        //else
        {
            pos.x = bbox.min[ax];
            pos.y = 0.0f;
            pcon = Constraint2D.CreatePointCon(0, pos);
        }
        pconl = soft.constraints.Count;
        soft.constraints.Add(pcon);

        //if ( right )
        //{
        //	pcon = Constraint2D.CreatePointTargetCon(soft.masses.Count - 1, left);
        //}
        //else
        {
            pos.x = bbox.max[ax];
            pcon = Constraint2D.CreatePointCon(soft.masses.Count - 1, pos);
        }
        pconr = soft.constraints.Count;
        soft.constraints.Add(pcon);

        soft.DoConstraints();
    }
Ejemplo n.º 7
0
        }//eom

        protected override void Update(GameTime gameTime)
        {
            if (!IsActive)
            {
                return;
            }
            KeyboardState keyboardState = Keyboard.GetState();

            #region Handling Keyboard
            // Exit on Esc
            if (keyboardState.IsKeyDown(Keys.Escape))
            {
                Exit();
            }

            // Toggle isString property in all springs
            if (keyboardState.IsKeyDown(Keys.Space) && prevKS.IsKeyUp(Keys.Space))
            {
                stringMode = !stringMode;
                foreach (Spring2D spr in springs)
                {
                    spr.StringMode = stringMode;
                }
            }//end if

            if (keyboardState.IsKeyDown(Keys.Up))
            {
                stiffness += 0.02f;
                stiffness  = stiffness.Clamp(0.5f, 3f);

                foreach (Spring2D spr in springs)
                {
                    spr.Stiffness = -stiffness;
                }
            }//end if
            else if (keyboardState.IsKeyDown(Keys.Down))
            {
                stiffness -= 0.02f;
                stiffness  = stiffness.Clamp(0.5f, 3f);

                foreach (Spring2D spr in springs)
                {
                    spr.Stiffness = -stiffness;
                }
            }//end else

            if (keyboardState.IsKeyDown(Keys.F1) && prevKS.IsKeyUp(Keys.F1))
            {
                helpVisible = !helpVisible;
            }//end if
            #endregion

            #region Handling Mouse
            MouseState mouseState = Mouse.GetState();
            mousePos = new Vector2(mouseState.X, mouseState.Y);
            #region Left Mouse Button Logic
            bool mouseDownL = (mouseState.LeftButton == ButtonState.Pressed && prevMs.LeftButton == ButtonState.Released);
            bool mouseUpL   = (mouseState.LeftButton == ButtonState.Released && prevMs.LeftButton == ButtonState.Pressed);
            bool mouseDragL = (mouseState.LeftButton == ButtonState.Pressed && prevMs.LeftButton == ButtonState.Pressed);

            if (mouseDownL)
            {
                nodeL = PickNode(mousePos); // a signle click picks a node

                // Checking double clicks to remove a node
                long currentTime = gameTime.TotalGameTime.Milliseconds;

                float dt = currentTime - clickTimeL;
                float dp = Vector2.Distance(clickPosL, mousePos);
                if (nodeL != null && dt < 500 && dp < 10)
                {
                    nodes.Remove(nodeL);
                    // Remove all springs attached to the deleted node
                    for (int i = 0; i < springs.Count; i++)
                    {
                        Spring2D spr = springs[i];
                        if (spr.node1 == nodeL || spr.node2 == nodeL)
                        {
                            springs.RemoveAt(i);
                            i--;
                        } //end if
                    }     //end for
                    nodeL = null;
                }         //end if

                clickTimeL = currentTime;
                clickPosL  = mousePos;
            }//end if
            else if (mouseDragL)
            {
                if (nodeL != null)
                {
                    // We make sure the selected node is always at the same position of the mouse
                    nodeL.a = Vector2.Zero;
                    nodeL.v = Vector2.Zero;
                    nodeL.p = mousePos;
                } //end if
            }     //end else
            #endregion

            #region Right Mouse Button Logic
            bool mouseDownR = (mouseState.RightButton == ButtonState.Pressed && prevMs.RightButton == ButtonState.Released);
            bool mouseUpR   = (mouseState.RightButton == ButtonState.Released && prevMs.RightButton == ButtonState.Pressed);

            if (mouseDownR)
            {
                clickPosR = mousePos;
                nodeR     = PickNode(mousePos);
            }//end if
            else if (mouseUpR)
            {
                float dist = Vector2.Distance(mousePos, clickPosR);
                if (nodeR == null && dist < 10) // Simple right click
                {
                    nodes.Add(new Node2D(mousePos, 1f));
                }//end if
                else if (nodeR != null && dist > 20)  // Right button drag\drop
                {
                    // Check if dropped on an existing node, if not then create a new one, then link them
                    Node2D target = PickNode(mousePos);
                    if (target == null)
                    {
                        target = new Node2D(mousePos, 1f);
                        nodes.Add(target);
                    }//end if
                    Spring2D spr = new Spring2D(target, nodeR, Vector2.Distance(target.p, nodeR.p) * 0.80f);
                    spr.StringMode = stringMode;

                    springs.Add(spr);
                }//end else

                nodeR = null;
            }//end if
            #endregion

            #region Mouse Wheel Logic
            // Change mass from 1 to 500 using mouse wheel
            if (nodeL != null)
            {
                float wheelDelta = mouseState.ScrollWheelValue - prevMs.ScrollWheelValue;
                nodeL.Mass += wheelDelta / 50f;
                //if (mass < 1) mass = 1; else if (mass > 500) mass = 500;
            }//end if
            #endregion

            #endregion

            if (keyboardState.IsKeyDown(Keys.P) && prevKS.IsKeyUp(Keys.P))
            {
                paused = !paused;
            }

            if (keyboardState.IsKeyDown(Keys.F5) && prevKS.IsKeyUp(Keys.F5))
            {
                InitLab();
                return;
            }//end if

            //if (prevMs.LeftButton == ButtonState.Released && mouseState.LeftButton == ButtonState.Pressed && linkRect.Contains(mouseState.X, mouseState.Y)) VisitBlog();

            prevKS = keyboardState;
            prevMs = mouseState;

            if (paused && keyboardState.IsKeyUp(Keys.Right))
            {
                return;
            }

            #region Physics Update
            // First update all springs, this will only update the objects' acceleration
            foreach (Spring2D spr in springs)
            {
                spr.Update();
            }

            // Second update objects, this will affect acceleration, velocity and position
            foreach (Node2D node in nodes)
            {
                node.Update();
            }
            #endregion

            base.Update(gameTime);
        }//eom