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(); } } }
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(); }