示例#1
0
	//anchor is local //vertices are local //have vector2 return?
	/// <summary>
	/// Rebuilds the anchor.
	/// </summary>
	/// <param name="anchor">The anchor (In local space).</param>
	/// <param name="isAnchorA">Whether to rebuild the first anchor as opposed to rebuilding the second anchor.</param>
	/// <param name="useBaseShape">Whether use JelloBody.Shape instead of JelloPointMass.Position. Has no effect if Transform has no JelloBody attached.</param>
	/// <param name="affectedIndices">The indices of the affected / affecting JelloPointMass objects. Has no effect if Transform has no JelloBody attached.</param>
	/// <param name="affectedVertices">The positions (in local space) of the affected / affecting JelloPointMass objects. Has no effect if Transform has no JelloBody attached.</param>
	public void RebuildAnchor(Vector2 anchor, bool isAnchorA, bool useBaseShape, int[] affectedIndices = null, Vector2[] affectedVertices = null)
	{
		//Vector2 point;

		if(isAnchorA)
		{
			localAnchorA = anchor;

			if(mTransformA == null)
				return;

			if(bodyA != null)
			{
				if(affectedIndices == null)
					affectedIndices = affectedIndicesA;
				else
					affectedIndicesA = affectedIndices;

				if(affectedVertices == null)//grab from point mass positions?
				{
					if(useBaseShape)
					{
						affectedVertices = new Vector2[affectedIndicesA.Length];
						for(int i = 0; i < affectedIndicesA.Length; i++)
							affectedVertices[i] = bodyA.Shape.getVertex(affectedIndicesA[i]);
					}
					else
					{
						affectedVertices = new Vector2[affectedIndicesA.Length];
						for(int i = 0; i < affectedIndicesA.Length; i++)
							affectedVertices[i] = bodyA.getPointMass(affectedIndicesA[i]).LocalPosition;
					}
				}

				if(affectedIndices != null)
				{
					if(affectedIndices.Length == 1)
					{
						scalarsA = new float[1];
						scalarsA[0] = 1f;
					}
					else if(affectedIndices.Length == 2)
					{
						Vector2 hit;

						scalarsA = new float[2];
						JelloVectorTools.getClosestPointOnSegmentSquared (localAnchorA, affectedVertices[0], affectedVertices[1], out hit, out scalarsA[1]);
						scalarsA[0] = 1 - scalarsA[1];
					}
					else if(affectedIndices.Length == 3)
					{
						scalarsA = JelloShapeTools.GetBarycentricCoords(localAnchorA, affectedVertices);
					}
				}
			}
		}
		else
		{
			localAnchorB = anchor;
			
			if(mTransformB == null)
				return;
			
			if(bodyB != null)
			{
				if(affectedIndices == null)
					affectedIndices = affectedIndicesB;
				else
					affectedIndicesB = affectedIndices;
				
				if(affectedVertices == null)//grab from point mass positions?
				{
					if(useBaseShape)
					{
						affectedVertices = new Vector2[affectedIndicesB.Length];
						for(int i = 0; i < affectedIndicesB.Length; i++)
							affectedVertices[i] = bodyB.Shape.getVertex(affectedIndicesB[i]);
					}
					else
					{
						affectedVertices = new Vector2[affectedIndicesB.Length];
						for(int i = 0; i < affectedIndicesB.Length; i++)
							affectedVertices[i] = bodyB.getPointMass(affectedIndicesB[i]).LocalPosition;
					}
				}
				
				if(affectedIndices != null)
				{
					if(affectedIndices.Length == 1)
					{
						scalarsB = new float[1];
						scalarsB[0] = 1f;
					}
					else if(affectedIndices.Length == 2)
					{
						Vector2 hit;
						
						scalarsB = new float[2];
						JelloVectorTools.getClosestPointOnSegmentSquared (localAnchorB, affectedVertices[0], affectedVertices[1], out hit, out scalarsB[1]);
						scalarsB[0] = 1 - scalarsB[1];
					}
					else if(affectedIndices.Length == 3)
					{
						scalarsB = JelloShapeTools.GetBarycentricCoords(localAnchorB, affectedVertices);
					}
				}
			}
		}
	}
