public override void SetEditIndex(int index)
	{
		JelloJoint joint = body.GetJoint(index);
		editIndex = index;
		int numA = joint.affectedIndicesA.Length;
		handlePositions[0] = handlePositions[1] = Vector2.zero;

		for(int i = 0; i < numA; i++)
		{
			handlePositions[i + 2] = body.Shape.getVertex(joint.affectedIndicesA[i]);
			handlePositions[0] += handlePositions[i + 2] * joint.scalarsA[i];
		}
		
		if(joint.TransformB != null)
		{
			if(joint.bodyB != null)
			{
				for(int i = 0; i < joint.affectedIndicesB.Length; i++)
				{
					handlePositions[numA + i + 2] = joint.bodyB.Shape.getVertex(joint.affectedIndicesB[i]);
					handlePositions[1] += handlePositions[numA + i + 2] * joint.scalarsB[i];
				}
			}
			else
			{
				handlePositions[1] = joint.localAnchorB;
			}
		}
	}
Esempio n. 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);
            }
        }
    }
Esempio n. 3
0
    //TODO make alternative method sigantures.
    /// <summary>
    /// Add a JelloJoint to this JelloBody.
    /// </summary>
    /// <param name="joint">The JelloJoint to add.</param>
    public void AddJoint(JelloJoint joint)
    {
        if(mJoints == null)
            mJoints = new JelloJoint[0];

        for(int i = 0; i < mJoints.Length; i++)
        {
            if(mJoints[i] == joint)
                return;
        }

        bool rigidB = joint.bodyB == null && joint.rigidbodyB != null;
        bool rigidA = joint.bodyA == null && joint.rigidbodyA != null;
        //only check for similar if a rigidbody
        if(rigidB || rigidA)
        {
            bool similar = false;
            //add similar to a list?
            List<JelloJoint> similarJoints = new List<JelloJoint>();

            for(int i = 0; i < mJoints.Length; i++)
            {
                similar = false;
                if(rigidB)
                {
                    if(joint.TransformB == mJoints[i].TransformB)
                    {
                        similar = true;
                    }
                    else if(joint.TransformB == mJoints[i].TransformA)
                    {
                        similar = true;
                    }
                }
                else if(rigidA)
                {
                    if(joint.TransformA == mJoints[i].TransformA)
                    {
                        similar = true;
                    }
                    else if(joint.TransformA == mJoints[i].TransformB)
                    {
                        similar = true;
                    }
                }

                if(similar)
                    similarJoints.Add (mJoints[i]);
            }

            for(int i = 0; i < similarJoints.Count; i++)
            {
                similarJoints[i].numSimilar = similarJoints.Count + 1;
            }

            joint.numSimilar = similarJoints.Count + 1;
        }

        JelloJoint[] oldJoints = mJoints;
        mJoints = new JelloJoint[mJoints.Length + 1];
        for(int i =0; i < oldJoints.Length; i++)
        {
            mJoints[i] = oldJoints[i];
        }
        mJoints[mJoints.Length - 1] = joint;

        if(Application.isPlaying)
            World.addJoint(joint);
    }
