示例#1
0
    public override void DrawSceneGUI()
    {
        if (springBody == null || multiEditing)
        {
            return;
        }

        //draw the hovered over spring
        if (drawIndex != -1)
        {
            JelloSpring spring = springBody.getSpring(drawIndex);
            Vector3     posA;
            Vector3     posB;

            posA = springBody.transform.TransformPoint(springBody.Shape.getVertex(spring.pointMassA));
            posB = springBody.transform.TransformPoint(springBody.Shape.getVertex(spring.pointMassB));

            Handles.color = Color.magenta;

            if (spring.lengthMultiplier != 1f)
            {
                float   dist = Vector2.Distance(posA, posB) * spring.lengthMultiplier;
                Vector3 mid  = (posA + posB) * 0.5f;
                posA = mid + (mid - posA).normalized * dist * 0.5f;
                posB = mid + (mid - posB).normalized * dist * 0.5f;
            }

            Handles.DrawLine(posA, posB);
        }

        //TODO make it remember the selected spring?
        //draw the currently selected spring
        if (editIndex != -1 && editIndex < springBody.SpringCount)
        {
            JelloSpring spring = springBody.getSpring(editIndex);
            Handles.color = Color.cyan;

            Vector3[] globalHandlePositions = new Vector3[2];
            for (int i = 0; i < handlePositions.Length; i++)
            {
                globalHandlePositions[i] = springBody.transform.TransformPoint(handlePositions[i]);
            }
            CalculateHandleSizes(handlePositions);

            bool mouseUp = false;

            if (Event.current.type == EventType.mouseUp)
            {
                mouseUp = true;
            }

            for (int i = 0; i < handlePositions.Length; i++)
            {
                handlePositions[i] = springBody.transform.InverseTransformPoint(Handles.FreeMoveHandle(springBody.transform.TransformPoint(handlePositions[i]), Quaternion.identity, handleSizes[i], Vector3.zero, Handles.CircleCap));
            }
            //handlePositions[1] = springBody.transform.InverseTransformPoint( Handles.FreeMoveHandle(springBody.transform.TransformPoint(handlePositions[1]), Quaternion.identity, HandleUtility.GetHandleSize(handlePositions[1]) * 0.15f, Vector3.zero, Handles.CircleCap));

            Handles.color = Color.magenta;
            Handles.DrawLine(springBody.transform.TransformPoint(handlePositions[0]), springBody.transform.TransformPoint(handlePositions[1]));

            if (mouseUp)
            {
                if ((Vector2)handlePositions[0] != springBody.Shape.getVertex(spring.pointMassA))
                {
                    Vector2[] points = new Vector2[springBody.Shape.VertexCount];
                    for (int i = 0; i < springBody.Shape.VertexCount; i++)
                    {
                        points[i] = springBody.Shape.getVertex(i);
                    }

                    spring.pointMassA = JelloShapeTools.FindClosestVertexOnShape(handlePositions[0], points);

                    handlePositions[0] = springBody.Shape.getVertex(spring.pointMassA);

                    spring.length = Vector2.Distance(springBody.Shape.getVertex(spring.pointMassA), springBody.Shape.getVertex(spring.pointMassB));

                    EditorUtility.SetDirty(springBody);
                }

                if ((Vector2)handlePositions[1] != springBody.Shape.getVertex(spring.pointMassB))
                {
                    Vector2[] points = new Vector2[springBody.Shape.VertexCount];
                    for (int i = 0; i < springBody.Shape.VertexCount; i++)
                    {
                        points[i] = springBody.Shape.getVertex(i);
                    }

                    spring.pointMassB = JelloShapeTools.FindClosestVertexOnShape(handlePositions[1], points);

                    handlePositions[1] = springBody.Shape.getVertex(spring.pointMassB);

                    spring.length = Vector2.Distance(springBody.Shape.getVertex(spring.pointMassA), springBody.Shape.getVertex(spring.pointMassB));

                    EditorUtility.SetDirty(springBody);
                }
            }

            Vector3 posA = springBody.transform.TransformPoint(springBody.Shape.getVertex(spring.pointMassA));
            Vector3 posB = springBody.transform.TransformPoint(springBody.Shape.getVertex(spring.pointMassB));

            if (spring.lengthMultiplier != 1f)
            {
                float   dist = Vector2.Distance(posA, posB) * spring.lengthMultiplier;
                Vector3 mid  = (posA + posB) * 0.5f;
                posA = mid + (mid - posA).normalized * dist * 0.5f;
                posB = mid + (mid - posB).normalized * dist * 0.5f;
            }

            Handles.color = Color.blue;

            Handles.DrawLine(posA, posB);
        }

        if (newSubComponentState != AddSubComponentState.inactive)
        {
            if (Event.current.isKey && Event.current.keyCode == KeyCode.Escape)
            {
                newSubComponentState = AddSubComponentState.inactive;
            }


            int controlID = GUIUtility.GetControlID(GetHashCode(), FocusType.Passive);

            if (Event.current.type == EventType.Layout)
            {
                HandleUtility.AddDefaultControl(controlID);
            }

            Handles.color = Color.red;

            Vector3 pos   = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition).origin;           //need where this ray intersects the zplane
            Plane   plane = new Plane(Vector3.forward, new Vector3(0, 0, springBody.transform.position.z));
            Ray     ray   = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
            float   dist  = 0f;
            plane.Raycast(ray, out dist);
            pos = ray.GetPoint(dist);
            Vector3 mousePosWorld = new Vector3(pos.x, pos.y, springBody.transform.position.z);

            if (newSubComponentState == AddSubComponentState.assignedFirst)
            {
                pos = springBody.transform.TransformPoint(springBody.Shape.getVertex(newSpring.pointMassA));
                Handles.CircleCap(3, pos, Quaternion.identity, HandleUtility.GetHandleSize(pos) * 0.15f);
                Handles.DrawLine(pos, mousePosWorld);

                Handles.color = Color.blue;
                Handles.CircleCap(3, mousePosWorld, Quaternion.identity, HandleUtility.GetHandleSize(mousePosWorld) * 0.15f);

                if (Event.current.type == EventType.MouseUp)
                {
                    Vector2[] points = new Vector2[springBody.Shape.VertexCount];
                    for (int i = 0; i < springBody.Shape.VertexCount; i++)
                    {
                        points[i] = springBody.Shape.getVertex(i);
                    }

                    newSpring.pointMassB = JelloShapeTools.FindClosestVertexOnShape(springBody.transform.InverseTransformPoint(mousePosWorld), points);
                    newSpring.length     = Vector2.Distance(springBody.Shape.getVertex(newSpring.pointMassA), springBody.Shape.getVertex(newSpring.pointMassB));
                    newSpring.stiffness  = springBody.DefaultCustomSpringStiffness;
                    newSpring.damping    = springBody.DefaultCustomSpringDamping;

                    editIndex = springBody.SpringCount;
                    springBody.addCustomSpring(newSpring);
                    newSubComponentState = AddSubComponentState.inactive;

                    handlePositions[0] = springBody.Shape.getVertex(newSpring.pointMassA);
                    handlePositions[1] = springBody.Shape.getVertex(newSpring.pointMassB);

                    eCustomSprings.isExpanded   = true;
                    eEdgeSprings.isExpanded     = false;
                    eInternalSprings.isExpanded = false;

                    EditorUtility.SetDirty(springBody);
                }
            }
            if (newSubComponentState == AddSubComponentState.initiated)
            {
                Handles.CircleCap(3, mousePosWorld, Quaternion.identity, HandleUtility.GetHandleSize(mousePosWorld) * 0.15f);

                if (Event.current.type == EventType.MouseUp)
                {
                    Vector2[] points = new Vector2[springBody.Shape.VertexCount];
                    for (int i = 0; i < springBody.Shape.VertexCount; i++)
                    {
                        points[i] = springBody.Shape.getVertex(i);
                    }

                    newSpring            = new JelloSpring();
                    newSpring.pointMassA = JelloShapeTools.FindClosestVertexOnShape(springBody.transform.InverseTransformPoint(mousePosWorld), points);
                    newSubComponentState = AddSubComponentState.assignedFirst;
                }
            }

            SceneView.RepaintAll();
        }

        if (newSubComponentState != AddSubComponentState.inactive || editIndex != -1)
        {
            Handles.color = new Color(0.5f, 0.5f, 0.5f, 0.5f);

            for (int i = springBody.EdgeSpringCount; i < springBody.SpringCount; i++)
            {
                if (editIndex == i)
                {
                    continue;
                }
                Handles.DrawLine(springBody.transform.TransformPoint(springBody.Shape.getVertex(springBody.getSpring(i).pointMassA)), springBody.transform.TransformPoint(springBody.Shape.getVertex(springBody.getSpring(i).pointMassB)));
            }

            mainEditor.DrawPointMasses(springBody, false);
        }
    }
	/// <summary>
	/// Grabs the point mass.
	/// </summary>
	public void GrabPointMass()
	{
		//i am now pulling the body.
		pulling = true;
	
		//clear old values from last pull
		adjacentPointMasses.Clear();
		oldMultipliers.Clear();

		//set the position to lock it in place while pulling the body
		position = body.Position;

		//get the closest point mass to the mouse positions and cache some information about it.
		mousePosInWorld = Camera.main.ScreenToWorldPoint(Input.mousePosition);
		pmIndex = body.getClosestPointMass(mousePosInWorld, false); //only grab edge point masses
		pointmass = body.getEdgePointMass(pmIndex);
		oldMultipliers.Add (pointmass.shapeMatchingMultiplier);
		pointmass.shapeMatchingMultiplier = 0f;
		adjacentPointMasses.Add (pointmass);

		//Set the body to kinematic to keep it in place while pulling.
		body.IsKinematic = true; 
		
		int adjIndex = 0;
		int numFromStart = 0;
		//grab adjacent point masses further in the array.
		for(int i = pmIndex; i < pmIndex + numAdjacentPoints; i++)
		{
			adjIndex = i > body.EdgePointMassCount - 1 ? i - body.EdgePointMassCount : i;
			
			if(adjIndex > body.EdgePointMassCount - 1 || adjacentPointMasses.Contains(body.getEdgePointMass(adjIndex)))
				continue;

			//cache the point mass info and modify the shape matching values by how close it is to the grabbed point mass
			adjacentPointMasses.Add (body.getEdgePointMass(adjIndex));
			oldMultipliers.Add(body.getEdgePointMass(adjIndex).shapeMatchingMultiplier);
			numFromStart++;
			body.getEdgePointMass(adjIndex).shapeMatchingMultiplier = numFromStart / (numAdjacentPoints + 1 + adjacentDropoff);
		}
		numFromStart = 0;
		//grab adjacent point masses before the current index in the array.
		for(int i = pmIndex; i > pmIndex - numAdjacentPoints; i--)
		{
			adjIndex = i < 0 ? i + body.EdgePointMassCount: i;
			if(adjIndex < 0 || adjacentPointMasses.Contains(body.getEdgePointMass(adjIndex)))
				continue;

			//cache the point mass info and modify the shape matching values by how close it is to the grabbed point mass
			adjacentPointMasses.Add (body.getEdgePointMass(adjIndex));
			oldMultipliers.Add(body.getEdgePointMass(adjIndex).shapeMatchingMultiplier);
			numFromStart++;
			body.getEdgePointMass(adjIndex).shapeMatchingMultiplier = numFromStart / (numAdjacentPoints + 1 + adjacentDropoff);
		}
		//find any internal point masses connected to the selected point mass (via spring) and cache/modify its shape matching multiplier.
		for(int i = 0; i < body.SpringCount; i++)
		{
			if(body.getSpring(i).pointMassA == pmIndex || body.getSpring(i).pointMassB == pmIndex)
			{
				if(body.getSpring(i).pointMassA >= body.EdgePointMassCount)
				{
					adjacentPointMasses.Add (body.getPointMass(body.getSpring(i).pointMassA));
					oldMultipliers.Add (body.getPointMass(body.getSpring(i).pointMassA).shapeMatchingMultiplier);
					body.getPointMass(body.getSpring(i).pointMassA).shapeMatchingMultiplier = 1 / (2 + adjacentDropoff);
				}
				else if(body.getSpring(i).pointMassB >= body.EdgePointMassCount)
				{
					adjacentPointMasses.Add (body.getPointMass(body.getSpring(i).pointMassB));
					oldMultipliers.Add (body.getPointMass(body.getSpring(i).pointMassB).shapeMatchingMultiplier);
					body.getPointMass(body.getSpring(i).pointMassB).shapeMatchingMultiplier = 1 / (2 + adjacentDropoff);
				}
			}
		}
	}