//TODO draw some info for the other body as well? like an outline?
	public void DrawjointSceneGUI()
	{
		mainEditor.DrawPointMasses(body, false);

		Vector3 pos;
		
		//hovered over joint
		if(drawIndex >= 0 && drawIndex < body.JointCount && body.GetJoint(drawIndex).bodyA != null)
		{
			JelloJoint joint = body.GetJoint(drawIndex);

			Vector3 posA = body.transform.TransformPoint(joint.GetAnchorPointA(true));
			posA.z = body.transform.position.z;

			Handles.color = Color.magenta;
			for(int i = 0; i < joint.affectedIndicesA.Length; i++)
			{
				Handles.DrawLine(posA, body.transform.TransformPoint(body.Shape.getVertex(joint.affectedIndicesA[i])));
				Handles.DotCap(3, 
				               body.transform.TransformPoint(body.Shape.getVertex(joint.affectedIndicesA[i])), 
				               Quaternion.identity, 
				               HandleUtility.GetHandleSize(body.transform.TransformPoint(body.Shape.getVertex(joint.affectedIndicesA[i]))) * 0.05f);
			}
			Handles.color = Color.blue;
			Handles.DotCap(3, posA, Quaternion.identity, HandleUtility.GetHandleSize(posA) * 0.075f);

			Vector3 posB = joint.GetAnchorPointB(true);



			if(joint.TransformB !=  null)
			{
				posB = joint.TransformB.TransformPoint(posB);
				
				if(joint.bodyB != null)
				{
					if(joint.affectedIndicesB != null)
					{


						Handles.color = Color.magenta;
						for(int i = 0; i < body.GetJoint(drawIndex).affectedIndicesB.Length; i++)
						{
							Handles.DrawLine(posB, joint.bodyB.transform.TransformPoint(joint.bodyB.Shape.getVertex(joint.affectedIndicesB[i])));
							Handles.DotCap(3, 
							               joint.bodyB.transform.TransformPoint(joint.bodyB.Shape.getVertex(joint.affectedIndicesB[i])), 
							               Quaternion.identity, 
							               HandleUtility.GetHandleSize(joint.bodyB.transform.TransformPoint(joint.bodyB.Shape.getVertex(joint.affectedIndicesB[i]))) * 0.05f);
						}
						Handles.color = Color.blue;
					}
				}
				
				
			}
			
			Handles.DotCap(3, posB, Quaternion.identity, HandleUtility.GetHandleSize(posB) * 0.075f);
			
			Handles.color = Color.red;
			Handles.DrawLine(posA, posB);
		}
		
		//selected joint
		if(editIndex >= 0 && editIndex < body.JointCount && body.GetJoint(editIndex).affectedIndicesA != null)
		{	
			JelloJoint joint = body.GetJoint(editIndex);


			int num = 2 + joint.affectedIndicesA.Length;
			if(joint.TransformB != null && joint.bodyB != null)
				num += joint.affectedIndicesB.Length;

			//first get handle sizes...
			//need global handle positions
			Vector3[] globalHandlePositions = new Vector3[num];

			globalHandlePositions[0] = body.transform.TransformPoint(handlePositions[0]);
			for(int i = 0; i < joint.affectedIndicesA.Length; i++)
				globalHandlePositions[i + 2] = body.transform.TransformPoint(handlePositions[i + 2]);
			
			
			if(joint.TransformB != null)
			{
				globalHandlePositions[1] = joint.TransformB.TransformPoint(handlePositions[1]);

				if(joint.bodyB != null)
				{
					for(int i = 0; i < joint.affectedIndicesB.Length; i++)
					{
						globalHandlePositions[i + 2 + joint.affectedIndicesA.Length] = joint.TransformB.TransformPoint(handlePositions[i + 2 + joint.affectedIndicesA.Length]);
					}
				}
			}
			else
			{
				globalHandlePositions[1] = joint.globalAnchorB;
			}

			CalculateHandleSizes(globalHandlePositions);
			
			bool mouseUp = false;
			
			if(Event.current.type == EventType.mouseUp)
				mouseUp = true;
			
			Handles.color = Color.cyan;
			
			EditorGUI.BeginChangeCheck();
			handlePositions[0] = body.transform.InverseTransformPoint( Handles.FreeMoveHandle(body.transform.TransformPoint(handlePositions[0]), Quaternion.identity, handleSizes[0], Vector3.zero, Handles.CircleCap));
			if(EditorGUI.EndChangeCheck())
			{
				Vector2[] affectedPoints = new Vector2[joint.affectedIndicesA.Length];
				for(int i = 0; i < affectedPoints.Length; i++)
					affectedPoints[i] = body.Shape.getVertex(joint.affectedIndicesA[i]);
				
				joint.RebuildAnchor
					(
						handlePositions[0], 
						true, 
						true,
						joint.affectedIndicesA,
						affectedPoints
						);
				SetEditIndex(editIndex);

				EditorUtility.SetDirty(body);

				SceneView.RepaintAll();
			}

			for(int i = 0; i < joint.affectedIndicesA.Length; i++)
			{
				Handles.color = Color.blue;
				handlePositions[i + 2] = body.transform.InverseTransformPoint(Handles.FreeMoveHandle(body.transform.TransformPoint(handlePositions[i + 2]), 
				                                                                                Quaternion.identity, 
				                                                                                handleSizes[i + 2],
				                                                                                Vector3.zero,  
				                                                                                Handles.CircleCap));
				
				if(mouseUp)
				{
					if((Vector2)handlePositions[i + 2] != body.Shape.getVertex(joint.affectedIndicesA[i]))
					{
						Vector2[] points = new Vector2[body.Shape.VertexCount];
						for(int s = 0; s < body.Shape.VertexCount; s++)
							points[s] = body.Shape.getVertex(s);
						
						int index = JelloShapeTools.FindClosestVertexOnShape(handlePositions[i + 2], points);
						bool indexInUse = false;
						
						for(int u = 0; u < joint.affectedIndicesA.Length; u++)
							if(index == joint.affectedIndicesA[u])
								indexInUse = true;
						
						if(!indexInUse)
						{
							joint.affectedIndicesA[i] = index;
							
							Vector2[] affectedVertices = new Vector2[joint.affectedIndicesA.Length];
							for(int v = 0; v < affectedVertices.Length; v++)
								affectedVertices[v] = body.Shape.getVertex(joint.affectedIndicesA[v]); 
							
							handlePositions[i + 2] = body.Shape.getVertex(index);
							
							
							joint.RebuildAnchor(joint.localAnchorA, true, true, null, affectedVertices);

							Vector2 newPosition = Vector2.zero;
							for(int v = 0; v < affectedVertices.Length; v++)
								newPosition += affectedVertices[v] * joint.scalarsA[v];

							handlePositions[0] = newPosition;

							EditorUtility.SetDirty(body);

							SceneView.RepaintAll();
						}
						else
						{
							handlePositions[i + 2] = body.Shape.getVertex(joint.affectedIndicesA[i]);
						}
					}
				}
				
				Handles.color = Color.black;
				Handles.DrawLine(body.transform.TransformPoint(handlePositions[0]), body.transform.TransformPoint( handlePositions[i + 2]));
			}
			
			//other object's GUI
			Handles.color = Color.magenta;
			
			if(joint.TransformB != null)
			{
				EditorGUI.BeginChangeCheck();
				handlePositions[1] = joint.TransformB.InverseTransformPoint( Handles.FreeMoveHandle(joint.TransformB.TransformPoint(handlePositions[1]), Quaternion.identity, handleSizes[1], Vector3.zero, Handles.CircleCap));
				if(EditorGUI.EndChangeCheck())
				{
					Vector2[] affectedPoints = new Vector2[0];
					
					if(joint.bodyB != null)
					{
						affectedPoints = new Vector2[joint.affectedIndicesB.Length];
						for(int i = 0; i < affectedPoints.Length; i++)
							affectedPoints[i] = joint.bodyB.Shape.getVertex(joint.affectedIndicesB[i]);
					}
					
					joint.RebuildAnchor
						(
							handlePositions[1], 
							false,
							true,
							joint.affectedIndicesB,
							affectedPoints
							);
					
					SetEditIndex(editIndex);

					EditorUtility.SetDirty(body);

					SceneView.RepaintAll();
				}

				if(joint.bodyB != null && joint.affectedIndicesB != null)
				{	
					int numAffectedA = joint.affectedIndicesA.Length;
					for(int i = 0; i < joint.affectedIndicesB.Length; i++)
					{
						int offsetIndex = i + numAffectedA + 2;
						
						Handles.color = Color.red;
						handlePositions[offsetIndex] = joint.TransformB.InverseTransformPoint(Handles.FreeMoveHandle(joint.TransformB.TransformPoint(handlePositions[offsetIndex]), 
						                                                                                                  Quaternion.identity, 
						                                                                                                  handleSizes[offsetIndex], 
						                                                                                                  Vector3.zero, 
						                                                                                                  Handles.CircleCap));

						if(mouseUp)
						{
							if((Vector2)handlePositions[offsetIndex] != joint.bodyB.Shape.getVertex(joint.affectedIndicesB[i]))
							{
								Vector2[] points = new Vector2[joint.bodyB.Shape.VertexCount];
								for(int s = 0; s < joint.bodyB.Shape.VertexCount; s++)
									points[s] = joint.bodyB.Shape.getVertex(s);
								
								int index = JelloShapeTools.FindClosestVertexOnShape(handlePositions[offsetIndex], points);
								bool indexInUse = false;
								
								for(int u = 0; u < joint.affectedIndicesB.Length; u++)
									if(index == joint.affectedIndicesB[u])
										indexInUse = true;
								
								
								if(!indexInUse)
								{
									joint.affectedIndicesB[i] = index;
									
									Vector2[] affectedVertices = new Vector2[joint.affectedIndicesB.Length];
									for(int v = 0; v < affectedVertices.Length; v++)
										affectedVertices[v] = joint.bodyB.Shape.getVertex(joint.affectedIndicesB[v]); 
									
									handlePositions[offsetIndex] = joint.bodyB.Shape.getVertex(index);
									

									joint.RebuildAnchor(joint.localAnchorB, false, true, null, affectedVertices);

									Vector2 newPosition = Vector2.zero;
									for(int v = 0; v < affectedVertices.Length; v++)
										newPosition += affectedVertices[v] * joint.scalarsB[v];
									handlePositions[1] = newPosition;

									EditorUtility.SetDirty(body);

									SceneView.RepaintAll();
								}
								else
								{
									handlePositions[offsetIndex] = joint.bodyB.Shape.getVertex(joint.affectedIndicesB[i]);
								}
							}
						}
						
						Handles.color = Color.grey;
						Handles.DrawLine(joint.bodyB.transform.TransformPoint(handlePositions[1]), joint.bodyB.transform.TransformPoint( handlePositions[offsetIndex]));
					}
				}
				
				Handles.color = Color.yellow;
				Handles.DrawLine(joint.TransformA.TransformPoint(handlePositions[0]), joint.TransformB.TransformPoint(handlePositions[1]));
			}
			else
			{
				//TODO this should be handlepositions[1]???
				EditorGUI.BeginChangeCheck();
				joint.globalAnchorB = Handles.FreeMoveHandle(joint.globalAnchorB, Quaternion.identity, handleSizes[1], Vector3.zero, Handles.CircleCap);
				if(EditorGUI.EndChangeCheck())
				{
					EditorUtility.SetDirty(body);
				}
				Handles.color = Color.yellow;
				Handles.DrawLine(joint.TransformA.TransformPoint(handlePositions[0]), joint.globalAnchorB);
			}
		}
		
		//add new joint logic
		if(newSubComponentState == AddSubComponentState.initiated)
		{
			int controlID = GUIUtility.GetControlID(GetHashCode(), FocusType.Passive);
			
			if(Event.current.type == EventType.Layout)
				HandleUtility.AddDefaultControl(controlID);
			
			pos = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition).origin; //need where this ray intersects the zplane
			Plane plane = new Plane(Vector3.forward, new Vector3(0, 0, body.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, body.transform.position.z);
			
			Handles.color = Color.blue;
			
			Handles.CircleCap(3, mousePosWorld, Quaternion.identity, HandleUtility.GetHandleSize(mousePosWorld) * 0.15f);
			
			if(Event.current.type == EventType.MouseUp)
			{
				body.AddJoint(new JelloJoint(body.transform, null, body.transform.InverseTransformPoint(mousePosWorld), Vector2.zero, true, true));
				newSubComponentState = AddSubComponentState.inactive;
				SetEditIndex(body.JointCount - 1);

				EditorUtility.SetDirty(body);
			}
			
			SceneView.RepaintAll();
		}
	}
