Exemple #1
0
        void Update()
        {
            // UPDATE the physics!


            _cursorPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);

            // dragging!
            if (Input.GetMouseButton(0))
            {
                if (_dragBody != null)
                {
                    PointMass pm = _dragBody.getPointMass(_dragPoint);
                    if (_dragBody.GetType().Name == "DraggableSpringBody")
                    {
                        ((DraggableSpringBody)_dragBody).setDragForce(JelloPhysics.VectorTools.calculateSpringForce(pm.Position, pm.Velocity, _cursorPos, Vector2.zero, 0.0f, 100.0f, 10.0f), _dragPoint);
                    }
                    else if (_dragBody.GetType().Name == "DraggablePressureBody")
                    {
                        ((DraggablePressureBody)_dragBody).setDragForce(JelloPhysics.VectorTools.calculateSpringForce(pm.Position, pm.Velocity, _cursorPos, Vector2.zero, 0.0f, 100.0f, 10.0f), _dragPoint);
                    }
                }
            }
            else
            {
                _dragBody  = null;
                _dragPoint = -1;
            }

            if (Input.GetMouseButtonDown(0))
            {
                if (_dragBody == (null))
                {
                    int body;
                    _world.getClosestPointMass(_cursorPos, out body, out _dragPoint);
                    _dragBody = _world.getBody(body);
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        void Update()
        {
            // UPDATE the physics!
            for (int i = 0; i < 3; i++)
            {
                mWorld.update(1 / 120f);
            }

            // cursor movement.
            cursorPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);

            // if the user presses the A button, create a new body at the cursor position.
            if (Input.GetKeyDown(KeyCode.A))
            {
                GameObject s = new GameObject();
                JelloPhysics.ClosedShape shape = new JelloPhysics.ClosedShape();

                shape.begin();
                shape.addVertex(new Vector2(-1.0f, 0f));
                shape.addVertex(new Vector2(0f, 1.0f));
                shape.addVertex(new Vector2(1.0f, 0f));
                shape.addVertex(new Vector2(0f, -1.0f));
                shape.finish();

                DraggableSpringBody body = new DraggableSpringBody();
                body.Setup(mWorld, shape, 1f, 150, 5, 300, 15, new Vector2(cursorPos.x, cursorPos.y), ((float)UnityEngine.Random.Range(0, 360)), Vector2.one);

                body.addInternalSpring(0, 2, 400f, 12f);
                body.addInternalSpring(1, 3, 400f, 12f);
            }

            if (Input.GetKeyDown(KeyCode.B))
            {
                GameObject s = new GameObject();
                JelloPhysics.ClosedShape shape = new JelloPhysics.ClosedShape();

                shape.begin();
                for (int i = 0; i < 360; i += 20)
                {
                    shape.addVertex(new Vector2((float)Mathf.Cos(((float)-i) * Mathf.Deg2Rad), (float)Mathf.Sin(((float)-i) * Mathf.Deg2Rad)));
                }
                shape.finish();

                DraggablePressureBody pb = new DraggablePressureBody();
                pb.Setup(mWorld, shape, 1.0f, 40.0f, 10.0f, 1.0f, 300.0f, 20.0f, cursorPos, 0, Vector2.one);
                pb.addTriangle(0, 10, 9);
                pb.addTriangle(0, 9, 1);
                pb.addTriangle(1, 9, 8);
                pb.addTriangle(1, 8, 2);
                pb.addTriangle(2, 8, 7);
                pb.addTriangle(2, 7, 3);
                pb.addTriangle(3, 7, 6);
                pb.addTriangle(3, 6, 4);
                pb.addTriangle(4, 6, 5);
                pb.addTriangle(17, 10, 0);
                pb.addTriangle(17, 11, 10);
                pb.addTriangle(16, 11, 17);
                pb.addTriangle(16, 12, 11);
                pb.addTriangle(15, 12, 16);
                pb.addTriangle(15, 13, 12);
                pb.addTriangle(14, 12, 15);
                pb.addTriangle(14, 13, 12);
                pb.finalizeTriangles(Color.white);

                pb.addInternalSpring(0, 2, 400f, 12f);
                pb.addInternalSpring(1, 3, 400f, 12f);
            }

            // dragging!
            if (Input.GetMouseButton(0))
            {
                if (dragBody != null)
                {
                    PointMass pm = dragBody.getPointMass(dragPoint);
                    if (dragBody.GetType().Name == "DraggableSpringBody")
                    {
                        ((DraggableSpringBody)dragBody).setDragForce(JelloPhysics.VectorTools.calculateSpringForce(pm.Position, pm.Velocity, cursorPos, Vector2.zero, 0.0f, 100.0f, 10.0f), dragPoint);
                    }
                    else if (dragBody.GetType().Name == "DraggablePressureBody")
                    {
                        ((DraggablePressureBody)dragBody).setDragForce(JelloPhysics.VectorTools.calculateSpringForce(pm.Position, pm.Velocity, cursorPos, Vector2.zero, 0.0f, 100.0f, 10.0f), dragPoint);
                    }
                }
            }
            else
            {
                dragBody  = null;
                dragPoint = -1;
            }

            if (Input.GetMouseButtonDown(0))
            {
                if (dragBody == null)
                {
                    int body;
                    mWorld.getClosestPointMass(cursorPos, out body, out dragPoint);
                    dragBody = mWorld.getBody(body);
                }
            }
        }
Exemple #3
0
        private void bodyCollide(Body bA, Body bB, List<BodyCollisionInfo> infoList)
        {
            int bApmCount = bA.PointMassCount;
            int bBpmCount = bB.PointMassCount;

            AABB boxB = bB.getAABB();

            // check all PointMasses on bodyA for collision against bodyB.  if there is a collision, return detailed info.
            BodyCollisionInfo infoAway = new BodyCollisionInfo();
            BodyCollisionInfo infoSame = new BodyCollisionInfo();
            for (int i = 0; i < bApmCount; i++)
            {
                Vector2 pt = bA.getPointMass(i).Position;

                // early out - if this point is outside the bounding box for bodyB, skip it!
                if (!boxB.contains(ref pt))
                    continue;

                // early out - if this point is not inside bodyB, skip it!
                if (!bB.contains(ref pt))
                    continue;

                int prevPt = (i>0) ? i-1 : bApmCount-1;
                int nextPt = (i < bApmCount - 1) ? i + 1 : 0;

                Vector2 prev = bA.getPointMass(prevPt).Position;
                Vector2 next = bA.getPointMass(nextPt).Position;

                // now get the normal for this point. (NOT A UNIT VECTOR)
                Vector2 fromPrev = new Vector2();
                fromPrev.X = pt.X - prev.X;
                fromPrev.Y = pt.Y - prev.Y;

                Vector2 toNext = new Vector2();
                toNext.X = next.X - pt.X;
                toNext.Y = next.Y - pt.Y;

                Vector2 ptNorm = new Vector2();
                ptNorm.X = fromPrev.X + toNext.X;
                ptNorm.Y = fromPrev.Y + toNext.Y;
                VectorTools.makePerpendicular(ref ptNorm);

                // this point is inside the other body.  now check if the edges on either side intersect with and edges on bodyB.
                float closestAway = 100000.0f;
                float closestSame = 100000.0f;

                infoAway.Clear();
                infoAway.bodyA = bA;
                infoAway.bodyApm = i;
                infoAway.bodyB = bB;

                infoSame.Clear();
                infoSame.bodyA = bA;
                infoSame.bodyApm = i;
                infoSame.bodyB = bB;

                bool found = false;

                int b1 = 0;
                int b2 = 1;
                for (int j = 0; j < bBpmCount; j++)
                {
                    Vector2 hitPt;
                    Vector2 norm;
                    float edgeD;

                    b1 = j;

                    if (j < bBpmCount - 1)
                        b2 = j + 1;
                    else
                        b2 = 0;

                    Vector2 pt1 = bB.getPointMass(b1).Position;
                    Vector2 pt2 = bB.getPointMass(b2).Position;

                    // quick test of distance to each point on the edge, if both are greater than current mins, we can skip!
                    float distToA = ((pt1.X - pt.X) * (pt1.X - pt.X)) + ((pt1.Y - pt.Y) * (pt1.Y - pt.Y));
                    float distToB = ((pt2.X - pt.X) * (pt2.X - pt.X)) + ((pt2.Y - pt.Y) * (pt2.Y - pt.Y));

                    if ((distToA > closestAway) && (distToA > closestSame) && (distToB > closestAway) && (distToB > closestSame))
                        continue;

                    // test against this edge.
                    float dist = bB.getClosestPointOnEdgeSquared(pt, j, out hitPt, out norm, out edgeD);

                    // only perform the check if the normal for this edge is facing AWAY from the point normal.
                    float dot;
                    //Vector2.Dot(ref ptNorm, ref edgeNorm, out dot);
                    Vector2.Dot(ref ptNorm, ref norm, out dot);
                    if (dot <= 0f)
                    {
                        if (dist < closestAway)
                        {
                            closestAway = dist;
                            infoAway.bodyBpmA = b1;
                            infoAway.bodyBpmB = b2;
                            infoAway.edgeD = edgeD;
                            infoAway.hitPt = hitPt;
                            infoAway.normal = norm;
                            infoAway.penetration = dist;
                            found = true;
                        }
                    }
                    else
                    {
                        if (dist < closestSame)
                        {
                            closestSame = dist;
                            infoSame.bodyBpmA = b1;
                            infoSame.bodyBpmB = b2;
                            infoSame.edgeD = edgeD;
                            infoSame.hitPt = hitPt;
                            infoSame.normal = norm;
                            infoSame.penetration = dist;
                        }
                    }
                }

                // we've checked all edges on BodyB.  add the collision info to the stack.
                if ((found) && (closestAway > mPenetrationThreshold) && (closestSame < closestAway))
                {
                    infoSame.penetration = (float)Math.Sqrt(infoSame.penetration);
                    infoList.Add(infoSame);
                }
                else
                {
                    infoAway.penetration = (float)Math.Sqrt(infoAway.penetration);
                    infoList.Add(infoAway);
                }
            }
        }
Exemple #4
0
        private void bodyCollide(Body bA, Body bB, List <BodyCollisionInfo> infoList)
        {
            int bApmCount = bA.PointMassCount;
            int bBpmCount = bB.PointMassCount;

            AABB boxB = bB.getAABB();

            // check all PointMasses on bodyA for collision against bodyB.  if there is a collision, return detailed info.
            BodyCollisionInfo infoAway = new BodyCollisionInfo();
            BodyCollisionInfo infoSame = new BodyCollisionInfo();

            for (int i = 0; i < bApmCount; i++)
            {
                Vector2 pt = bA.getPointMass(i).Position;

                // early out - if this point is outside the bounding box for bodyB, skip it!
                if (!boxB.contains(ref pt))
                {
                    continue;
                }

                // early out - if this point is not inside bodyB, skip it!
                if (!bB.contains(ref pt))
                {
                    continue;
                }

                int prevPt = (i > 0) ? i - 1 : bApmCount - 1;
                int nextPt = (i < bApmCount - 1) ? i + 1 : 0;

                Vector2 prev = bA.getPointMass(prevPt).Position;
                Vector2 next = bA.getPointMass(nextPt).Position;

                // now get the normal for this point. (NOT A UNIT VECTOR)
                Vector2 fromPrev = new Vector2();
                fromPrev.x = pt.x - prev.x;
                fromPrev.y = pt.y - prev.y;

                Vector2 toNext = new Vector2();
                toNext.x = next.x - pt.x;
                toNext.y = next.y - pt.y;

                Vector2 ptNorm = new Vector2();
                ptNorm.x = fromPrev.x + toNext.x;
                ptNorm.y = fromPrev.y + toNext.y;
                VectorTools.makePerpendicular(ref ptNorm);

                // this point is inside the other body.  now check if the edges on either side intersect with and edges on bodyB.
                float closestAway = 100000.0f;
                float closestSame = 100000.0f;

                infoAway.Clear();
                infoAway.bodyA   = bA;
                infoAway.bodyApm = i;
                infoAway.bodyB   = bB;

                infoSame.Clear();
                infoSame.bodyA   = bA;
                infoSame.bodyApm = i;
                infoSame.bodyB   = bB;

                bool found = false;

                int b1 = 0;
                int b2 = 1;
                for (int j = 0; j < bBpmCount; j++)
                {
                    Vector2 hitPt;
                    Vector2 norm;
                    float   edgeD;

                    b1 = j;

                    if (j < bBpmCount - 1)
                    {
                        b2 = j + 1;
                    }
                    else
                    {
                        b2 = 0;
                    }

                    Vector2 pt1 = bB.getPointMass(b1).Position;
                    Vector2 pt2 = bB.getPointMass(b2).Position;

                    // quick test of distance to each point on the edge, if both are greater than current mins, we can skip!
                    float distToA = ((pt1.x - pt.x) * (pt1.x - pt.x)) + ((pt1.y - pt.y) * (pt1.y - pt.y));
                    float distToB = ((pt2.x - pt.x) * (pt2.x - pt.x)) + ((pt2.y - pt.y) * (pt2.y - pt.y));


                    if ((distToA > closestAway) && (distToA > closestSame) && (distToB > closestAway) && (distToB > closestSame))
                    {
                        continue;
                    }

                    // test against this edge.
                    float dist = bB.getClosestPointOnEdgeSquared(pt, j, out hitPt, out norm, out edgeD);

                    // only perform the check if the normal for this edge is facing AWAY from the point normal.
                    float dot;
                    //Vector2.Dot(ref ptNorm, ref edgeNorm, out dot);
//                    Vector2.Dot(ref ptNorm, ref norm, out dot);
                    dot = Vector2.Dot(ptNorm, norm);
                    if (dot <= 0f)
                    {
                        if (dist < closestAway)
                        {
                            closestAway          = dist;
                            infoAway.bodyBpmA    = b1;
                            infoAway.bodyBpmB    = b2;
                            infoAway.edgeD       = edgeD;
                            infoAway.hitPt       = hitPt;
                            infoAway.normal      = norm;
                            infoAway.penetration = dist;
                            found = true;
                        }
                    }
                    else
                    {
                        if (dist < closestSame)
                        {
                            closestSame          = dist;
                            infoSame.bodyBpmA    = b1;
                            infoSame.bodyBpmB    = b2;
                            infoSame.edgeD       = edgeD;
                            infoSame.hitPt       = hitPt;
                            infoSame.normal      = norm;
                            infoSame.penetration = dist;
                        }
                    }
                }

                // we've checked all edges on BodyB.  add the collision info to the stack.
                if ((found) && (closestAway > mPenetrationThreshold) && (closestSame < closestAway))
                {
                    infoSame.penetration = (float)Math.Sqrt(infoSame.penetration);
                    infoList.Add(infoSame);
                }
                else
                {
                    infoAway.penetration = (float)Math.Sqrt(infoAway.penetration);
                    infoList.Add(infoAway);
                }
            }
        }