예제 #1
0
    public override void DrawSceneGUI()
    {
        MegaFFD ffd = (MegaFFD)target;

        bool snapshot = false;

        if (ffd.DisplayGizmo)
        {
            MegaModifiers context = ffd.GetComponent <MegaModifiers>();

            if (context && context.DrawGizmos)
            {
                Vector3 size  = ffd.lsize;
                Vector3 osize = ffd.lsize;
                osize.x = 1.0f / size.x;
                osize.y = 1.0f / size.y;
                osize.z = 1.0f / size.z;

                Matrix4x4  tm1 = Matrix4x4.identity;
                Quaternion rot = Quaternion.Euler(ffd.gizmoRot);
                tm1.SetTRS(-(ffd.gizmoPos + ffd.Offset), rot, Vector3.one);

                Matrix4x4 tm = Matrix4x4.identity;
                Handles.matrix = Matrix4x4.identity;

                if (context != null && context.sourceObj != null)
                {
                    tm = context.sourceObj.transform.localToWorldMatrix * tm1;
                }
                else
                {
                    tm = ffd.transform.localToWorldMatrix * tm1;
                }

                DrawGizmos(ffd, tm);                    //Handles.matrix);

                Handles.color = Color.yellow;
        #if false
                int pc = ffd.GridSize();
                pc = pc * pc * pc;
                for (int i = 0; i < pc; i++)
                {
                    Vector3 p = ffd.GetPoint(i);                        // + ffd.bcenter;

                    //pm = Handles.PositionHandle(p, Quaternion.identity);
                    pm = Handles.FreeMoveHandle(p, Quaternion.identity, ffd.KnotSize * 0.1f, Vector3.zero, Handles.CircleCap);

                    pm  -= ffd.bcenter;
                    p    = Vector3.Scale(pm, osize);
                    p.x += 0.5f;
                    p.y += 0.5f;
                    p.z += 0.5f;

                    ffd.pt[i] = p;
                }
        #endif
                int gs = ffd.GridSize();
                //int i = 0;

                Vector3 ttp = Vector3.zero;

                for (int z = 0; z < gs; z++)
                {
                    for (int y = 0; y < gs; y++)
                    {
                        for (int x = 0; x < gs; x++)
                        {
                            int index = ffd.GridIndex(x, y, z);
                            //Vector3 p = ffd.GetPoint(i);	// + ffd.bcenter;
                            Vector3 lp = ffd.GetPoint(index);
                            Vector3 p  = lp;                            //tm.MultiplyPoint(lp);	//ffdi);	// + ffd.bcenter;

                            Vector3 tp = tm.MultiplyPoint(p);
                            if (handles)
                            {
                                ttp = Handles.PositionHandle(tp, Quaternion.identity);

                                //pm = tm.inverse.MultiplyPoint(Handles.PositionHandle(tm.MultiplyPoint(p), Quaternion.identity));
                                //pm = PositionHandle(p, Quaternion.identity, handleSize, ffd.gizCol1.a);
                            }
                            else
                            {
                                ttp = Handles.FreeMoveHandle(tp, Quaternion.identity, ffd.KnotSize * 0.1f, Vector3.zero, Handles.CircleCap);
                            }

                            if (ttp != tp)
                            {
                                if (!snapshot)
                                {
                                    MegaUndo.SetSnapshotTarget(ffd, "FFD Lattice Move");
                                    snapshot = true;
                                }
                            }

                            pm = tm.inverse.MultiplyPoint(ttp);
                            Vector3 delta = pm - p;

                            //pm = lp + delta;

                            //ffd.SetPoint(x, y, z, pm);
                            pm  -= ffd.bcenter;
                            p    = Vector3.Scale(pm, osize);
                            p.x += 0.5f;
                            p.y += 0.5f;
                            p.z += 0.5f;

                            ffd.pt[index] = p;

                            if (mirrorX)
                            {
                                int y1 = y - (gs - 1);
                                if (y1 < 0)
                                {
                                    y1 = -y1;
                                }

                                if (y != y1)
                                {
                                    Vector3 p1 = ffd.GetPoint(ffd.GridIndex(x, y1, z));                                         // + ffd.bcenter;

                                    delta.y = -delta.y;
                                    p1     += delta;
                                    p1     -= ffd.bcenter;
                                    p       = Vector3.Scale(p1, osize);
                                    p.x    += 0.5f;
                                    p.y    += 0.5f;
                                    p.z    += 0.5f;

                                    ffd.pt[ffd.GridIndex(x, y1, z)] = p;
                                }
                            }

                            if (mirrorY)
                            {
                                int z1 = z - (gs - 1);
                                if (z1 < 0)
                                {
                                    z1 = -z1;
                                }

                                if (z != z1)
                                {
                                    Vector3 p1 = ffd.GetPoint(ffd.GridIndex(x, y, z1));                                         // + ffd.bcenter;

                                    delta.z = -delta.z;
                                    p1     += delta;
                                    p1     -= ffd.bcenter;
                                    p       = Vector3.Scale(p1, osize);
                                    p.x    += 0.5f;
                                    p.y    += 0.5f;
                                    p.z    += 0.5f;

                                    ffd.pt[ffd.GridIndex(x, y, z1)] = p;
                                }
                            }

                            if (mirrorZ)
                            {
                                int x1 = x - (gs - 1);
                                if (x1 < 0)
                                {
                                    x1 = -x1;
                                }

                                if (x != x1)
                                {
                                    Vector3 p1 = ffd.GetPoint(ffd.GridIndex(x1, y, z));                                         // + ffd.bcenter;

                                    delta.x = -delta.x;
                                    p1     += delta;
                                    p1     -= ffd.bcenter;
                                    p       = Vector3.Scale(p1, osize);
                                    p.x    += 0.5f;
                                    p.y    += 0.5f;
                                    p.z    += 0.5f;

                                    ffd.pt[ffd.GridIndex(x1, y, z)] = p;
                                }
                            }
                        }
                    }
                }

                Handles.matrix = Matrix4x4.identity;

                if (GUI.changed && snapshot)
                {
                    MegaUndo.CreateSnapshot();
                    MegaUndo.RegisterSnapshot();
                }

                MegaUndo.ClearSnapshotTarget();
            }
        }
    }