예제 #2
0
    /// <summary>
    /// Processes the collision event.
    /// </summary>
    /// <param name="jelloCollision">Jello collision.</param>
    private void ProcessCollisionEvent(JelloCollision jelloCollision)
    {
        if(!stickAtPoints && !stickAtEdges)
            return;

        //loop through each contact and see if a joint exists.
        //if not, create the joint.
        for(int i = 0; i < jelloCollision.contacts.Length; i++)
        {
            JelloContact contact = jelloCollision.contacts[i];

            bool skip = true;
            if(stickAtPoints && body == contact.bodyA)
                skip = false;
            if(stickAtEdges && body == contact.bodyB)
                skip = false;
            if(skip)
                continue;

            bool found = false;

            //see if this joint already exists
            for(int c = joints.Count - 1; c >= 0; c--)
            {
                JelloJoint joint = joints[c];

                //remove joints that have been destroyed
                if(joint.destroyed)
                {
                    joints.Remove(joint);
                    continue;
                }

                //i only want to know if there is a joint between the two bodies and if the point or edge is already taken.
                //should only need to use transform...?
                if(joint.TransformA != contact.transformA && joint.TransformB != contact.transformA)
                    continue;
                if(joint.TransformA != contact.transformB && joint.TransformB != contact.transformB)
                    continue;

                //at this point we know that they share the same transforms.

                //we also know that one of the bodies is the body that this script is attached to.

                if(contact.bodyA != null)
                {
                    if(stickAtPoints && joint.bodyA == contact.bodyA) //this matters if i am alowing point joints
                    {
                        if(joint.affectedIndicesA.Length != 1) //joint bodya has multiple anchors
                        {
                            continue;
                        }
                        else if(joint.affectedIndicesA[0] != contact.bodyApm) //joint bodyA has a single anchor and is not the same
                        {
                            continue;
                        }
                    }

                    //where am i handling rigidbodies or even static bodies??

                    if(stickAtEdges && joint.bodyB != null)
                    {
                        if(joint.bodyB == contact.bodyA)//this matters if i am allowing edge joints
                        {
                            if(joint.affectedIndicesB.Length != 1)
                            {
                                continue;
                            }
                            else if(joint.affectedIndicesB[0] != contact.bodyApm)
                            {
                                continue;
                            }
                        }
                    }
                }

                if(contact.bodyB != null)
                {
                    if(stickAtEdges && joint.bodyA == contact.bodyB)
                    {
                        if(joint.affectedIndicesA.Length != 2)
                        {
                            continue;
                        }
                        else
                        {
                            if(joint.affectedIndicesA[0] != contact.bodyBpmA && joint.affectedIndicesA[0] != contact.bodyBpmB)
                            {
                                continue;
                            }
                            if(joint.affectedIndicesA[1] != contact.bodyBpmA && joint.affectedIndicesA[1] != contact.bodyBpmB)
                            {
                                continue;
                            }
                            if(joint.bodyB != null)
                            {
                                if(joint.affectedIndicesB.Length != 1)
                                {
                                    continue;
                                }
                                else if(joint.affectedIndicesB[0] != contact.bodyApm)
                                {
                                    continue;
                                }
                            }
                        }
                    }

                    if(stickAtPoints && joint.bodyB != null)
                    {
                        if(joint.bodyB == contact.bodyB)
                        {
                            if(joint.affectedIndicesB.Length != 2)
                            {
                                continue;
                            }
                            else
                            {
                                if(joint.affectedIndicesB[0] != contact.bodyBpmA && joint.affectedIndicesB[0] != contact.bodyBpmB)
                                {
                                    continue;
                                }
                                if(joint.affectedIndicesB[1] != contact.bodyBpmA && joint.affectedIndicesB[1] != contact.bodyBpmB)
                                {
                                    continue;
                                }
                                if(joint.bodyA != null)
                                {
                                    if(joint.affectedIndicesA.Length != 1)
                                    {
                                        continue;
                                    }
                                    else if(joint.affectedIndicesA[0] != contact.bodyApm)
                                    {
                                        continue;
                                    }
                                }
                                //else check if ra is the same?
                            }
                        }
                    }
                }

                //must be the same
                found = true;
                break;
            }

            if(!found)//joint Doesn't exist, so create it!
            {
                if(!stickAtPoints && contact.transformA == transform)
                    continue;
                if(!stickAtEdges && contact.transformB == transform)
                    continue;

                JelloJoint joint = new JelloJoint();

                joint.TransformA = contact.transformA;
                joint.localAnchorA = joint.TransformA.InverseTransformPoint(contact.hitPoint);
                if(joint.bodyA != null)
                {
                    int[] indices = new int[1];
                    Vector2[] vertices = new Vector2[1];

                    indices[0] = contact.bodyApm;
                    vertices[0] = contact.bodyA.getPointMass(indices[0]).LocalPosition;
                    joint.RebuildAnchor(contact.transformA.InverseTransformPoint(contact.hitPoint), true, false, indices, vertices);
                }

                joint.TransformB = contact.transformB;
                joint.localAnchorB = joint.TransformB.InverseTransformPoint(contact.hitPoint);
                if(contact.bodyB != null)
                {
                    int[] indices = new int[2];
                    Vector2[] vertices = new Vector2[2];

                    indices[0] = contact.bodyBpmA;
                    indices[1] = contact.bodyBpmB;

                    vertices[0] = contact.bodyB.getPointMass(indices[0]).LocalPosition;
                    vertices[1] = contact.bodyB.getPointMass(indices[1]).LocalPosition;
                    joint.RebuildAnchor(joint.localAnchorB, false, false, indices, vertices);
                }

                joint.breakable = true;
                joint.breakVelocity = breakVelocity;
                body.AddJoint (joint);
                joints.Add(joint);
            }
        }
    }