示例#2
0
    /// <summary>
    /// Update this JelloAttachPoint .
    /// Will derive the new position for the JelloAttachPoint.point, AttachTransform.Position and AttachedTrasnform.Angle.
    /// This will be called by the simulation and should not need to be called manualy.
    /// </summary>
    /// <param name="useBaseShape">Whether to use the JelloBody.Shape positions to determine the new position.</param>
    public Vector2 Update(bool useBaseShape)
    {
        point = Vector2.zero;
        if (useBaseShape)
        {
            for (int i = 0; i < affectedIndices.Length; i++)
            {
                point += body.Shape.getVertex(affectedIndices[i]) * scalars[i];
            }

            if (point.x == float.NaN)
            {
                for (int i = 0; i < affectedIndices.Length; i++)
                {
                    Debug.Log(body.Shape.getVertex(affectedIndices[i]) + "     " + scalars[i]);
                }
            }
        }
        else
        {
            for (int i = 0; i < affectedIndices.Length; i++)
            {
                point += body.getPointMass(affectedIndices[i]).Position *scalars[i];
            }

            point = transform.InverseTransformPoint(point);

            if (point.x == float.NaN)
            {
                for (int i = 0; i < affectedIndices.Length; i++)
                {
                    Debug.Log(body.getPointMass(affectedIndices[i]).Position + "     " + scalars[i]);
                }
            }
        }


        if (mAttachedTransform != null)
        {
            Vector3 newPos = transform.TransformPoint(point);
            newPos.z = mAttachedTransform.position.z;
            mAttachedTransform.position = newPos;
            if (rotate)
            {
                float   angle         = 0;
                int     originalSign  = 1;
                float   originalAngle = 0;
                float   thisAngle;
                Vector2 center       = Vector2.zero;
                Vector2 centerGlobal = Vector2.zero;

                if (affectedIndices.Length == 1)
                {
                    centerGlobal = body.Position;
                }
                else
                {
                    for (int i = 0; i < affectedIndices.Length; i++)
                    {
                        center += body.Shape.getVertex(affectedIndices[i]);
                    }
                    center /= affectedIndices.Length;

                    centerGlobal = Vector2.zero;
                    for (int i = 0; i < affectedIndices.Length; i++)
                    {
                        centerGlobal += body.getPointMass(affectedIndices[i]).Position;
                    }
                    centerGlobal /= affectedIndices.Length;
                }

                for (int i = 0; i < affectedIndices.Length; i++)
                {
                    thisAngle = Vector2.Angle(body.Shape.getVertex(affectedIndices[i]) - center, body.getPointMass(affectedIndices[i]).Position - centerGlobal);                  //(Vector2)body.transform.TransformPoint(center));
                    if (Vector3.Cross(body.Shape.getVertex(affectedIndices[i]) - center, body.getPointMass(affectedIndices[i]).Position - centerGlobal).z < 0f)                   //(Vector2)body.transform.TransformPoint(center)).z < 0f)
                    {
                        thisAngle *= -1f;
                    }

                    if (i == 0)
                    {
                        originalSign  = (thisAngle >= 0f) ? 1 : -1;
                        originalAngle = thisAngle;
                    }
                    else
                    {
                        if ((Mathf.Abs(thisAngle - originalAngle) > 180f) && ((thisAngle >= 0f ? 1 : -1) != originalSign))
                        {
                            thisAngle = ((thisAngle >= 0f ? 1 : -1) == -1) ? 360f + thisAngle : -thisAngle;
                        }
                    }

                    angle += thisAngle;
                }

                angle /= affectedIndices.Length;

                mAttachedTransform.eulerAngles = new Vector3(mAttachedTransform.eulerAngles.x, mAttachedTransform.eulerAngles.y, angle + transformAngle);
            }
        }

        return(point);
    }