예제 #2
0
	public void OnSceneGUI()
	{
		MegaShape shape = (MegaShape)target;

		bool mouseup = false;
		bool recalc = false;

		if ( Event.current.type == EventType.KeyDown )
		{
			if ( Event.current.keyCode == KeyCode.LeftAlt || Event.current.keyCode == KeyCode.RightAlt )
			{
				editmode = false;
			}
		}

		if ( Event.current.type == EventType.KeyUp )
		{
			if ( Event.current.keyCode == KeyCode.LeftAlt || Event.current.keyCode == KeyCode.RightAlt )
			{
				editmode = true;
			}
		}

		if ( !editmode )
		{
			return;
		}

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

			if ( addingknot )
			{
				addingknot = false;
				MegaKnot knot = new MegaKnot();

				knot.p = addpos;
				knot.id = shape.splines[snum].knots[knum].id;
				knot.twist = shape.splines[snum].knots[knum].twist;

				shape.splines[snum].knots.Insert(knum + 1, knot);

				if ( shape.smoothonaddknot )
					shape.AutoCurve(shape.splines[snum]);	//, knum, knum + 2);
				shape.CalcLength();	//10);
				EditorUtility.SetDirty(target);
				if ( shape.makeMesh )
				{
					shape.SetMats();
					shape.BuildMesh();
				}
			}
		}

		Handles.matrix = shape.transform.localToWorldMatrix;

		if ( shape.selcurve > shape.splines.Count - 1 )
			shape.selcurve = 0;

		Vector3 dragplane = Vector3.one;

		Color nocol = new Color(0, 0, 0, 0);

		bounds.size = Vector3.zero;

		Color twistcol = new Color(0.5f, 0.5f, 1.0f, 0.25f);

		for ( int s = 0; s < shape.splines.Count; s++ )
		{
			for ( int p = 0; p < shape.splines[s].knots.Count; p++ )
			{
				if ( s == shape.selcurve )
				{
					bounds.Encapsulate(shape.splines[s].knots[p].p);
				}

				if ( shape.drawKnots && s == shape.selcurve )
				{
					pm = shape.splines[s].knots[p].p;

					if ( showlabels )
					{
						if ( p == selected && s == shape.selcurve )
						{
							Handles.color = Color.white;
							Handles.Label(pm, " Selected\n" + pm.ToString("0.000"));
						}
						else
						{
							Handles.color = shape.KnotCol;
							Handles.Label(pm, " " + p);
						}
					}

					Handles.color = nocol;
					Vector3 newp = Vector3.zero;
					
					if ( shape.usesnap )
						newp = PosHandlesSnap(shape, pm, Quaternion.identity);
					else
						newp = PosHandles(shape, pm, Quaternion.identity);

					if ( newp != pm )
					{
						MegaUndo.SetSnapshotTarget(shape, "Knot Move");
					}

					Vector3 dl = Vector3.Scale(newp - pm, dragplane);

					shape.splines[s].knots[p].p += dl;	//Vector3.Scale(newp - pm, dragplane);

					shape.splines[s].knots[p].invec += dl;	//delta;
					shape.splines[s].knots[p].outvec += dl;	//delta;

					if ( newp != pm )
					{
						selected = p;
						recalc = true;
					}
				}

				if ( shape.drawHandles && s == shape.selcurve )
				{
					Handles.color = shape.VecCol;
					pm = shape.splines[s].knots[p].p;

					Vector3 ip = shape.splines[s].knots[p].invec;
					Vector3 op = shape.splines[s].knots[p].outvec;
					Handles.DrawLine(pm, ip);
					Handles.DrawLine(pm, op);

					Handles.color = shape.HandleCol;

					Vector3 invec = shape.splines[s].knots[p].invec;
					Handles.color = nocol;
					Vector3 newinvec = Vector3.zero;
					
					if ( shape.usesnaphandles )
						newinvec = PosHandlesSnap(shape, invec, Quaternion.identity);
					else
						newinvec = PosHandles(shape, invec, Quaternion.identity);

					if ( newinvec != invec )	//shape.splines[s].knots[p].invec )
					{
						MegaUndo.SetSnapshotTarget(shape, "Handle Move");
					}
					Vector3 dl = Vector3.Scale(newinvec - invec, dragplane);
					shape.splines[s].knots[p].invec += dl;	//Vector3.Scale(newinvec - invec, dragplane);
					if ( invec != newinvec )	//shape.splines[s].knots[p].invec )
					{
						if ( shape.lockhandles )
						{
							shape.splines[s].knots[p].outvec -= dl;
						}

						selected = p;
						recalc = true;
					}
					Vector3 outvec = shape.splines[s].knots[p].outvec;

					Vector3 newoutvec = Vector3.zero;
					if ( shape.usesnaphandles )
						newoutvec = PosHandlesSnap(shape, outvec, Quaternion.identity);
					else
						newoutvec = PosHandles(shape, outvec, Quaternion.identity);

					if ( newoutvec != outvec )	//shape.splines[s].knots[p].outvec )
					{
						MegaUndo.SetSnapshotTarget(shape, "Handle Move");
					}
					dl = Vector3.Scale(newoutvec - outvec, dragplane);
					shape.splines[s].knots[p].outvec += dl;
					if ( outvec != newoutvec )	//shape.splines[s].knots[p].outvec )
					{
						if ( shape.lockhandles )
						{
							shape.splines[s].knots[p].invec -= dl;
						}

						selected = p;
						recalc = true;
					}
					Vector3 hp = shape.splines[s].knots[p].invec;
					if ( selected == p )
						Handles.Label(hp, " " + p);

					hp = shape.splines[s].knots[p].outvec;

					if ( selected == p )
						Handles.Label(hp, " " + p);
				}

				// TODO: Draw a wedge to show the twist angle
				// Twist handles
				if ( shape.drawTwist && s == shape.selcurve )
				{
					Vector3 np = Vector3.zero;

					if ( p == 0 || p < shape.splines[s].knots.Count - 2 )
					{
						np = shape.splines[s].knots[p].Interpolate(0.002f, shape.splines[s].knots[p + 1]);
						np = np - shape.splines[s].knots[p].p;
						//np = shape.splines[s].knots[p].outvec;	//(0.0f, shape.splines[s].knots[p + 1]);

						//Debug.Log("np " + np);
					}
					else
					{
						if ( shape.splines[s].closed )
						{
							np = shape.splines[s].knots[p].Interpolate(0.002f, shape.splines[s].knots[0]);
							np = np - shape.splines[s].knots[p].p;
							//np = shape.splines[s].knots[p].outvec;	//Tangent(0.0f, shape.splines[s].knots[0]);
							//Debug.Log("np " + np);
						}
						else
						{
							np = shape.splines[s].knots[p - 1].Interpolate(0.998f, shape.splines[s].knots[p]);
							np = shape.splines[s].knots[p].p - np;
							//np = shape.splines[s].knots[p - 1].outvec;	//Tangent(0.9999f, shape.splines[s].knots[p]);
							//Debug.Log("np " + np);
						}
					}

					if ( np == Vector3.zero )
						np = Vector3.forward;

					np = np.normalized;
					// np holds the tangent so we can align the arc
					Quaternion fwd = Quaternion.LookRotation(np);

					Vector3 rg = Vector3.Cross(np, Vector3.up);
					//Vector3 up = Vector3.Cross(np, rg);

					Handles.color = twistcol;
					float twist = shape.splines[s].knots[p].twist;

					Handles.DrawSolidArc(shape.splines[s].knots[p].p, np, rg, twist, shape.KnotSize * 0.1f);

					Vector3 tang = new Vector3(0.0f, 0.0f, shape.splines[s].knots[p].twist);
					Quaternion inrot = fwd * Quaternion.Euler(tang);
					//Quaternion rot = Handles.RotationHandle(inrot, shape.splines[s].knots[p].p);
					Handles.color = Color.white;
					Quaternion rot = Handles.Disc(inrot, shape.splines[s].knots[p].p, np, shape.KnotSize * 0.1f, false, 0.0f);
					
					if ( rot != inrot )
					{
						tang = rot.eulerAngles;
						float diff = (tang.z - shape.splines[s].knots[p].twist);
						if ( Mathf.Abs(diff) > 0.0001f  )
						{
							while ( diff > 180.0f )
								diff -= 360.0f;

							while ( diff < -180.0f )
								diff += 360.0f;

							shape.splines[s].knots[p].twist += diff;
							recalc = true;
						}
					}
				}

				// Midpoint add knot code
				if ( s == shape.selcurve )
				{
					if ( p < shape.splines[s].knots.Count - 1 )
					{
						Handles.color = Color.white;

						Vector3 mp = shape.splines[s].knots[p].InterpolateCS(0.5f, shape.splines[s].knots[p + 1]);

						Vector3 mp1 = Handles.FreeMoveHandle(mp, Quaternion.identity, shape.KnotSize * 0.01f, Vector3.zero, Handles.CircleCap);
						if ( mp1 != mp )
						{
							if ( !addingknot )
							{
								addingknot = true;
								addpos = mp;
								knum = p;
								snum = s;
							}
						}
					}
				}
			}
		}

		// Draw nearest point (use for adding knot)
		Vector3 wcp = CursorPos;
		Vector3 newCursorPos = PosHandles(shape, wcp, Quaternion.identity);
		
		if ( newCursorPos != wcp )
		{
			Vector3 cd = newCursorPos - wcp;

			CursorPos += cd;

			float calpha = 0.0f;
			CursorPos = shape.FindNearestPoint(CursorPos, 5, ref CursorKnot, ref CursorTangent, ref calpha);
			shape.CursorPercent = calpha * 100.0f;
		}

		Handles.Label(CursorPos, "Cursor " + shape.CursorPercent.ToString("0.00") + "% - " + CursorPos);

		// Move whole spline handle
		if ( shape.showorigin )
		{
			Handles.Label(bounds.min, "Origin");
			Vector3 spos = Handles.PositionHandle(bounds.min, Quaternion.identity);
			if ( spos != bounds.min )
			{
				if ( shape.usesnap )
				{
					if ( shape.snap.x != 0.0f )
						spos.x = (int)(spos.x / shape.snap.x) * shape.snap.x;

					if ( shape.snap.y != 0.0f )
						spos.y = (int)(spos.y / shape.snap.y) * shape.snap.y;

					if ( shape.snap.z != 0.0f )
						spos.z = (int)(spos.z / shape.snap.z) * shape.snap.z;
				}

				// Move the spline
				shape.MoveSpline(spos - bounds.min, shape.selcurve, false);
				recalc = true;
			}
		}

		if ( recalc )
		{
			shape.CalcLength();	//10);

			if ( shape.updateondrag || (!shape.updateondrag && mouseup) )
			{
				shape.BuildMesh();

				//MegaLoftLayerSimple[] layers = (MegaLoftLayerSimple[])FindObjectsOfType(typeof(MegaLoftLayerSimple));

				//for ( int i = 0; i < layers.Length; i++ )
				//{
					//layers[i].Notify(shape.splines[shape.selcurve], 0);
				//}

				EditorUtility.SetDirty(shape);
			}
		}

		Handles.matrix = Matrix4x4.identity;
		//undoManager.CheckDirty(target);

		// This is wrong gui not changing here
		if ( GUI.changed )
		{
			MegaUndo.CreateSnapshot();
			MegaUndo.RegisterSnapshot();
		}

		MegaUndo.ClearSnapshotTarget();
	}