예제 #3
0
    /// <summary>
    /// Processes the collision event.
    /// </summary>
    /// <param name="jelloCollision">Jello collision.</param>
    private void ProcessCollisionEvent(JelloCollision jelloCollision)
    {
        if (!stickAtPoints && !stickAtEdges)
        {
            return;
        }

        //loop through each contact and see if a joint exists.
        //if not, create the joint.
        for (int i = 0; i < jelloCollision.contacts.Length; i++)
        {
            JelloContact contact = jelloCollision.contacts[i];

            bool skip = true;
            if (stickAtPoints && body == contact.bodyA)
            {
                skip = false;
            }
            if (stickAtEdges && body == contact.bodyB)
            {
                skip = false;
            }
            if (skip)
            {
                continue;
            }

            bool found = false;

            //see if this joint already exists
            for (int c = joints.Count - 1; c >= 0; c--)
            {
                JelloJoint joint = joints[c];

                //remove joints that have been destroyed
                if (joint.destroyed)
                {
                    joints.Remove(joint);
                    continue;
                }

                //i only want to know if there is a joint between the two bodies and if the point or edge is already taken.
                //should only need to use transform...?
                if (joint.TransformA != contact.transformA && joint.TransformB != contact.transformA)
                {
                    continue;
                }
                if (joint.TransformA != contact.transformB && joint.TransformB != contact.transformB)
                {
                    continue;
                }

                //at this point we know that they share the same transforms.

                //we also know that one of the bodies is the body that this script is attached to.


                if (contact.bodyA != null)
                {
                    if (stickAtPoints && joint.bodyA == contact.bodyA)                 //this matters if i am alowing point joints
                    {
                        if (joint.affectedIndicesA.Length != 1)                        //joint bodya has multiple anchors
                        {
                            continue;
                        }
                        else if (joint.affectedIndicesA[0] != contact.bodyApm)                        //joint bodyA has a single anchor and is not the same
                        {
                            continue;
                        }
                    }

                    //where am i handling rigidbodies or even static bodies??

                    if (stickAtEdges && joint.bodyB != null)
                    {
                        if (joint.bodyB == contact.bodyA)                       //this matters if i am allowing edge joints
                        {
                            if (joint.affectedIndicesB.Length != 1)
                            {
                                continue;
                            }
                            else if (joint.affectedIndicesB[0] != contact.bodyApm)
                            {
                                continue;
                            }
                        }
                    }
                }

                if (contact.bodyB != null)
                {
                    if (stickAtEdges && joint.bodyA == contact.bodyB)
                    {
                        if (joint.affectedIndicesA.Length != 2)
                        {
                            continue;
                        }
                        else
                        {
                            if (joint.affectedIndicesA[0] != contact.bodyBpmA && joint.affectedIndicesA[0] != contact.bodyBpmB)
                            {
                                continue;
                            }
                            if (joint.affectedIndicesA[1] != contact.bodyBpmA && joint.affectedIndicesA[1] != contact.bodyBpmB)
                            {
                                continue;
                            }
                            if (joint.bodyB != null)
                            {
                                if (joint.affectedIndicesB.Length != 1)
                                {
                                    continue;
                                }
                                else if (joint.affectedIndicesB[0] != contact.bodyApm)
                                {
                                    continue;
                                }
                            }
                        }
                    }


                    if (stickAtPoints && joint.bodyB != null)
                    {
                        if (joint.bodyB == contact.bodyB)
                        {
                            if (joint.affectedIndicesB.Length != 2)
                            {
                                continue;
                            }
                            else
                            {
                                if (joint.affectedIndicesB[0] != contact.bodyBpmA && joint.affectedIndicesB[0] != contact.bodyBpmB)
                                {
                                    continue;
                                }
                                if (joint.affectedIndicesB[1] != contact.bodyBpmA && joint.affectedIndicesB[1] != contact.bodyBpmB)
                                {
                                    continue;
                                }
                                if (joint.bodyA != null)
                                {
                                    if (joint.affectedIndicesA.Length != 1)
                                    {
                                        continue;
                                    }
                                    else if (joint.affectedIndicesA[0] != contact.bodyApm)
                                    {
                                        continue;
                                    }
                                }
                                //else check if ra is the same?
                            }
                        }
                    }
                }


                //must be the same
                found = true;
                break;
            }

            if (!found)           //joint Doesn't exist, so create it!
            {
                if (!stickAtPoints && contact.transformA == transform)
                {
                    continue;
                }
                if (!stickAtEdges && contact.transformB == transform)
                {
                    continue;
                }

                JelloJoint joint = new JelloJoint();

                joint.TransformA   = contact.transformA;
                joint.localAnchorA = joint.TransformA.InverseTransformPoint(contact.hitPoint);
                if (joint.bodyA != null)
                {
                    int[]     indices  = new int[1];
                    Vector2[] vertices = new Vector2[1];

                    indices[0]  = contact.bodyApm;
                    vertices[0] = contact.bodyA.getPointMass(indices[0]).LocalPosition;
                    joint.RebuildAnchor(contact.transformA.InverseTransformPoint(contact.hitPoint), true, false, indices, vertices);
                }

                joint.TransformB   = contact.transformB;
                joint.localAnchorB = joint.TransformB.InverseTransformPoint(contact.hitPoint);
                if (contact.bodyB != null)
                {
                    int[]     indices  = new int[2];
                    Vector2[] vertices = new Vector2[2];

                    indices[0] = contact.bodyBpmA;
                    indices[1] = contact.bodyBpmB;

                    vertices[0] = contact.bodyB.getPointMass(indices[0]).LocalPosition;
                    vertices[1] = contact.bodyB.getPointMass(indices[1]).LocalPosition;
                    joint.RebuildAnchor(joint.localAnchorB, false, false, indices, vertices);
                }

                joint.breakable     = true;
                joint.breakVelocity = breakVelocity;
                body.AddJoint(joint);
                joints.Add(joint);
            }
        }
    }