示例#3
0
    /// <summary>
    /// Rebuild this JelloAttachPoint.
    /// </summary>
    /// <param name="attachPoint">The point (local to the JelloAttachPoint.body) at which to attach the JelloAttachPoint.AttachedTransform.</param>
    /// <param name="jelloBody">The JelloBody to to be attached to.</param>
    /// <param name="indices">The JelloPointMass Indices. Should have a length of 1, 2, or 3.</param>
    /// <param name="useBaseShape">Whether to use the  JelloBody.Shape positions (instead of JelloPointMass.Position) when building the JelloAttachPoint.</param>
    public void Rebuild(Vector2 attachPoint, JelloBody jelloBody, int[] indices, bool useBaseShape = true)
    {
        body      = jelloBody;
        transform = body.transform;

        if (indices == null)
        {
            if (affectedIndices == null)
            {
                Rebuild(attachPoint, jelloBody, useBaseShape);
                return;
            }
            else
            {
                indices = affectedIndices;
            }
        }
        else if (indices.Length > 4)
        {
            affectedIndices = new int[3];
            for (int i = 0; i < 3; i++)
            {
                affectedIndices[i] = indices[i];
            }
        }
        else
        {
            affectedIndices = indices;
        }

        Vector2[] verts = new Vector2[3];

        if (useBaseShape)
        {
            for (int i = 0; i < affectedIndices.Length; i++)
            {
                verts[i] = body.Shape.getVertex(affectedIndices[i]);
            }
        }
        else
        {
            attachPoint = transform.TransformPoint(attachPoint);
            for (int i = 0; i < affectedIndices.Length; i++)
            {
                verts[i] = body.getPointMass(affectedIndices[i]).Position;
            }
        }

        if (affectedIndices.Length == 1)
        {
            scalars    = new float[1];
            scalars[0] = 1f;
        }
        else if (affectedIndices.Length == 2)
        {
            Vector2 hit;

            scalars = new float[2];
            JelloVectorTools.getClosestPointOnSegmentSquared(attachPoint, verts[0], verts[1], out hit, out scalars[1]);
            scalars[0] = 1 - scalars[1];
        }
        else if (affectedIndices.Length == 3)
        {
            scalars = JelloShapeTools.GetBarycentricCoords(attachPoint, verts);
        }

        //throw into for loop...
        point = Vector2.zero;
        for (int i = 0; i < affectedIndices.Length; i++)
        {
            point += scalars[i] * verts[i];
        }

        if (!useBaseShape)
        {
            point = transform.InverseTransformPoint(point);
        }

        if (mAttachedTransform != null)
        {
            Vector3 newPos = transform.TransformPoint(point);
            newPos.z = mAttachedTransform.position.z;
            mAttachedTransform.position = newPos;
        }
    }