Esempio n. 4
0
    /// <summary>
    /// Remove a JelloJoint from this JelloBody.
    /// </summary>
    /// <param name="joint">The JelloJoint to remove.</param>
    public void RemoveJoint(JelloJoint joint)
    {
        bool contains = false;

        List<JelloJoint> tempJoints = new List<JelloJoint>();
        for(int i = 0; i < mJoints.Length; i++)
        {
            if(joint != mJoints[i])
            {
                tempJoints.Add (mJoints[i]);
            }
            else
            {
                //do something
                contains = true;
            }
        }

        if(!contains)
            return;

        mJoints = tempJoints.ToArray();

        bool rigidB = joint.bodyB == null && joint.rigidbodyB != null;
        bool rigidA = joint.bodyA == null && joint.rigidbodyA != null;
        //only check for similar if a rigidbody
        if(rigidB || rigidA)
        {
            bool similar = false;
            //add similar to a list?
            List<JelloJoint> similarJoints = new List<JelloJoint>();

            for(int i = 0; i < mJoints.Length; i++)
            {
                similar = false;

                if(rigidB)
                {
                    if(joint.TransformB == mJoints[i].TransformB)
                    {
                        similar = true;
                    }
                    else if(joint.TransformB == mJoints[i].TransformA)
                    {
                        similar = true;
                    }
                }
                else if(rigidA)
                {
                    if(joint.TransformA == mJoints[i].TransformA)
                    {
                        similar = true;
                    }
                    else if(joint.TransformA == mJoints[i].TransformB)
                    {
                        similar = true;
                    }
                }

                if(similar)
                    similarJoints.Add (mJoints[i]);
            }

            for(int i = 0; i < similarJoints.Count; i++)
            {
                similarJoints[i].numSimilar = similarJoints.Count;
            }

            joint.numSimilar = similarJoints.Count;
        }

        if(Application.isPlaying && !applicationIsQuitting)
            World.removeJoint(joint);
    }
	//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();
		}
	}
	public virtual void DrawEditJointGUI() //TODO have some sort of snap all? and/or refresh all?
	{
		SerializedProperty eJoint = eJoints.GetArrayElementAtIndex(editIndex);
		SerializedProperty eBreakable = eJoint.FindPropertyRelative("breakable");
		SerializedProperty eVelocity = eJoint.FindPropertyRelative("breakVelocity");
		SerializedProperty eTransformB = eJoint.FindPropertyRelative("mTransformB");
		SerializedProperty eGlobalAnchorB = eJoint.FindPropertyRelative("globalAnchorB");
		SerializedProperty eLocalAnchorA = eJoint.FindPropertyRelative("localAnchorA");
		SerializedProperty eIndicesA = eJoint.FindPropertyRelative("affectedIndicesA");
		SerializedProperty eScalarsA = eJoint.FindPropertyRelative("scalarsA");
		SerializedProperty eLocalAnchorB = eJoint.FindPropertyRelative("localAnchorB");
		SerializedProperty eIndicesB = eJoint.FindPropertyRelative("affectedIndicesB");
		SerializedProperty eScalarsB = eJoint.FindPropertyRelative("scalarsB");


		JelloJoint joint = body.GetJoint(editIndex);

		EditorGUILayout.PropertyField(eBreakable, breakableContent);
		if(eBreakable.boolValue)
		{
			EditorGUI.indentLevel++;
			EditorGUILayout.PropertyField(eVelocity, jointBreakVelocityContent);
			EditorGUI.indentLevel--;
		}

		//TODO make anchor point bold

		GUIStyle anchorAStyle = new GUIStyle(EditorStyles.label);
		if(eIndicesA.prefabOverride || eScalarsA.prefabOverride || eLocalAnchorA.prefabOverride)
			anchorAStyle.fontStyle = FontStyle.Bold;

		EditorGUILayout.BeginHorizontal();
		EditorGUILayout.LabelField("Anchor Point", anchorAStyle); //TODO have toggle to always snap??? how would this work with multiple objects?
		if(GUILayout.Button(snapJointContent))
		{
			if(eTransformB.objectReferenceValue != null)
			{
				joint.TransformB.position -= joint.TransformB.TransformPoint(handlePositions[1]) - joint.TransformA.TransformPoint(handlePositions[0]); 	
			}
			else
			{
				eGlobalAnchorB.vector2Value = body.transform.TransformPoint(joint.GetAnchorPointA(true));
				SceneView.RepaintAll();
			}

			//EditorUtility.SetDirty(body);			//?
		}
		EditorGUILayout.EndHorizontal();

		GUIStyle localStyleA = new GUIStyle(EditorStyles.label);
		if(eIndicesA.prefabOverride || eScalarsA.prefabOverride || eLocalAnchorA.prefabOverride)
			localStyleA.fontStyle = FontStyle.Bold;

		EditorGUI.indentLevel++;
		EditorGUILayout.LabelField("Local Position", handlePositions[0].ToString(), localStyleA);
		string text = "";
		for(int i = 0; i < joint.affectedIndicesA.Length; i++)
			text += joint.affectedIndicesA[i].ToString() + ", ";

		GUIStyle indicesStyleA = new GUIStyle(EditorStyles.label);
		if(eIndicesA.prefabOverride)
		   indicesStyleA.fontStyle = FontStyle.Bold;

		GUIContent anchorIndicesContent = new GUIContent("Anchored Indices");
		EditorGUILayout.LabelField(anchorIndicesContent, indicesStyleA);
	
		EditorGUI.indentLevel++;
		EditorGUILayout.BeginHorizontal();

		EditorGUILayout.LabelField(text, indicesStyleA);
		if(GUILayout.Button(removeJointLegContent) && joint.affectedIndicesA.Length > 1)
		{
			joint.SetupAnchor(body.transform, joint.GetAnchorPointA(true), true, true, joint.affectedIndicesA.Length - 1);
			SetEditIndex(editIndex);

			EditorUtility.SetDirty(body);

			SceneView.RepaintAll();
		}
		if(GUILayout.Button(addJointLegContent) && joint.affectedIndicesA.Length < 3)
		{
			joint.SetupAnchor(body.transform, joint.GetAnchorPointA(true), true, true, joint.affectedIndicesA.Length + 1);
			SetEditIndex(editIndex);

			EditorUtility.SetDirty(body);

			SceneView.RepaintAll();
		}
		
		EditorGUILayout.EndHorizontal();
		EditorGUI.indentLevel--;
		EditorGUI.indentLevel--;

		GUIStyle xformStyleB = new GUIStyle(EditorStyles.label);
		if(eTransformB.prefabOverride)
			xformStyleB.fontStyle = FontStyle.Bold;


		EditorGUILayout.LabelField("Connected Transform", xformStyleB);

		EditorGUI.indentLevel++;
		EditorGUI.BeginChangeCheck();
		EditorGUILayout.PropertyField(eTransformB, new GUIContent());
		if(EditorGUI.EndChangeCheck())
		{
			Vector2 point = Vector2.zero;
			Transform xformB = (Transform)eTransformB.objectReferenceValue;
			if(xformB.collider2D != null)
			{
				Vector2 anchorPositionA = body.transform.TransformPoint(handlePositions[0]);
				if(xformB.collider2D.OverlapPoint(anchorPositionA))
					point = xformB.InverseTransformPoint(anchorPositionA);
			}

			joint.SetupAnchor((Transform)eTransformB.objectReferenceValue, point, false, true);
			
			SetEditIndex(editIndex);

			EditorUtility.SetDirty(body);
			mainEditor.serializedObject.UpdateIfDirtyOrScript();

			SceneView.RepaintAll();
		}
		EditorGUI.indentLevel--;
		EditorGUILayout.BeginHorizontal();

		GUIStyle anchorStyleB = new GUIStyle(EditorStyles.label);
		if(eTransformB.prefabOverride || eIndicesB.prefabOverride || eScalarsB.prefabOverride || eLocalAnchorB.prefabOverride || eGlobalAnchorB.prefabOverride)
			anchorStyleB.fontStyle = FontStyle.Bold;

		EditorGUILayout.LabelField("Anchor Point", anchorStyleB);
		
		if(GUILayout.Button(snapJointContent))
		{
			if(eTransformB.objectReferenceValue != null)
			{
				joint.TransformA.position -= joint.TransformA.TransformPoint(handlePositions[0]) - joint.TransformB.TransformPoint(handlePositions[1]); 	
			}
			else
			{
				joint.TransformA.position -= joint.TransformA.TransformPoint(handlePositions[0]) - (Vector3)joint.globalAnchorB;
			}

			EditorUtility.SetDirty(body);
		}
		EditorGUILayout.EndHorizontal();
		
		EditorGUI.indentLevel++;
		if(eTransformB.objectReferenceValue != null)
		{
			GUIStyle positionStyleB = new GUIStyle(EditorStyles.label);
			if(eIndicesB.prefabOverride || eScalarsB.prefabOverride || eLocalAnchorB.prefabOverride)
				positionStyleB.fontStyle = FontStyle.Bold;

			EditorGUILayout.LabelField("Local Position", handlePositions[1].ToString(), positionStyleB);

			if(joint.bodyB != null)
			{	
				text = "";
				for(int i = 0; i < joint.affectedIndicesB.Length; i++)
					text += joint.affectedIndicesB[i].ToString() + ", ";

				GUIStyle indicesStyleB = new GUIStyle(EditorStyles.label);
				if(eIndicesB.prefabOverride)
					indicesStyleB.fontStyle = FontStyle.Bold;

				EditorGUILayout.LabelField("Anchored Indices", indicesStyleB);

				EditorGUI.indentLevel++;
				EditorGUILayout.BeginHorizontal();

				EditorGUILayout.LabelField(text, indicesStyleB);
				
				if(GUILayout.Button(removeJointLegContent) && joint.affectedIndicesB.Length > 1)
				{
					joint.SetupAnchor(joint.TransformB, joint.GetAnchorPointB(true), false, true, joint.affectedIndicesB.Length - 1);
					SetEditIndex(editIndex);

					EditorUtility.SetDirty(body);

					SceneView.RepaintAll();
				}
				if(GUILayout.Button(addJointLegContent) && joint.affectedIndicesA.Length < 3)
				{
					joint.SetupAnchor(joint.TransformB, joint.GetAnchorPointB(true), false, true, joint.affectedIndicesB.Length + 1);
					SetEditIndex(editIndex);

					EditorUtility.SetDirty(body);

					SceneView.RepaintAll();
				}
				
				EditorGUILayout.EndHorizontal();
				EditorGUI.indentLevel--;
			}
			EditorGUI.indentLevel--;
		}
		else
		{
			EditorGUILayout.PropertyField(eGlobalAnchorB, jointAnchorBcontent);
		}
		EditorGUI.indentLevel--;
	}
Esempio n. 7
0
    /// <summary>
    /// Add a JelloJoint to the JelloWorld.
    /// </summary>
    /// <param name="joint">The JelloJoint to be added.</param>
    public void addJoint(JelloJoint joint)
    {
        //exit if this body is already here
        if (mJoints.Contains(joint))
            return;

        mJoints.Add(joint);
    }
Esempio n. 8
0
 /// <summary>
 /// Remove the JelloJoint from the JelloWorld.
 /// </summary>
 /// <param name="joint">The JelloJoint to remove.</param>
 public void removeJoint(JelloJoint joint)
 {
     if (mJoints.Contains(joint))
     {
         mJoints.Remove(joint);
         if(joint.bodyA != null)
             joint.bodyA.RemoveJoint(joint);
         if(joint.bodyB != null)
             joint.bodyB.RemoveJoint(joint);
     }
 }
Esempio n. 9
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);
            }
        }
    }