示例#4
0
    /// <summary>
    /// Rebuild this JelloAttachPoint.
    /// </summary>
    /// <param name="attachPoint">The point (local to the JelloAttachPoint.body) at which to attach the JelloAttachPoint.AttachedTransform.</param>
    /// <param name="jelloBody">The JelloBody to to be attached to.</param>
    /// <param name="useBaseShape">Whether to use the  JelloBody.Shape positions (instead of JelloPointMass.Position) when building the JelloAttachPoint.</param>
    /// <param name="numLegs">Number of JelloPointMass objects to use as "legs" (use 1, 2, or 3).</param>
    public void Rebuild(Vector2 attachPoint, JelloBody jelloBody, bool useBaseShape = true, int numLegs = 0)
    {
        body      = jelloBody;
        transform = body.transform;

        if (numLegs != 0)
        {
            if (numLegs < 0)
            {
                numLegs = 1;
            }
            if (numLegs > 3)
            {
                numLegs = 3;
            }

            affectedIndices = new int[numLegs];
        }
        else if (affectedIndices == null || affectedIndices.Length == 0 || affectedIndices.Length > 3)
        {
            affectedIndices = new int[2];            //default to 3?
        }
        Vector2[] shape = new Vector2[body.Shape.VertexCount];
        if (useBaseShape)
        {
            for (int i = 0; i < shape.Length; i++)
            {
                shape[i] = body.Shape.getVertex(i);
            }
        }
        else
        {
            attachPoint = transform.TransformPoint(attachPoint);

            for (int i = 0; i < shape.Length; i++)
            {
                shape[i] = body.getPointMass(i).Position;
            }
        }

        if (affectedIndices.Length == 1)
        {
            affectedIndices = JelloShapeTools.GetClosestIndices(attachPoint, shape, 1);
            scalars         = new float[1];
            scalars[0]      = 1f;
        }
        else if (affectedIndices.Length == 2)
        {
            Vector2 hit;
            affectedIndices = JelloShapeTools.FindClosestEdgeOnShape(attachPoint, shape);
            scalars         = new float[2];
            JelloVectorTools.getClosestPointOnSegmentSquared(attachPoint, shape[affectedIndices[0]], shape[affectedIndices[1]], out hit, out scalars[1]);
            scalars[0] = 1 - scalars[1];
        }
        else if (affectedIndices.Length == 3)
        {
            Vector2[] shapePerimeter = new Vector2[body.EdgePointMassCount];
            if (useBaseShape)
            {
                shapePerimeter = body.Shape.EdgeVertices;
            }
            else
            {
                for (int i = 0; i < shapePerimeter.Length; i++)
                {
                    shapePerimeter[i] = body.getEdgePointMass(i).Position;
                }
            }

            affectedIndices = JelloShapeTools.FindContainingTriangle(attachPoint, shape, shapePerimeter, body.Shape.Triangles, out scalars);
        }

        point = Vector2.zero;
        for (int i = 0; i < affectedIndices.Length; i++)
        {
            point += shape[affectedIndices[i]] * scalars[i];
        }


        if (!useBaseShape)
        {
            point = transform.InverseTransformPoint(point);
        }

        if (mAttachedTransform != null)
        {
            Vector3 newPos = transform.TransformPoint(point);
            newPos.z = mAttachedTransform.position.z;
            mAttachedTransform.position = newPos;
        }
    }
    /// <summary>
    /// Rebuild this JelloAttachPoint.
    /// </summary>
    /// <param name="attachPoint">The point (local to the JelloAttachPoint.body) at which to attach the JelloAttachPoint.AttachedTransform.</param>
    /// <param name="jelloBody">The JelloBody to to be attached to.</param>
    /// <param name="indices">The JelloPointMass Indices. Should have a length of 1, 2, or 3.</param>
    /// <param name="useBaseShape">Whether to use the  JelloBody.Shape positions (instead of JelloPointMass.Position) when building the JelloAttachPoint.</param>
    public void Rebuild(Vector2 attachPoint, JelloBody jelloBody, int[] indices, bool useBaseShape = true)
    {
        body = jelloBody;
        transform = body.transform;

        if(indices == null)
        {
            if(affectedIndices == null)
            {
                Rebuild(attachPoint, jelloBody, useBaseShape);
                return;
            }
            else
            {
                indices = affectedIndices;
            }
        }
        else if(indices.Length > 4)
        {
            affectedIndices = new int[3];
            for(int i = 0; i < 3; i++)
                affectedIndices[i] = indices[i];
        }
        else
        {
            affectedIndices = indices;
        }

        Vector2[] verts = new Vector2[3];

        if(useBaseShape)
        {
            for(int i = 0; i < affectedIndices.Length; i++)
                verts[i] = body.Shape.getVertex(affectedIndices[i]);
        }
        else
        {
            attachPoint = transform.TransformPoint(attachPoint);
            for(int i = 0; i < affectedIndices.Length; i++)
                verts[i] = body.getPointMass(affectedIndices[i]).Position;
        }

        if(affectedIndices.Length == 1)
        {
            scalars = new float[1];
            scalars[0] = 1f;
        }
        else if(affectedIndices.Length == 2)
        {
            Vector2 hit;

            scalars = new float[2];
            JelloVectorTools.getClosestPointOnSegmentSquared (attachPoint, verts[0], verts[1], out hit, out scalars[1]);
            scalars[0] = 1 - scalars[1];
        }
        else if (affectedIndices.Length == 3)
        {
            scalars = JelloShapeTools.GetBarycentricCoords(attachPoint, verts);
        }

        //throw into for loop...
        point = Vector2.zero;
        for(int i = 0; i < affectedIndices.Length; i++)
            point += scalars[i] * verts[i];

        if(!useBaseShape)
            point = transform.InverseTransformPoint(point);

        if(mAttachedTransform != null)
        {
            Vector3 newPos = transform.TransformPoint(point);
            newPos.z = mAttachedTransform.position.z;
            mAttachedTransform.position = newPos;
        }
    }
    /// <summary>
    /// Rebuild this JelloAttachPoint.
    /// </summary>
    /// <param name="attachPoint">The point (local to the JelloAttachPoint.body) at which to attach the JelloAttachPoint.AttachedTransform.</param>
    /// <param name="jelloBody">The JelloBody to to be attached to.</param>
    /// <param name="useBaseShape">Whether to use the  JelloBody.Shape positions (instead of JelloPointMass.Position) when building the JelloAttachPoint.</param>
    /// <param name="numLegs">Number of JelloPointMass objects to use as "legs" (use 1, 2, or 3).</param>
    public void Rebuild(Vector2 attachPoint, JelloBody jelloBody, bool useBaseShape = true, int numLegs = 0)
    {
        body = jelloBody;
        transform = body.transform;

        if(numLegs != 0)
        {
            if(numLegs < 0)
                numLegs = 1;
            if(numLegs > 3)
                numLegs = 3;

            affectedIndices = new int[numLegs];
        }
        else if(affectedIndices == null || affectedIndices.Length == 0 || affectedIndices.Length > 3)
            affectedIndices = new int[2];//default to 3?

        Vector2[] shape = new Vector2[body.Shape.VertexCount];
        if(useBaseShape)
        {
            for(int i = 0; i < shape.Length; i++)
                shape[i] = body.Shape.getVertex(i);
        }
        else
        {
            attachPoint = transform.TransformPoint(attachPoint);

            for(int i = 0; i < shape.Length; i++)
                shape[i] = body.getPointMass(i).Position;
        }

        if(affectedIndices.Length == 1)
        {
            affectedIndices = JelloShapeTools.GetClosestIndices(attachPoint, shape, 1);
            scalars = new float[1];
            scalars[0] = 1f;
        }
        else if(affectedIndices.Length == 2)
        {
            Vector2 hit;
            affectedIndices = JelloShapeTools.FindClosestEdgeOnShape(attachPoint, shape);
            scalars = new float[2];
            JelloVectorTools.getClosestPointOnSegmentSquared (attachPoint, shape[affectedIndices[0]], shape[affectedIndices[1]], out hit, out scalars[1]);
            scalars[0] = 1 - scalars[1];
        }
        else if(affectedIndices.Length == 3)
        {
            Vector2[] shapePerimeter = new Vector2[body.EdgePointMassCount];
            if(useBaseShape)
            {
                shapePerimeter = body.Shape.EdgeVertices;
            }
            else
            {
                for(int i = 0; i < shapePerimeter.Length; i++)
                    shapePerimeter[i] = body.getEdgePointMass(i).Position;
            }

            affectedIndices = JelloShapeTools.FindContainingTriangle(attachPoint, shape, shapePerimeter, body.Shape.Triangles, out scalars);
        }

        point = Vector2.zero;
        for(int i = 0; i < affectedIndices.Length; i++)
            point += shape[affectedIndices[i]] * scalars[i];

        if(!useBaseShape)
            point = transform.InverseTransformPoint(point);

        if(mAttachedTransform != null)
        {
            Vector3 newPos = transform.TransformPoint(point);
            newPos.z = mAttachedTransform.position.z;
            mAttachedTransform.position = newPos;
        }
    }