static public MegaSpline Copy(MegaSpline src) { MegaSpline spl = new MegaSpline(); spl.closed = src.closed; spl.offset = src.offset; spl.rotate = src.rotate; spl.scale = src.scale; spl.length = src.length; spl.knots = new List <MegaKnot>(); //src.knots); for (int i = 0; i < src.knots.Count; i++) { MegaKnot knot = new MegaKnot(); knot.p = src.knots[i].p; knot.invec = src.knots[i].invec; knot.outvec = src.knots[i].outvec; knot.seglength = src.knots[i].seglength; knot.length = src.knots[i].length; knot.notlocked = src.knots[i].notlocked; spl.knots.Add(knot); } spl.animations = new List <MegaKnotAnim>(src.animations); return(spl); }
public void AddKnot(Vector3 p, Vector3 invec, Vector3 outvec) { MegaKnot knot = new MegaKnot(); knot.p = p; knot.invec = invec; knot.outvec = outvec; knots.Add(knot); }
public void AddKnot(Vector3 p, Vector3 invec, Vector3 outvec, Matrix4x4 tm) { MegaKnot knot = new MegaKnot(); knot.p = tm.MultiplyPoint3x4(p); knot.invec = tm.MultiplyPoint3x4(invec); knot.outvec = tm.MultiplyPoint3x4(outvec); knots.Add(knot); }
static public string Export(MegaShape shape, int x, int y, float strokewidth, Color col) { string file = ""; Color32 c = col; file += "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; file += "<!-- MegaShapes SVG Exporter v1.0 -->\n"; file += "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"; file += "<svg version=\"1.1\" id=\"" + shape.name + "\" x=\"0px\" y=\"0px\" width=\"640.0px\" height=\"480.0px\">\n"; for (int i = 0; i < shape.splines.Count; i++) { MegaSpline spline = shape.splines[i]; file += "<path d=\""; MegaKnot k1; MegaKnot k = spline.knots[0]; k1 = k; file += "M" + k.p[x] + "," + -k.p[y]; //Vector3 cp = k.p; for (int j = 1; j < spline.knots.Count; j++) { k = spline.knots[j]; Vector3 po = k1.outvec; // - cp; // - k1.p; Vector3 pi = k.invec; // - cp; // - k.p; Vector3 kp = k.p; // - cp; kp[y] = -kp[y]; po[y] = -po[y]; pi[y] = -pi[y]; file += "C" + po[x] + "," + po[y]; file += " " + pi[x] + "," + pi[y]; file += " " + kp[x] + "," + kp[y]; k1 = k; } if (spline.closed) { file += "z\""; } file += " fill=\"none\""; file += " stroke=\"#" + c.r.ToString("x") + c.g.ToString("x") + c.b.ToString("x") + "\""; file += " stroke-width=\"" + strokewidth + "\""; file += "/>\n"; } file += "</svg>\n"; return(file); }
void DisplayKnot(MegaShape shape, MegaSpline spline, MegaKnot knot) { bool recalc = false; Vector3 p = EditorGUILayout.Vector3Field("Pos", knot.p); #if false Vector3 invec = EditorGUILayout.Vector3Field("In", knot.invec); //Vector3 outvec = EditorGUILayout.Vector3Field("Out", knot.outvec); if (invec != knot.invec) { if (shape.lockhandles) { Vector3 d = invec - knot.invec; knot.outvec -= d; } knot.invec = invec; recalc = true; } Vector3 outvec = EditorGUILayout.Vector3Field("Out", knot.outvec); if (outvec != knot.outvec) { if (shape.lockhandles) { Vector3 d = outvec - knot.outvec; knot.invec -= d; } knot.outvec = outvec; recalc = true; } //Vector3 p = EditorGUILayout.Vector3Field("Pos", knot.p); #endif delta = p - knot.p; knot.invec += delta; knot.outvec += delta; if (knot.p != p) { recalc = true; knot.p = p; } if (recalc) { shape.CalcLength(10); } }
public void MoveKey(MegaKnot knot, float t, int k) { px.MoveKey(k, new Keyframe(t, knot.p.x)); py.MoveKey(k, new Keyframe(t, knot.p.y)); pz.MoveKey(k, new Keyframe(t, knot.p.z)); ix.MoveKey(k, new Keyframe(t, knot.invec.x)); iy.MoveKey(k, new Keyframe(t, knot.invec.y)); iz.MoveKey(k, new Keyframe(t, knot.invec.z)); ox.MoveKey(k, new Keyframe(t, knot.outvec.x)); oy.MoveKey(k, new Keyframe(t, knot.outvec.y)); oz.MoveKey(k, new Keyframe(t, knot.outvec.z)); }
public void AddKey(MegaKnot knot, float t) { px.AddKey(new Keyframe(t, knot.p.x)); py.AddKey(new Keyframe(t, knot.p.y)); pz.AddKey(new Keyframe(t, knot.p.z)); ix.AddKey(new Keyframe(t, knot.invec.x)); iy.AddKey(new Keyframe(t, knot.invec.y)); iz.AddKey(new Keyframe(t, knot.invec.z)); ox.AddKey(new Keyframe(t, knot.outvec.x)); oy.AddKey(new Keyframe(t, knot.outvec.y)); oz.AddKey(new Keyframe(t, knot.outvec.z)); }
public void GetState(MegaKnot knot, float t) { knot.p.x = px.Evaluate(t); knot.p.y = py.Evaluate(t); knot.p.z = pz.Evaluate(t); knot.invec.x = ix.Evaluate(t); knot.invec.y = iy.Evaluate(t); knot.invec.z = iz.Evaluate(t); knot.outvec.x = ox.Evaluate(t); knot.outvec.y = oy.Evaluate(t); knot.outvec.z = oz.Evaluate(t); }
void UpdateKnot(int knotIndex, int boneIndex, Transform bone, Transform prev, Transform next) { MegaKnot knot = megaSpline.knots[knotIndex]; Vector3 newPos = shapeTr.InverseTransformPoint(bone.position) + offsets[boneIndex]; if (newPos != knot.p) { knot.p = newPos; } Vector3 inV, outV; if (knotIndex > 0) { inV = shapeTr.InverseTransformPoint(prev.position) + offsets[boneIndex - 1]; } else { inV = 2f * newPos - knot.outvec; } if (knotIndex < megaSpline.knots.Count - 1) { outV = shapeTr.InverseTransformPoint(next.position) + offsets[boneIndex + 1]; } else { outV = 2f * newPos - knot.invec; } if (knotIndex == 0 || knotIndex == megaSpline.knots.Count - 1 || !smoothTang) { knot.invec = inV; knot.outvec = outV; } else { Vector3 toIn = inV - knot.p; Vector3 toOut = outV - knot.p; Vector3 ortho = toIn.normalized + toOut.normalized; Vector3 newIn = Vector3.ProjectOnPlane(toIn, ortho); Vector3 newOut = Vector3.ProjectOnPlane(toOut, ortho); knot.invec = knot.p + newIn; knot.outvec = knot.p + newOut; } shape.CalcLength(); }
void UpdateTang(int index) { MegaKnot knot = megaSpline.knots[index]; if (index > 0) { Vector3 previous = megaSpline.knots[index - 1].p; knot.invec = (knot.p + previous) * 0.5f; } if (index < bones.Length - 1) { Vector3 next = megaSpline.knots[1].p; knot.outvec = (knot.p + next) * 0.5f; } }
public void Reverse() { List <MegaKnot> newknots = new List <MegaKnot>(); for (int i = knots.Count - 1; i >= 0; i--) { MegaKnot k = new MegaKnot(); k.p = knots[i].p; k.invec = knots[i].outvec; k.outvec = knots[i].invec; newknots.Add(k); } knots = newknots; CalcLength(); //(10); }
public Vector3 InterpolateCS(float t, MegaKnot k) { if (lengths == null || lengths.Length == 0) { return(Interpolate(t, k)); } float u = (t * seglength) + lengths[0]; int high = lengths.Length - 1; int low = -1; int probe = 0; //int i = lengths.Length / 2; while (high - low > 1) { probe = (high + low) / 2; if (u >= lengths[probe]) { if (u < lengths[probe + 1]) { break; } low = probe; } else { high = probe; } } //for ( i = 0; i < lengths.Length - 1; i++ ) //{ // if ( u < lengths[i] ) // { // break; // } //} float alpha = (u - lengths[probe]) / (lengths[probe + 1] - lengths[probe]); return(Vector3.Lerp(points[probe], points[probe + 1], alpha)); }
public Vector3 InterpolateCS(float t, MegaKnot k) { if ( lengths == null || lengths.Length == 0 ) return Interpolate(t, k); float u = (t * seglength) + lengths[0]; int i = 0; for ( i = 0; i < lengths.Length - 1; i++ ) { if ( u < lengths[i] ) { break; } } float alpha = (u - lengths[i - 1]) / (lengths[i] - lengths[i - 1]); return Vector3.Lerp(points[i - 1], points[i], alpha); }
public Vector3 Tangent(float t, MegaKnot k) { Vector3 vel; float a = t; float b = 1.0f - t; float b2 = b * b; float a2 = a * a; vel.x = (-3.0f * p.x * b2) + (3.0f * outvec.x * b * (b - 2.0f * a)) + (3.0f * k.invec.x * a * (2.0f * b - a)) + (k.p.x * 3.0f * a2); vel.y = (-3.0f * p.y * b2) + (3.0f * outvec.y * b * (b - 2.0f * a)) + (3.0f * k.invec.y * a * (2.0f * b - a)) + (k.p.y * 3.0f * a2); vel.z = (-3.0f * p.z * b2) + (3.0f * outvec.z * b * (b - 2.0f * a)) + (3.0f * k.invec.z * a * (2.0f * b - a)) + (k.p.z * 3.0f * a2); //float d = vel.sqrMagnitude; return(vel); }
bool SplineParse(BinaryReader br, string cid) { MegaShape ms = (MegaShape)target; MegaSpline ps = ms.splines[ms.splines.Count - 1]; switch (cid) { case "Transform": Vector3 pos = ReadP3(br); Vector3 rot = ReadP3(br); Vector3 scl = ReadP3(br); rot.y = -rot.y; ms.transform.position = pos; ms.transform.rotation = Quaternion.Euler(rot * Mathf.Rad2Deg); ms.transform.localScale = scl; break; case "Flags": int count = br.ReadInt32(); ps.closed = (br.ReadInt32() == 1); count = br.ReadInt32(); ps.knots = new List <MegaKnot>(count); ps.length = 0.0f; break; case "Knots": for (int i = 0; i < ps.knots.Capacity; i++) { MegaKnot pk = new MegaKnot(); pk.p = ReadP3(br); pk.invec = ReadP3(br); pk.outvec = ReadP3(br); pk.seglength = br.ReadSingle(); ps.length += pk.seglength; pk.length = ps.length; ps.knots.Add(pk); } break; } return(true); }
public Vector3 Interpolate(float t, MegaKnot k) { float omt = 1.0f - t; float omt2 = omt * omt; float omt3 = omt2 * omt; float t2 = t * t; float t3 = t2 * t; omt2 = 3.0f * omt2 * t; omt = 3.0f * omt * t2; Vector3 tp = Vector3.zero; tp.x = (omt3 * p.x) + (omt2 * outvec.x) + (omt * k.invec.x) + (t3 * k.p.x); tp.y = (omt3 * p.y) + (omt2 * outvec.y) + (omt * k.invec.y) + (t3 * k.p.y); tp.z = (omt3 * p.z) + (omt2 * outvec.z) + (omt * k.invec.z) + (t3 * k.p.z); return(tp); }
public Vector3 Interpolate(float t, MegaKnot k) { float omt = 1.0f - t; float omt2 = omt * omt; float omt3 = omt2 * omt; float t2 = t * t; float t3 = t2 * t; omt2 = 3.0f * omt2 * t; omt = 3.0f * omt * t2; Vector3 tp = Vector3.zero; tp.x = (omt3 * p.x) + (omt2 * outvec.x) + (omt * k.invec.x) + (t3 * k.p.x); tp.y = (omt3 * p.y) + (omt2 * outvec.y) + (omt * k.invec.y) + (t3 * k.p.y); tp.z = (omt3 * p.z) + (omt2 * outvec.z) + (omt * k.invec.z) + (t3 * k.p.z); return tp; }
void ParsePolygon(MegaXMLNode node, MegaShape shape) { MegaSpline spline = GetSpline(shape); spline.knots.Clear(); spline.closed = true; char[] charSeparators = new char[] { ' ' }; for (int i = 0; i < node.values.Count; i++) { MegaXMLValue val = node.values[i]; switch (val.name) { case "points": string[] coordinates = val.value.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries); for (int j = 0; j < coordinates.Length; j++) { Vector3 p = ParseV2Split(coordinates[j], 0); MegaKnot k = new MegaKnot(); k.p = SwapAxis(new Vector3(p.x, 0.0f, p.y), shape.axis); k.invec = k.p; k.outvec = k.p; spline.knots.Add(k); } break; } } if (spline.closed) { Vector3 delta1 = spline.knots[0].outvec - spline.knots[0].p; spline.knots[0].invec = spline.knots[0].p - delta1; } }
public Vector3 InterpolateCS(float t, MegaKnot k) { if (lengths == null || lengths.Length == 0) { return(Interpolate(t, k)); } float u = (t * seglength) + lengths[0]; int i = 0; for (i = 0; i < lengths.Length - 1; i++) { if (u < lengths[i]) { break; } } float alpha = (u - lengths[i - 1]) / (lengths[i] - lengths[i - 1]); return(Vector3.Lerp(points[i - 1], points[i], alpha)); }
void DisplayKnot(MegaShape shape, MegaSpline spline, MegaKnot knot) { bool recalc = false; Vector3 p = EditorGUILayout.Vector3Field("Pos", knot.p); delta = p - knot.p; knot.invec += delta; knot.outvec += delta; if (knot.p != p) { recalc = true; knot.p = p; } if (recalc) { shape.CalcLength(10); } }
void DisplayKnot(MegaShape shape, MegaSpline spline, MegaKnot knot, int i) { bool recalc = false; Vector3 p = EditorGUILayout.Vector3Field("Knot [" + i + "] Pos", knot.p); delta = p - knot.p; knot.invec += delta; knot.outvec += delta; if ( knot.p != p ) { recalc = true; knot.p = p; } if ( recalc ) { shape.CalcLength(); //10); } knot.twist = EditorGUILayout.FloatField("Twist", knot.twist); knot.id = EditorGUILayout.IntField("ID", knot.id); }
void DisplayKnot(MegaShape shape, MegaSpline spline, MegaKnot knot) { bool recalc = false; Vector3 p = EditorGUILayout.Vector3Field("Pos", knot.p); #if false Vector3 invec = EditorGUILayout.Vector3Field("In", knot.invec); //Vector3 outvec = EditorGUILayout.Vector3Field("Out", knot.outvec); if ( invec != knot.invec ) { if ( shape.lockhandles ) { Vector3 d = invec - knot.invec; knot.outvec -= d; } knot.invec = invec; recalc = true; } Vector3 outvec = EditorGUILayout.Vector3Field("Out", knot.outvec); if ( outvec != knot.outvec ) { if ( shape.lockhandles ) { Vector3 d = outvec - knot.outvec; knot.invec -= d; } knot.outvec = outvec; recalc = true; } //Vector3 p = EditorGUILayout.Vector3Field("Pos", knot.p); #endif delta = p - knot.p; knot.invec += delta; knot.outvec += delta; if ( knot.p != p ) { recalc = true; knot.p = p; } if ( recalc ) { shape.CalcLength(10); } }
public override void OnInspectorGUI() { MegaShape shape = (MegaShape)target; EditorGUILayout.BeginHorizontal(); if ( GUILayout.Button("Add Knot") ) { if ( shape.splines == null || shape.splines.Count == 0 ) { MegaSpline spline = new MegaSpline(); // Have methods for these shape.splines.Add(spline); } //Undo.RegisterUndo(target, "Add Knot"); MegaKnot knot = new MegaKnot(); int sp = 0; if ( selected == -1 || shape.splines[0].knots.Count == 1 ) { shape.splines[0].knots.Add(knot); selected = shape.splines[0].knots.Count - 1; } else { if ( selected < shape.splines[0].knots.Count - 1 ) { sp = selected + 1; knot.p = shape.splines[0].knots[selected].Interpolate(0.5f, shape.splines[0].knots[selected + 1]); Vector3 t = shape.splines[0].knots[selected].Interpolate(0.51f, shape.splines[0].knots[selected + 1]); knot.outvec = (t - knot.p); //.Normalize(); knot.outvec.Normalize(); knot.outvec *= shape.splines[0].knots[selected].seglength * 0.25f; knot.invec = -knot.outvec; knot.invec += knot.p; knot.outvec += knot.p; } else { if ( shape.splines[0].closed ) { sp = selected + 1; knot.p = shape.splines[0].knots[selected].Interpolate(0.5f, shape.splines[0].knots[0]); Vector3 t = shape.splines[0].knots[selected].Interpolate(0.51f, shape.splines[0].knots[0]); knot.outvec = (t - knot.p); //.Normalize(); knot.outvec.Normalize(); knot.outvec *= shape.splines[0].knots[selected].seglength * 0.25f; knot.invec = -knot.outvec; knot.invec += knot.p; knot.outvec += knot.p; } else { sp = selected - 1; //Debug.Log("selected " + selected + " count " + shape.splines[0].knots.Count + " sp " + sp); knot.p = shape.splines[0].knots[sp].Interpolate(0.5f, shape.splines[0].knots[sp + 1]); Vector3 t = shape.splines[0].knots[sp].Interpolate(0.51f, shape.splines[0].knots[sp + 1]); knot.outvec = (t - knot.p); //.Normalize(); knot.outvec.Normalize(); knot.outvec *= shape.splines[0].knots[sp].seglength * 0.25f; knot.invec = -knot.outvec; knot.invec += knot.p; knot.outvec += knot.p; sp++; } } shape.splines[0].knots.Insert(sp, knot); selected = sp; //++; } shape.CalcLength(10); EditorUtility.SetDirty(target); } if ( GUILayout.Button("Delete Knot") ) { if ( selected != -1 ) { //Undo.RegisterUndo(target, "Delete Knot"); shape.splines[0].knots.RemoveAt(selected); selected--; shape.CalcLength(10); } EditorUtility.SetDirty(target); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if ( GUILayout.Button("Match Handles") ) { if ( selected != -1 ) { //Undo.RegisterUndo(target, "Match Handles"); Vector3 p = shape.splines[0].knots[selected].p; Vector3 d = shape.splines[0].knots[selected].outvec - p; shape.splines[0].knots[selected].invec = p - d; shape.CalcLength(10); } EditorUtility.SetDirty(target); } if ( GUILayout.Button("Load") ) { // Load a spl file from max, so delete everything and replace LoadShape(ImportScale); } EditorGUILayout.EndHorizontal(); showcommon = EditorGUILayout.Foldout(showcommon, "Common Params"); bool rebuild = false; //Params(); if ( showcommon ) { ImportScale = EditorGUILayout.FloatField("Import Scale", ImportScale); MegaAxis av = (MegaAxis)EditorGUILayout.EnumPopup("Axis", shape.axis); if ( av != shape.axis ) { shape.axis = av; rebuild = true; } shape.col1 = EditorGUILayout.ColorField("Col 1", shape.col1); shape.col2 = EditorGUILayout.ColorField("Col 2", shape.col2); shape.KnotCol = EditorGUILayout.ColorField("Knot Col", shape.KnotCol); shape.HandleCol = EditorGUILayout.ColorField("Handle Col", shape.HandleCol); shape.VecCol = EditorGUILayout.ColorField("Vec Col", shape.VecCol); shape.KnotSize = EditorGUILayout.FloatField("Knot Size", shape.KnotSize); shape.stepdist = EditorGUILayout.FloatField("Step Dist", shape.stepdist); if ( shape.stepdist < 0.01f ) shape.stepdist = 0.01f; shape.normalizedInterp = EditorGUILayout.Toggle("Normalized Interp", shape.normalizedInterp); shape.drawHandles = EditorGUILayout.Toggle("Draw Handles", shape.drawHandles); shape.drawKnots = EditorGUILayout.Toggle("Draw Knots", shape.drawKnots); shape.drawspline = EditorGUILayout.Toggle("Draw Spline", shape.drawspline); shape.lockhandles = EditorGUILayout.Toggle("Lock Handles", shape.lockhandles); shape.animate = EditorGUILayout.Toggle("Animate", shape.animate); if ( shape.animate ) { shape.time = EditorGUILayout.FloatField("Time", shape.time); shape.MaxTime = EditorGUILayout.FloatField("Loop Time", shape.MaxTime); shape.speed = EditorGUILayout.FloatField("Speed", shape.speed); shape.LoopMode = (MegaRepeatMode)EditorGUILayout.EnumPopup("Loop Mode", shape.LoopMode); } showsplines = EditorGUILayout.Foldout(showsplines, "Splines"); if ( showsplines ) { for ( int i = 0; i < shape.splines.Count; i++ ) { DisplaySpline(shape, shape.splines[i]); } } } if ( Params() ) { rebuild = true; } if ( GUI.changed ) { EditorUtility.SetDirty(target); //shape.CalcLength(10); } if ( rebuild ) { shape.MakeShape(); EditorUtility.SetDirty(target); } }
public void AddToSpline(int curve, Vector3[] points) { if ( curve >= 0 && curve < splines.Count ) { MegaSpline spline = splines[curve]; int fk = spline.knots.Count; for ( int i = 0; i < points.Length; i++ ) { MegaKnot knot = new MegaKnot(); knot.p = points[i]; spline.knots.Add(knot); } AutoCurve(spline, fk, fk + points.Length); } }
public override void OnInspectorGUI() { bool buildmesh = false; MegaShape shape = (MegaShape)target; EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Add Knot")) { if (shape.splines == null || shape.splines.Count == 0) { MegaSpline spline = new MegaSpline(); // Have methods for these shape.splines.Add(spline); } //Undo.RegisterUndo(target, "Add Knot"); MegaKnot knot = new MegaKnot(); #if true // Add a point at CursorPos //sp = selected + 1; //Debug.Log("CursorPos " + CursorPos + " CursorKnot " + CursorKnot); float per = CursorPercent * 0.01f; CursorTangent = shape.splines[0].Interpolate(per + 0.01f, true, ref CursorKnot); //this.GetPositionOnSpline(i) - p; CursorPos = shape.splines[0].Interpolate(per, true, ref CursorKnot); //this.GetPositionOnSpline(i) - p; knot.p = CursorPos; //CursorTangent = //Vector3 t = shape.splines[0].knots[selected].Interpolate(0.51f, shape.splines[0].knots[0]); knot.outvec = (CursorTangent - knot.p); knot.outvec.Normalize(); knot.outvec *= shape.splines[0].knots[CursorKnot].seglength * 0.25f; knot.invec = -knot.outvec; knot.invec += knot.p; knot.outvec += knot.p; shape.splines[0].knots.Insert(CursorKnot + 1, knot); #else int sp = 0; if (selected == -1 || shape.splines[0].knots.Count == 1) { shape.splines[0].knots.Add(knot); selected = shape.splines[0].knots.Count - 1; } else { if (selected < shape.splines[0].knots.Count - 1) { sp = selected + 1; knot.p = shape.splines[0].knots[selected].Interpolate(0.5f, shape.splines[0].knots[selected + 1]); Vector3 t = shape.splines[0].knots[selected].Interpolate(0.51f, shape.splines[0].knots[selected + 1]); knot.outvec = (t - knot.p); //.Normalize(); knot.outvec.Normalize(); knot.outvec *= shape.splines[0].knots[selected].seglength * 0.25f; knot.invec = -knot.outvec; knot.invec += knot.p; knot.outvec += knot.p; } else { if (shape.splines[0].closed) { sp = selected + 1; knot.p = shape.splines[0].knots[selected].Interpolate(0.5f, shape.splines[0].knots[0]); Vector3 t = shape.splines[0].knots[selected].Interpolate(0.51f, shape.splines[0].knots[0]); knot.outvec = (t - knot.p); //.Normalize(); knot.outvec.Normalize(); knot.outvec *= shape.splines[0].knots[selected].seglength * 0.25f; knot.invec = -knot.outvec; knot.invec += knot.p; knot.outvec += knot.p; } else { sp = selected - 1; //Debug.Log("selected " + selected + " count " + shape.splines[0].knots.Count + " sp " + sp); knot.p = shape.splines[0].knots[sp].Interpolate(0.5f, shape.splines[0].knots[sp + 1]); Vector3 t = shape.splines[0].knots[sp].Interpolate(0.51f, shape.splines[0].knots[sp + 1]); knot.outvec = (t - knot.p); //.Normalize(); knot.outvec.Normalize(); knot.outvec *= shape.splines[0].knots[sp].seglength * 0.25f; knot.invec = -knot.outvec; knot.invec += knot.p; knot.outvec += knot.p; sp++; } } shape.splines[0].knots.Insert(sp, knot); selected = sp; //++; } #endif shape.CalcLength(10); EditorUtility.SetDirty(target); buildmesh = true; } if (GUILayout.Button("Delete Knot")) { if (selected != -1) { //Undo.RegisterUndo(target, "Delete Knot"); shape.splines[0].knots.RemoveAt(selected); selected--; shape.CalcLength(10); } EditorUtility.SetDirty(target); buildmesh = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Match Handles")) { if (selected != -1) { //Undo.RegisterUndo(target, "Match Handles"); Vector3 p = shape.splines[0].knots[selected].p; Vector3 d = shape.splines[0].knots[selected].outvec - p; shape.splines[0].knots[selected].invec = p - d; shape.CalcLength(10); } EditorUtility.SetDirty(target); buildmesh = true; } if (GUILayout.Button("Load")) { // Load a spl file from max, so delete everything and replace LoadShape(ImportScale); buildmesh = true; } EditorGUILayout.EndHorizontal(); showcommon = EditorGUILayout.Foldout(showcommon, "Common Params"); bool rebuild = false; //Params(); if (showcommon) { //CursorPos = EditorGUILayout.Vector3Field("Cursor", CursorPos); CursorPercent = EditorGUILayout.FloatField("Cursor", CursorPercent); CursorPercent = Mathf.Repeat(CursorPercent, 100.0f); ImportScale = EditorGUILayout.FloatField("Import Scale", ImportScale); MegaAxis av = (MegaAxis)EditorGUILayout.EnumPopup("Axis", shape.axis); if (av != shape.axis) { shape.axis = av; rebuild = true; } shape.col1 = EditorGUILayout.ColorField("Col 1", shape.col1); shape.col2 = EditorGUILayout.ColorField("Col 2", shape.col2); shape.KnotCol = EditorGUILayout.ColorField("Knot Col", shape.KnotCol); shape.HandleCol = EditorGUILayout.ColorField("Handle Col", shape.HandleCol); shape.VecCol = EditorGUILayout.ColorField("Vec Col", shape.VecCol); shape.KnotSize = EditorGUILayout.FloatField("Knot Size", shape.KnotSize); shape.stepdist = EditorGUILayout.FloatField("Step Dist", shape.stepdist); if (shape.stepdist < 0.01f) { shape.stepdist = 0.01f; } shape.normalizedInterp = EditorGUILayout.Toggle("Normalized Interp", shape.normalizedInterp); shape.drawHandles = EditorGUILayout.Toggle("Draw Handles", shape.drawHandles); shape.drawKnots = EditorGUILayout.Toggle("Draw Knots", shape.drawKnots); shape.drawspline = EditorGUILayout.Toggle("Draw Spline", shape.drawspline); shape.lockhandles = EditorGUILayout.Toggle("Lock Handles", shape.lockhandles); shape.animate = EditorGUILayout.Toggle("Animate", shape.animate); if (shape.animate) { shape.time = EditorGUILayout.FloatField("Time", shape.time); shape.MaxTime = EditorGUILayout.FloatField("Loop Time", shape.MaxTime); shape.speed = EditorGUILayout.FloatField("Speed", shape.speed); shape.LoopMode = (MegaRepeatMode)EditorGUILayout.EnumPopup("Loop Mode", shape.LoopMode); } // Mesher shape.makeMesh = EditorGUILayout.Toggle("Make Mesh", shape.makeMesh); if (shape.makeMesh) { shape.meshType = (MeshShapeType)EditorGUILayout.EnumPopup("Mesh Type", shape.meshType); shape.Pivot = EditorGUILayout.Vector3Field("Pivot", shape.Pivot); shape.CalcTangents = EditorGUILayout.Toggle("Calc Tangents", shape.CalcTangents); shape.GenUV = EditorGUILayout.Toggle("Gen UV", shape.GenUV); shape.PhysUV = EditorGUILayout.Toggle("Physical UV", shape.PhysUV); shape.UVOffset = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset); shape.UVRotate = EditorGUILayout.Vector2Field("UV Rotate", shape.UVRotate); shape.UVScale = EditorGUILayout.Vector2Field("UV Scale", shape.UVScale); shape.UVOffset1 = EditorGUILayout.Vector2Field("UV Offset1", shape.UVOffset1); shape.UVRotate1 = EditorGUILayout.Vector2Field("UV Rotate1", shape.UVRotate1); shape.UVScale1 = EditorGUILayout.Vector2Field("UV Scale1", shape.UVScale1); switch (shape.meshType) { case MeshShapeType.Fill: shape.DoubleSided = EditorGUILayout.Toggle("Double Sided", shape.DoubleSided); shape.Height = EditorGUILayout.FloatField("Height", shape.Height); shape.HeightSegs = EditorGUILayout.IntField("HeightSegs", shape.HeightSegs); shape.UseHeightCurve = EditorGUILayout.Toggle("Use Height Crv", shape.UseHeightCurve); if (shape.UseHeightCurve) { shape.heightCrv = EditorGUILayout.CurveField("Height Curve", shape.heightCrv); } break; case MeshShapeType.Line: shape.DoubleSided = EditorGUILayout.Toggle("Double Sided", shape.DoubleSided); shape.Height = EditorGUILayout.FloatField("Height", shape.Height); shape.HeightSegs = EditorGUILayout.IntField("HeightSegs", shape.HeightSegs); shape.heightCrv = EditorGUILayout.CurveField("Height Curve", shape.heightCrv); shape.Start = EditorGUILayout.FloatField("Start", shape.Start); shape.End = EditorGUILayout.FloatField("End", shape.End); shape.Rotate = EditorGUILayout.FloatField("Rotate", shape.Rotate); break; case MeshShapeType.Tube: shape.Sides = EditorGUILayout.IntField("Sides", shape.Sides); shape.TubeStep = EditorGUILayout.FloatField("TubeStep", shape.TubeStep); shape.Start = EditorGUILayout.FloatField("Start", shape.Start); shape.End = EditorGUILayout.FloatField("End", shape.End); break; } } showsplines = EditorGUILayout.Foldout(showsplines, "Splines"); if (showsplines) { for (int i = 0; i < shape.splines.Count; i++) { DisplaySpline(shape, shape.splines[i]); } } } if (Params()) { rebuild = true; } if (GUI.changed) { EditorUtility.SetDirty(target); //shape.CalcLength(10); buildmesh = true; } if (rebuild) { shape.MakeShape(); EditorUtility.SetDirty(target); buildmesh = true; } if (buildmesh) { shape.BuildMesh(); } }
public void OnSceneGUI() { MegaShape shape = (MegaShape)target; bool mouseup = false; bool recalc = false; 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); 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(); }
public override void OnInspectorGUI() { //undoManager.CheckUndo(); bool buildmesh = false; bool recalc = false; MegaShape shape = (MegaShape)target; EditorGUILayout.BeginHorizontal(); int curve = shape.selcurve; if ( GUILayout.Button("Add Knot") ) { if ( shape.splines == null || shape.splines.Count == 0 ) { MegaSpline spline = new MegaSpline(); // Have methods for these shape.splines.Add(spline); } MegaKnot knot = new MegaKnot(); float per = shape.CursorPercent * 0.01f; CursorTangent = shape.splines[curve].Interpolate(per + 0.01f, true, ref CursorKnot); //this.GetPositionOnSpline(i) - p; CursorPos = shape.splines[curve].Interpolate(per, true, ref CursorKnot); //this.GetPositionOnSpline(i) - p; knot.p = CursorPos; knot.outvec = (CursorTangent - knot.p); knot.outvec.Normalize(); knot.outvec *= shape.splines[curve].knots[CursorKnot].seglength * 0.25f; knot.invec = -knot.outvec; knot.invec += knot.p; knot.outvec += knot.p; knot.twist = shape.splines[curve].knots[CursorKnot].twist; knot.id = shape.splines[curve].knots[CursorKnot].id; shape.splines[curve].knots.Insert(CursorKnot + 1, knot); shape.CalcLength(); //10); EditorUtility.SetDirty(target); buildmesh = true; } if ( GUILayout.Button("Delete Knot") ) { if ( selected != -1 ) { shape.splines[curve].knots.RemoveAt(selected); selected--; shape.CalcLength(); //10); } EditorUtility.SetDirty(target); buildmesh = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if ( GUILayout.Button("Match Handles") ) { if ( selected != -1 ) { Vector3 p = shape.splines[curve].knots[selected].p; Vector3 d = shape.splines[curve].knots[selected].outvec - p; shape.splines[curve].knots[selected].invec = p - d; shape.CalcLength(); //10); } EditorUtility.SetDirty(target); buildmesh = true; } if ( GUILayout.Button("Load") ) { LoadShape(ImportScale); buildmesh = true; } if ( GUILayout.Button("Load SXL") ) { LoadSXL(ImportScale); buildmesh = true; } if ( GUILayout.Button("Load KML") ) { LoadKML(ImportScale); buildmesh = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if ( GUILayout.Button("AutoCurve") ) { shape.AutoCurve(); EditorUtility.SetDirty(target); buildmesh = true; } if ( GUILayout.Button("Reverse") ) { shape.Reverse(curve); //shape.CalcLength(); EditorUtility.SetDirty(target); buildmesh = true; } EditorGUILayout.EndHorizontal(); if ( GUILayout.Button("Centre Shape") ) { shape.Centre(1.0f, Vector3.one); } if ( GUILayout.Button("Apply Scaling") ) { shape.Scale(shape.transform.localScale); EditorUtility.SetDirty(target); shape.transform.localScale = Vector3.one; buildmesh = true; } if ( GUILayout.Button("Import SVG") ) { LoadSVG(ImportScale); buildmesh = true; } showcommon = EditorGUILayout.Foldout(showcommon, "Common Params"); bool rebuild = false; //Params(); if ( showcommon ) { shape.CursorPercent = EditorGUILayout.FloatField("Cursor", shape.CursorPercent); shape.CursorPercent = Mathf.Repeat(shape.CursorPercent, 100.0f); ImportScale = EditorGUILayout.FloatField("Import Scale", ImportScale); MegaAxis av = (MegaAxis)EditorGUILayout.EnumPopup("Axis", shape.axis); if ( av != shape.axis ) { shape.axis = av; rebuild = true; } if ( shape.splines.Count > 1 ) shape.selcurve = EditorGUILayout.IntSlider("Curve", shape.selcurve, 0, shape.splines.Count - 1); if ( shape.selcurve < 0 ) shape.selcurve = 0; if ( shape.selcurve > shape.splines.Count - 1 ) shape.selcurve = shape.splines.Count - 1; EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Colors"); shape.col1 = EditorGUILayout.ColorField(shape.col1); shape.col2 = EditorGUILayout.ColorField(shape.col2); EditorGUILayout.EndHorizontal(); shape.VecCol = EditorGUILayout.ColorField("Vec Col", shape.VecCol); shape.KnotSize = EditorGUILayout.FloatField("Knot Size", shape.KnotSize); shape.stepdist = EditorGUILayout.FloatField("Step Dist", shape.stepdist); MegaSpline spline = shape.splines[shape.selcurve]; if ( shape.stepdist < 0.01f ) shape.stepdist = 0.01f; shape.dolateupdate = EditorGUILayout.Toggle("Do Late Update", shape.dolateupdate); shape.normalizedInterp = EditorGUILayout.Toggle("Normalized Interp", shape.normalizedInterp); spline.constantSpeed = EditorGUILayout.Toggle("Constant Speed", spline.constantSpeed); int subdivs = EditorGUILayout.IntField("Calc Subdivs", spline.subdivs); if ( subdivs < 2 ) subdivs = 2; if ( subdivs != spline.subdivs ) spline.CalcLength(subdivs); shape.drawHandles = EditorGUILayout.Toggle("Draw Handles", shape.drawHandles); shape.drawKnots = EditorGUILayout.Toggle("Draw Knots", shape.drawKnots); shape.drawTwist = EditorGUILayout.Toggle("Draw Twist", shape.drawTwist); shape.drawspline = EditorGUILayout.Toggle("Draw Spline", shape.drawspline); shape.showorigin = EditorGUILayout.Toggle("Origin Handle", shape.showorigin); shape.lockhandles = EditorGUILayout.Toggle("Lock Handles", shape.lockhandles); shape.updateondrag = EditorGUILayout.Toggle("Update On Drag", shape.updateondrag); shape.usesnap = EditorGUILayout.BeginToggleGroup("Use Snap", shape.usesnap); shape.usesnaphandles = EditorGUILayout.Toggle("Snap Handles", shape.usesnaphandles); shape.snap = EditorGUILayout.Vector3Field("Snap", shape.snap); if ( shape.snap.x < 0.0f ) shape.snap.x = 0.0f; if ( shape.snap.y < 0.0f ) shape.snap.y = 0.0f; if ( shape.snap.z < 0.0f ) shape.snap.z = 0.0f; EditorGUILayout.EndToggleGroup(); //shape.autosmooth = EditorGUILayout.Toggle("Auto Smooth", shape.autosmooth); //shape.smoothness = EditorGUILayout.FloatField("Smoothness", shape.smoothness); float smoothness = EditorGUILayout.Slider("Smoothness", shape.smoothness, 0.0f, 1.5f); if ( smoothness != shape.smoothness ) { shape.smoothness = smoothness; shape.AutoCurve(); recalc = true; } shape.handleType = (MegaHandleType)EditorGUILayout.EnumPopup("Handle Type", shape.handleType); showlabels = EditorGUILayout.Toggle("Labels", showlabels); bool hidewire1 = EditorGUILayout.Toggle("Hide Wire", hidewire); if ( hidewire1 != hidewire ) { hidewire = hidewire1; EditorUtility.SetSelectedWireframeHidden(shape.GetComponent<Renderer>(), hidewire); } shape.animate = EditorGUILayout.Toggle("Animate", shape.animate); if ( shape.animate ) { shape.time = EditorGUILayout.FloatField("Time", shape.time); shape.MaxTime = EditorGUILayout.FloatField("Loop Time", shape.MaxTime); shape.speed = EditorGUILayout.FloatField("Speed", shape.speed); shape.LoopMode = (MegaRepeatMode)EditorGUILayout.EnumPopup("Loop Mode", shape.LoopMode); } AnimationKeyFrames(shape); if ( shape.splines.Count > 0 ) { if ( spline.outlineSpline != -1 ) { int outlineSpline = EditorGUILayout.IntSlider("Outline Spl", spline.outlineSpline, 0, shape.splines.Count - 1); float outline = EditorGUILayout.FloatField("Outline", spline.outline); if ( outline != spline.outline || outlineSpline != spline.outlineSpline ) { spline.outlineSpline = outlineSpline; spline.outline = outline; if ( outlineSpline != shape.selcurve ) { shape.OutlineSpline(shape.splines[spline.outlineSpline], spline, spline.outline, true); spline.CalcLength(); //10); EditorUtility.SetDirty(target); buildmesh = true; } } } else { outline = EditorGUILayout.FloatField("Outline", outline); if ( GUILayout.Button("Outline") ) { shape.OutlineSpline(shape, shape.selcurve, outline, true); shape.splines[shape.splines.Count - 1].outline = outline; shape.splines[shape.splines.Count - 1].outlineSpline = shape.selcurve; shape.selcurve = shape.splines.Count - 1; EditorUtility.SetDirty(target); buildmesh = true; } } } // Mesher shape.makeMesh = EditorGUILayout.Toggle("Make Mesh", shape.makeMesh); if ( shape.makeMesh ) { shape.meshType = (MeshShapeType)EditorGUILayout.EnumPopup("Mesh Type", shape.meshType); shape.Pivot = EditorGUILayout.Vector3Field("Pivot", shape.Pivot); shape.CalcTangents = EditorGUILayout.Toggle("Calc Tangents", shape.CalcTangents); shape.GenUV = EditorGUILayout.Toggle("Gen UV", shape.GenUV); if ( GUILayout.Button("Build LightMap") ) { MegaShapeLightMapWindow.Init(); } EditorGUILayout.BeginVertical("Box"); switch ( shape.meshType ) { case MeshShapeType.Fill: shape.DoubleSided = EditorGUILayout.Toggle("Double Sided", shape.DoubleSided); shape.Height = EditorGUILayout.FloatField("Height", shape.Height); shape.UseHeightCurve = EditorGUILayout.Toggle("Use Height Crv", shape.UseHeightCurve); if ( shape.UseHeightCurve ) { shape.heightCrv = EditorGUILayout.CurveField("Height Curve", shape.heightCrv); shape.heightOff = EditorGUILayout.Slider("Height Off", shape.heightOff, -1.0f, 1.0f); } shape.mat1 = (Material)EditorGUILayout.ObjectField("Top Mat", shape.mat1, typeof(Material), true); shape.mat2 = (Material)EditorGUILayout.ObjectField("Bot Mat", shape.mat2, typeof(Material), true); shape.mat3 = (Material)EditorGUILayout.ObjectField("Side Mat", shape.mat3, typeof(Material), true); shape.PhysUV = EditorGUILayout.Toggle("Physical UV", shape.PhysUV); shape.UVOffset = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset); shape.UVRotate = EditorGUILayout.Vector2Field("UV Rotate", shape.UVRotate); shape.UVScale = EditorGUILayout.Vector2Field("UV Scale", shape.UVScale); shape.UVOffset1 = EditorGUILayout.Vector2Field("UV Offset1", shape.UVOffset1); shape.UVRotate1 = EditorGUILayout.Vector2Field("UV Rotate1", shape.UVRotate1); shape.UVScale1 = EditorGUILayout.Vector2Field("UV Scale1", shape.UVScale1); break; case MeshShapeType.Tube: shape.TubeStart = EditorGUILayout.Slider("Start", shape.TubeStart, -1.0f, 2.0f); shape.TubeLength = EditorGUILayout.Slider("Length", shape.TubeLength, 0.0f, 1.0f); shape.rotate = EditorGUILayout.FloatField("Rotate", shape.rotate); shape.tsides = EditorGUILayout.IntField("Sides", shape.tsides); shape.tradius = EditorGUILayout.FloatField("Radius", shape.tradius); shape.offset = EditorGUILayout.FloatField("Offset", shape.offset); shape.scaleX = EditorGUILayout.CurveField("Scale X", shape.scaleX); shape.unlinkScale = EditorGUILayout.BeginToggleGroup("unlink Scale", shape.unlinkScale); shape.scaleY = EditorGUILayout.CurveField("Scale Y", shape.scaleY); EditorGUILayout.EndToggleGroup(); shape.strands = EditorGUILayout.IntField("Strands", shape.strands); if ( shape.strands > 1 ) { shape.strandRadius = EditorGUILayout.FloatField("Strand Radius", shape.strandRadius); shape.TwistPerUnit = EditorGUILayout.FloatField("Twist", shape.TwistPerUnit); shape.startAng = EditorGUILayout.FloatField("Start Twist", shape.startAng); } shape.UVOffset = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset); shape.uvtilex = EditorGUILayout.FloatField("UV Tile X", shape.uvtilex); shape.uvtiley = EditorGUILayout.FloatField("UV Tile Y", shape.uvtiley); shape.cap = EditorGUILayout.Toggle("Cap", shape.cap); shape.RopeUp = (MegaAxis)EditorGUILayout.EnumPopup("Up", shape.RopeUp); shape.mat1 = (Material)EditorGUILayout.ObjectField("Mat", shape.mat1, typeof(Material), true); shape.flipNormals = EditorGUILayout.Toggle("Flip Normals", shape.flipNormals); break; case MeshShapeType.Ribbon: shape.TubeStart = EditorGUILayout.Slider("Start", shape.TubeStart, -1.0f, 2.0f); shape.TubeLength = EditorGUILayout.Slider("Length", shape.TubeLength, 0.0f, 1.0f); shape.boxwidth = EditorGUILayout.FloatField("Width", shape.boxwidth); shape.raxis = (MegaAxis)EditorGUILayout.EnumPopup("Axis", shape.raxis); shape.rotate = EditorGUILayout.FloatField("Rotate", shape.rotate); shape.ribsegs = EditorGUILayout.IntField("Segs", shape.ribsegs); if ( shape.ribsegs < 1 ) shape.ribsegs = 1; shape.offset = EditorGUILayout.FloatField("Offset", shape.offset); shape.scaleX = EditorGUILayout.CurveField("Scale X", shape.scaleX); shape.strands = EditorGUILayout.IntField("Strands", shape.strands); if ( shape.strands > 1 ) { shape.strandRadius = EditorGUILayout.FloatField("Strand Radius", shape.strandRadius); shape.TwistPerUnit = EditorGUILayout.FloatField("Twist", shape.TwistPerUnit); shape.startAng = EditorGUILayout.FloatField("Start Twist", shape.startAng); } shape.UVOffset = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset); shape.uvtilex = EditorGUILayout.FloatField("UV Tile X", shape.uvtilex); shape.uvtiley = EditorGUILayout.FloatField("UV Tile Y", shape.uvtiley); shape.RopeUp = (MegaAxis)EditorGUILayout.EnumPopup("Up", shape.RopeUp); shape.mat1 = (Material)EditorGUILayout.ObjectField("Mat", shape.mat1, typeof(Material), true); shape.flipNormals = EditorGUILayout.Toggle("Flip Normals", shape.flipNormals); break; case MeshShapeType.Box: shape.TubeStart = EditorGUILayout.Slider("Start", shape.TubeStart, -1.0f, 2.0f); shape.TubeLength = EditorGUILayout.Slider("Length", shape.TubeLength, 0.0f, 1.0f); shape.rotate = EditorGUILayout.FloatField("Rotate", shape.rotate); shape.boxwidth = EditorGUILayout.FloatField("Box Width", shape.boxwidth); shape.boxheight = EditorGUILayout.FloatField("Box Height", shape.boxheight); shape.offset = EditorGUILayout.FloatField("Offset", shape.offset); shape.scaleX = EditorGUILayout.CurveField("Scale X", shape.scaleX); shape.unlinkScale = EditorGUILayout.BeginToggleGroup("unlink Scale", shape.unlinkScale); shape.scaleY = EditorGUILayout.CurveField("Scale Y", shape.scaleY); EditorGUILayout.EndToggleGroup(); shape.strands = EditorGUILayout.IntField("Strands", shape.strands); if ( shape.strands > 1 ) { shape.tradius = EditorGUILayout.FloatField("Radius", shape.tradius); shape.TwistPerUnit = EditorGUILayout.FloatField("Twist", shape.TwistPerUnit); shape.startAng = EditorGUILayout.FloatField("Start Twist", shape.startAng); } shape.UVOffset = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset); shape.uvtilex = EditorGUILayout.FloatField("UV Tile X", shape.uvtilex); shape.uvtiley = EditorGUILayout.FloatField("UV Tile Y", shape.uvtiley); shape.cap = EditorGUILayout.Toggle("Cap", shape.cap); shape.RopeUp = (MegaAxis)EditorGUILayout.EnumPopup("Up", shape.RopeUp); shape.mat1 = (Material)EditorGUILayout.ObjectField("Mat", shape.mat1, typeof(Material), true); shape.flipNormals = EditorGUILayout.Toggle("Flip Normals", shape.flipNormals); break; } if ( shape.strands < 1 ) shape.strands = 1; EditorGUILayout.EndVertical(); // Conform shape.conform = EditorGUILayout.BeginToggleGroup("Conform", shape.conform); GameObject contarget = (GameObject)EditorGUILayout.ObjectField("Target", shape.target, typeof(GameObject), true); if ( contarget != shape.target ) shape.SetTarget(contarget); shape.conformAmount = EditorGUILayout.Slider("Amount", shape.conformAmount, 0.0f, 1.0f); shape.raystartoff = EditorGUILayout.FloatField("Ray Start Off", shape.raystartoff); shape.conformOffset = EditorGUILayout.FloatField("Conform Offset", shape.conformOffset); shape.raydist = EditorGUILayout.FloatField("Ray Dist", shape.raydist); EditorGUILayout.EndToggleGroup(); } else { shape.ClearMesh(); } showsplines = EditorGUILayout.Foldout(showsplines, "Spline Data"); if ( showsplines ) { EditorGUILayout.BeginVertical("Box"); if ( shape.splines != null && shape.splines.Count > 0 ) DisplaySpline(shape, shape.splines[shape.selcurve]); EditorGUILayout.EndVertical(); } EditorGUILayout.BeginHorizontal(); Color col = GUI.backgroundColor; GUI.backgroundColor = Color.green; if ( GUILayout.Button("Add") ) { // Create a new spline in the shape MegaSpline spl = MegaSpline.Copy(shape.splines[shape.selcurve]); shape.splines.Add(spl); shape.selcurve = shape.splines.Count - 1; EditorUtility.SetDirty(shape); buildmesh = true; } if ( shape.splines.Count > 1 ) { GUI.backgroundColor = Color.red; if ( GUILayout.Button("Delete") ) { // Delete current spline shape.splines.RemoveAt(shape.selcurve); for ( int i = 0; i < shape.splines.Count; i++ ) { if ( shape.splines[i].outlineSpline == shape.selcurve ) shape.splines[i].outlineSpline = -1; if ( shape.splines[i].outlineSpline > shape.selcurve ) shape.splines[i].outlineSpline--; } shape.selcurve--; if ( shape.selcurve < 0 ) shape.selcurve = 0; EditorUtility.SetDirty(shape); buildmesh = true; } } GUI.backgroundColor = col; EditorGUILayout.EndHorizontal(); } if ( !shape.imported ) { if ( Params() ) { rebuild = true; } } showfuncs = EditorGUILayout.Foldout(showfuncs, "Extra Functions"); if ( showfuncs ) { if ( GUILayout.Button("Flatten") ) { shape.SetHeight(shape.selcurve, 0.0f); shape.CalcLength(); EditorUtility.SetDirty(target); } if ( GUILayout.Button("Remove Twist") ) { shape.SetTwist(shape.selcurve, 0.0f); EditorUtility.SetDirty(target); } if ( GUILayout.Button("Copy IDS") ) { shape.CopyIDS(shape.selcurve); EditorUtility.SetDirty(target); } } export = EditorGUILayout.Foldout(export, "Export Options"); if ( export ) { xaxis = (MegaAxis)EditorGUILayout.EnumPopup("X Axis", xaxis); yaxis = (MegaAxis)EditorGUILayout.EnumPopup("Y Axis", yaxis); strokewidth = EditorGUILayout.FloatField("Stroke Width", strokewidth); strokecol = EditorGUILayout.ColorField("Stroke Color", strokecol); if ( GUILayout.Button("Export") ) { Export(shape); } } if ( recalc ) { shape.CalcLength(); //10); 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); } if ( GUI.changed ) { EditorUtility.SetDirty(target); buildmesh = true; } if ( rebuild ) { shape.MakeShape(); EditorUtility.SetDirty(target); buildmesh = true; } if ( buildmesh ) { if ( shape.makeMesh ) { shape.SetMats(); shape.BuildMesh(); } } //undoManager.CheckDirty(); }
void ParsePolygon(MegaXMLNode node, MegaShape shape) { MegaSpline spline = GetSpline(shape); spline.knots.Clear(); spline.closed = true; char[] charSeparators = new char[] { ' ' }; for ( int i = 0; i < node.values.Count; i++ ) { MegaXMLValue val = node.values[i]; switch ( val.name ) { case "points": string[] coordinates = val.value.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries); for ( int j = 0; j < coordinates.Length; j++ ) { Vector3 p = ParseV2Split(coordinates[j], 0); MegaKnot k = new MegaKnot(); k.p = SwapAxis(new Vector3(p.x, 0.0f, p.y), shape.axis); k.invec = k.p; k.outvec = k.p; spline.knots.Add(k); } break; } } if ( spline.closed ) { Vector3 delta1 = spline.knots[0].outvec - spline.knots[0].p; spline.knots[0].invec = spline.knots[0].p - delta1; } }
public override void OnInspectorGUI() { //undoManager.CheckUndo(); bool buildmesh = false; bool recalc = false; MegaShape shape = (MegaShape)target; EditorGUILayout.BeginHorizontal(); int curve = shape.selcurve; if ( GUILayout.Button("Add Knot") ) { if ( shape.splines == null || shape.splines.Count == 0 ) { MegaSpline spline = new MegaSpline(); // Have methods for these shape.splines.Add(spline); } MegaKnot knot = new MegaKnot(); float per = shape.CursorPercent * 0.01f; CursorTangent = shape.splines[curve].Interpolate(per + 0.01f, true, ref CursorKnot); //this.GetPositionOnSpline(i) - p; CursorPos = shape.splines[curve].Interpolate(per, true, ref CursorKnot); //this.GetPositionOnSpline(i) - p; knot.p = CursorPos; knot.outvec = (CursorTangent - knot.p); knot.outvec.Normalize(); knot.outvec *= shape.splines[curve].knots[CursorKnot].seglength * 0.25f; knot.invec = -knot.outvec; knot.invec += knot.p; knot.outvec += knot.p; knot.twist = shape.splines[curve].knots[CursorKnot].twist; knot.id = shape.splines[curve].knots[CursorKnot].id; shape.splines[curve].knots.Insert(CursorKnot + 1, knot); if ( shape.smoothonaddknot ) shape.AutoCurve(shape.splines[snum]); //, knum, knum + 2); shape.CalcLength(); //10); EditorUtility.SetDirty(target); buildmesh = true; } if ( GUILayout.Button("Delete Knot") ) { if ( selected != -1 ) { shape.splines[curve].knots.RemoveAt(selected); selected--; shape.CalcLength(); //10); } EditorUtility.SetDirty(target); buildmesh = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if ( GUILayout.Button("Match Handles") ) { if ( selected != -1 ) { Vector3 p = shape.splines[curve].knots[selected].p; Vector3 d = shape.splines[curve].knots[selected].outvec - p; shape.splines[curve].knots[selected].invec = p - d; shape.CalcLength(); //10); } EditorUtility.SetDirty(target); buildmesh = true; } if ( GUILayout.Button("Load") ) { LoadShape(ImportScale); buildmesh = true; } if ( GUILayout.Button("Load SXL") ) { LoadSXL(ImportScale); buildmesh = true; } if ( GUILayout.Button("Load KML") ) { LoadKML(ImportScale); buildmesh = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if ( GUILayout.Button("AutoCurve") ) { shape.AutoCurve(); EditorUtility.SetDirty(target); buildmesh = true; } if ( GUILayout.Button("Reverse") ) { shape.Reverse(curve); //shape.CalcLength(); EditorUtility.SetDirty(target); buildmesh = true; } EditorGUILayout.EndHorizontal(); if ( GUILayout.Button("Centre Shape") ) { shape.Centre(1.0f, Vector3.one); } if ( GUILayout.Button("Apply Scaling") ) { shape.Scale(shape.transform.localScale); EditorUtility.SetDirty(target); shape.transform.localScale = Vector3.one; buildmesh = true; } if ( GUILayout.Button("Import SVG") ) { LoadSVG(ImportScale); buildmesh = true; } showcommon = EditorGUILayout.Foldout(showcommon, "Common Params"); bool rebuild = false; //Params(); if ( showcommon ) { shape.CursorPercent = EditorGUILayout.FloatField("Cursor", shape.CursorPercent); shape.CursorPercent = Mathf.Repeat(shape.CursorPercent, 100.0f); ImportScale = EditorGUILayout.FloatField("Import Scale", ImportScale); MegaAxis av = (MegaAxis)EditorGUILayout.EnumPopup("Axis", shape.axis); if ( av != shape.axis ) { shape.axis = av; rebuild = true; } if ( shape.splines.Count > 1 ) shape.selcurve = EditorGUILayout.IntSlider("Curve", shape.selcurve, 0, shape.splines.Count - 1); if ( shape.selcurve < 0 ) shape.selcurve = 0; if ( shape.selcurve > shape.splines.Count - 1 ) shape.selcurve = shape.splines.Count - 1; EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Colors"); shape.col1 = EditorGUILayout.ColorField(shape.col1); shape.col2 = EditorGUILayout.ColorField(shape.col2); EditorGUILayout.EndHorizontal(); shape.VecCol = EditorGUILayout.ColorField("Vec Col", shape.VecCol); shape.KnotSize = EditorGUILayout.FloatField("Knot Size", shape.KnotSize); shape.stepdist = EditorGUILayout.FloatField("Step Dist", shape.stepdist); MegaSpline spline = shape.splines[shape.selcurve]; if ( shape.stepdist < 0.01f ) shape.stepdist = 0.01f; shape.dolateupdate = EditorGUILayout.Toggle("Do Late Update", shape.dolateupdate); shape.normalizedInterp = EditorGUILayout.Toggle("Normalized Interp", shape.normalizedInterp); spline.constantSpeed = EditorGUILayout.Toggle("Constant Speed", spline.constantSpeed); int subdivs = EditorGUILayout.IntField("Calc Subdivs", spline.subdivs); if ( subdivs < 2 ) subdivs = 2; if ( subdivs != spline.subdivs ) spline.CalcLength(subdivs); shape.drawHandles = EditorGUILayout.Toggle("Draw Handles", shape.drawHandles); shape.drawKnots = EditorGUILayout.Toggle("Draw Knots", shape.drawKnots); shape.drawTwist = EditorGUILayout.Toggle("Draw Twist", shape.drawTwist); shape.drawspline = EditorGUILayout.Toggle("Draw Spline", shape.drawspline); shape.showorigin = EditorGUILayout.Toggle("Origin Handle", shape.showorigin); shape.lockhandles = EditorGUILayout.Toggle("Lock Handles", shape.lockhandles); shape.updateondrag = EditorGUILayout.Toggle("Update On Drag", shape.updateondrag); shape.usesnap = EditorGUILayout.BeginToggleGroup("Use Snap", shape.usesnap); shape.usesnaphandles = EditorGUILayout.Toggle("Snap Handles", shape.usesnaphandles); shape.snap = EditorGUILayout.Vector3Field("Snap", shape.snap); if ( shape.snap.x < 0.0f ) shape.snap.x = 0.0f; if ( shape.snap.y < 0.0f ) shape.snap.y = 0.0f; if ( shape.snap.z < 0.0f ) shape.snap.z = 0.0f; EditorGUILayout.EndToggleGroup(); //shape.autosmooth = EditorGUILayout.Toggle("Auto Smooth", shape.autosmooth); //shape.smoothness = EditorGUILayout.FloatField("Smoothness", shape.smoothness); float smoothness = EditorGUILayout.Slider("Smoothness", shape.smoothness, 0.0f, 1.5f); if ( smoothness != shape.smoothness ) { shape.smoothness = smoothness; shape.AutoCurve(); recalc = true; } shape.smoothonaddknot = EditorGUILayout.Toggle("Smooth on Add Knot", shape.smoothonaddknot); shape.handleType = (MegaHandleType)EditorGUILayout.EnumPopup("Handle Type", shape.handleType); showlabels = EditorGUILayout.Toggle("Labels", showlabels); bool hidewire1 = EditorGUILayout.Toggle("Hide Wire", hidewire); if ( hidewire1 != hidewire ) { hidewire = hidewire1; EditorUtility.SetSelectedWireframeHidden(shape.GetComponent<Renderer>(), hidewire); } shape.animate = EditorGUILayout.Toggle("Animate", shape.animate); if ( shape.animate ) { shape.time = EditorGUILayout.FloatField("Time", shape.time); shape.MaxTime = EditorGUILayout.FloatField("Loop Time", shape.MaxTime); shape.speed = EditorGUILayout.FloatField("Speed", shape.speed); shape.LoopMode = (MegaRepeatMode)EditorGUILayout.EnumPopup("Loop Mode", shape.LoopMode); } AnimationKeyFrames(shape); if ( shape.splines.Count > 0 ) { if ( spline.outlineSpline != -1 ) { int outlineSpline = EditorGUILayout.IntSlider("Outline Spl", spline.outlineSpline, 0, shape.splines.Count - 1); float outline = EditorGUILayout.FloatField("Outline", spline.outline); if ( outline != spline.outline || outlineSpline != spline.outlineSpline ) { spline.outlineSpline = outlineSpline; spline.outline = outline; if ( outlineSpline != shape.selcurve ) { shape.OutlineSpline(shape.splines[spline.outlineSpline], spline, spline.outline, true); spline.CalcLength(); //10); EditorUtility.SetDirty(target); buildmesh = true; } } } else { outline = EditorGUILayout.FloatField("Outline", outline); if ( GUILayout.Button("Outline") ) { shape.OutlineSpline(shape, shape.selcurve, outline, true); shape.splines[shape.splines.Count - 1].outline = outline; shape.splines[shape.splines.Count - 1].outlineSpline = shape.selcurve; shape.selcurve = shape.splines.Count - 1; EditorUtility.SetDirty(target); buildmesh = true; } } } // Mesher shape.makeMesh = EditorGUILayout.Toggle("Make Mesh", shape.makeMesh); if ( shape.makeMesh ) { shape.meshType = (MeshShapeType)EditorGUILayout.EnumPopup("Mesh Type", shape.meshType); shape.Pivot = EditorGUILayout.Vector3Field("Pivot", shape.Pivot); shape.CalcTangents = EditorGUILayout.Toggle("Calc Tangents", shape.CalcTangents); shape.GenUV = EditorGUILayout.Toggle("Gen UV", shape.GenUV); if ( GUILayout.Button("Build LightMap") ) { MegaShapeLightMapWindow.Init(); } EditorGUILayout.BeginVertical("Box"); switch ( shape.meshType ) { case MeshShapeType.Fill: shape.DoubleSided = EditorGUILayout.Toggle("Double Sided", shape.DoubleSided); shape.Height = EditorGUILayout.FloatField("Height", shape.Height); shape.UseHeightCurve = EditorGUILayout.Toggle("Use Height Crv", shape.UseHeightCurve); if ( shape.UseHeightCurve ) { shape.heightCrv = EditorGUILayout.CurveField("Height Curve", shape.heightCrv); shape.heightOff = EditorGUILayout.Slider("Height Off", shape.heightOff, -1.0f, 1.0f); } shape.mat1 = (Material)EditorGUILayout.ObjectField("Top Mat", shape.mat1, typeof(Material), true); shape.mat2 = (Material)EditorGUILayout.ObjectField("Bot Mat", shape.mat2, typeof(Material), true); shape.mat3 = (Material)EditorGUILayout.ObjectField("Side Mat", shape.mat3, typeof(Material), true); shape.PhysUV = EditorGUILayout.Toggle("Physical UV", shape.PhysUV); shape.UVOffset = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset); shape.UVRotate = EditorGUILayout.Vector2Field("UV Rotate", shape.UVRotate); shape.UVScale = EditorGUILayout.Vector2Field("UV Scale", shape.UVScale); shape.UVOffset1 = EditorGUILayout.Vector2Field("UV Offset1", shape.UVOffset1); shape.UVRotate1 = EditorGUILayout.Vector2Field("UV Rotate1", shape.UVRotate1); shape.UVScale1 = EditorGUILayout.Vector2Field("UV Scale1", shape.UVScale1); break; case MeshShapeType.Tube: shape.TubeStart = EditorGUILayout.Slider("Start", shape.TubeStart, -1.0f, 2.0f); shape.TubeLength = EditorGUILayout.Slider("Length", shape.TubeLength, 0.0f, 1.0f); shape.rotate = EditorGUILayout.FloatField("Rotate", shape.rotate); shape.tsides = EditorGUILayout.IntField("Sides", shape.tsides); shape.tradius = EditorGUILayout.FloatField("Radius", shape.tradius); shape.offset = EditorGUILayout.FloatField("Offset", shape.offset); shape.scaleX = EditorGUILayout.CurveField("Scale X", shape.scaleX); shape.unlinkScale = EditorGUILayout.BeginToggleGroup("unlink Scale", shape.unlinkScale); shape.scaleY = EditorGUILayout.CurveField("Scale Y", shape.scaleY); EditorGUILayout.EndToggleGroup(); shape.strands = EditorGUILayout.IntField("Strands", shape.strands); if ( shape.strands > 1 ) { shape.strandRadius = EditorGUILayout.FloatField("Strand Radius", shape.strandRadius); shape.TwistPerUnit = EditorGUILayout.FloatField("Twist", shape.TwistPerUnit); shape.startAng = EditorGUILayout.FloatField("Start Twist", shape.startAng); } shape.UVOffset = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset); shape.uvtilex = EditorGUILayout.FloatField("UV Tile X", shape.uvtilex); shape.uvtiley = EditorGUILayout.FloatField("UV Tile Y", shape.uvtiley); shape.cap = EditorGUILayout.Toggle("Cap", shape.cap); shape.RopeUp = (MegaAxis)EditorGUILayout.EnumPopup("Up", shape.RopeUp); shape.mat1 = (Material)EditorGUILayout.ObjectField("Mat", shape.mat1, typeof(Material), true); shape.flipNormals = EditorGUILayout.Toggle("Flip Normals", shape.flipNormals); break; case MeshShapeType.Ribbon: shape.TubeStart = EditorGUILayout.Slider("Start", shape.TubeStart, -1.0f, 2.0f); shape.TubeLength = EditorGUILayout.Slider("Length", shape.TubeLength, 0.0f, 1.0f); shape.boxwidth = EditorGUILayout.FloatField("Width", shape.boxwidth); shape.raxis = (MegaAxis)EditorGUILayout.EnumPopup("Axis", shape.raxis); shape.rotate = EditorGUILayout.FloatField("Rotate", shape.rotate); shape.ribsegs = EditorGUILayout.IntField("Segs", shape.ribsegs); if ( shape.ribsegs < 1 ) shape.ribsegs = 1; shape.offset = EditorGUILayout.FloatField("Offset", shape.offset); shape.scaleX = EditorGUILayout.CurveField("Scale X", shape.scaleX); shape.strands = EditorGUILayout.IntField("Strands", shape.strands); if ( shape.strands > 1 ) { shape.strandRadius = EditorGUILayout.FloatField("Strand Radius", shape.strandRadius); shape.TwistPerUnit = EditorGUILayout.FloatField("Twist", shape.TwistPerUnit); shape.startAng = EditorGUILayout.FloatField("Start Twist", shape.startAng); } shape.UVOffset = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset); shape.uvtilex = EditorGUILayout.FloatField("UV Tile X", shape.uvtilex); shape.uvtiley = EditorGUILayout.FloatField("UV Tile Y", shape.uvtiley); shape.RopeUp = (MegaAxis)EditorGUILayout.EnumPopup("Up", shape.RopeUp); shape.mat1 = (Material)EditorGUILayout.ObjectField("Mat", shape.mat1, typeof(Material), true); shape.flipNormals = EditorGUILayout.Toggle("Flip Normals", shape.flipNormals); break; case MeshShapeType.Box: shape.TubeStart = EditorGUILayout.Slider("Start", shape.TubeStart, -1.0f, 2.0f); shape.TubeLength = EditorGUILayout.Slider("Length", shape.TubeLength, 0.0f, 1.0f); shape.rotate = EditorGUILayout.FloatField("Rotate", shape.rotate); shape.boxwidth = EditorGUILayout.FloatField("Box Width", shape.boxwidth); shape.boxheight = EditorGUILayout.FloatField("Box Height", shape.boxheight); shape.offset = EditorGUILayout.FloatField("Offset", shape.offset); shape.scaleX = EditorGUILayout.CurveField("Scale X", shape.scaleX); shape.unlinkScale = EditorGUILayout.BeginToggleGroup("unlink Scale", shape.unlinkScale); shape.scaleY = EditorGUILayout.CurveField("Scale Y", shape.scaleY); EditorGUILayout.EndToggleGroup(); shape.strands = EditorGUILayout.IntField("Strands", shape.strands); if ( shape.strands > 1 ) { shape.tradius = EditorGUILayout.FloatField("Radius", shape.tradius); shape.TwistPerUnit = EditorGUILayout.FloatField("Twist", shape.TwistPerUnit); shape.startAng = EditorGUILayout.FloatField("Start Twist", shape.startAng); } shape.UVOffset = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset); shape.uvtilex = EditorGUILayout.FloatField("UV Tile X", shape.uvtilex); shape.uvtiley = EditorGUILayout.FloatField("UV Tile Y", shape.uvtiley); shape.cap = EditorGUILayout.Toggle("Cap", shape.cap); shape.RopeUp = (MegaAxis)EditorGUILayout.EnumPopup("Up", shape.RopeUp); shape.mat1 = (Material)EditorGUILayout.ObjectField("Mat", shape.mat1, typeof(Material), true); shape.flipNormals = EditorGUILayout.Toggle("Flip Normals", shape.flipNormals); break; } if ( shape.strands < 1 ) shape.strands = 1; EditorGUILayout.EndVertical(); // Conform shape.conform = EditorGUILayout.BeginToggleGroup("Conform", shape.conform); GameObject contarget = (GameObject)EditorGUILayout.ObjectField("Target", shape.target, typeof(GameObject), true); if ( contarget != shape.target ) shape.SetTarget(contarget); shape.conformAmount = EditorGUILayout.Slider("Amount", shape.conformAmount, 0.0f, 1.0f); shape.raystartoff = EditorGUILayout.FloatField("Ray Start Off", shape.raystartoff); shape.conformOffset = EditorGUILayout.FloatField("Conform Offset", shape.conformOffset); shape.raydist = EditorGUILayout.FloatField("Ray Dist", shape.raydist); EditorGUILayout.EndToggleGroup(); } else { shape.ClearMesh(); } showsplines = EditorGUILayout.Foldout(showsplines, "Spline Data"); if ( showsplines ) { EditorGUILayout.BeginVertical("Box"); if ( shape.splines != null && shape.splines.Count > 0 ) DisplaySpline(shape, shape.splines[shape.selcurve]); EditorGUILayout.EndVertical(); } EditorGUILayout.BeginHorizontal(); Color col = GUI.backgroundColor; GUI.backgroundColor = Color.green; if ( GUILayout.Button("Add") ) { // Create a new spline in the shape MegaSpline spl = MegaSpline.Copy(shape.splines[shape.selcurve]); shape.splines.Add(spl); shape.selcurve = shape.splines.Count - 1; EditorUtility.SetDirty(shape); buildmesh = true; } if ( shape.splines.Count > 1 ) { GUI.backgroundColor = Color.red; if ( GUILayout.Button("Delete") ) { // Delete current spline shape.splines.RemoveAt(shape.selcurve); for ( int i = 0; i < shape.splines.Count; i++ ) { if ( shape.splines[i].outlineSpline == shape.selcurve ) shape.splines[i].outlineSpline = -1; if ( shape.splines[i].outlineSpline > shape.selcurve ) shape.splines[i].outlineSpline--; } shape.selcurve--; if ( shape.selcurve < 0 ) shape.selcurve = 0; EditorUtility.SetDirty(shape); buildmesh = true; } } GUI.backgroundColor = col; EditorGUILayout.EndHorizontal(); } if ( !shape.imported ) { if ( Params() ) { rebuild = true; } } showfuncs = EditorGUILayout.Foldout(showfuncs, "Extra Functions"); if ( showfuncs ) { if ( GUILayout.Button("Flatten") ) { shape.SetHeight(shape.selcurve, 0.0f); shape.CalcLength(); EditorUtility.SetDirty(target); } if ( GUILayout.Button("Remove Twist") ) { shape.SetTwist(shape.selcurve, 0.0f); EditorUtility.SetDirty(target); } if ( GUILayout.Button("Copy IDS") ) { shape.CopyIDS(shape.selcurve); EditorUtility.SetDirty(target); } } export = EditorGUILayout.Foldout(export, "Export Options"); if ( export ) { xaxis = (MegaAxis)EditorGUILayout.EnumPopup("X Axis", xaxis); yaxis = (MegaAxis)EditorGUILayout.EnumPopup("Y Axis", yaxis); strokewidth = EditorGUILayout.FloatField("Stroke Width", strokewidth); strokecol = EditorGUILayout.ColorField("Stroke Color", strokecol); if ( GUILayout.Button("Export") ) { Export(shape); } } if ( recalc ) { shape.CalcLength(); //10); 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); } if ( GUI.changed ) { EditorUtility.SetDirty(target); buildmesh = true; } if ( rebuild ) { shape.MakeShape(); EditorUtility.SetDirty(target); buildmesh = true; } if ( buildmesh ) { if ( shape.makeMesh ) { shape.SetMats(); shape.BuildMesh(); } } //undoManager.CheckDirty(); }
void ParsePath(MegaXMLNode node, MegaShape shape) { Vector3 cp = Vector3.zero; Vector2 cP1; Vector2 cP2; char[] charSeparators = new char[] { ',', ' ' }; MegaSpline spline = null; MegaKnot k; string[] coord; for (int i = 0; i < node.values.Count; i++) { MegaXMLValue val = node.values[i]; //Debug.Log("val name " + val.name); switch (val.name) { case "d": #if UNITY_FLASH || UNITY_WP8 || UNITY_METRO string[] coordinates = null; //string.Split(val.value, @"(?=[MmLlCcSsZzHhVv])"); #else string[] coordinates = Regex.Split(val.value, @"(?=[MmLlCcSsZzHhVv])"); #endif for (int j = 0; j < coordinates.Length; j++) { if (coordinates[j].Length > 0) { string v = coordinates[j].Substring(1); if (v != null && v.Length > 0) { //v = v.Replace("-", ",-"); while (v.Length > 0 && (v[0] == ',' || v[0] == ' ')) { v = v.Substring(1); } } switch (coordinates[j][0]) { case 'Z': case 'z': if (spline != null) { spline.closed = true; #if false Vector3 delta1 = spline.knots[0].outvec - spline.knots[0].p; spline.knots[0].invec = spline.knots[0].p - delta1; if (spline.knots[0].p == spline.knots[spline.knots.Count - 1].p) { spline.knots.Remove(spline.knots[spline.knots.Count - 1]); } #else int kc = spline.knots.Count - 1; spline.knots[0].invec = spline.knots[kc].invec; spline.knots.Remove(spline.knots[kc]); #endif } break; case 'M': spline = GetSpline(shape); spline.knots.Clear(); cp = ParseV2Split(v, 0); k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = k.p; k.outvec = k.p; spline.knots.Add(k); break; case 'm': spline = GetSpline(shape); spline.knots.Clear(); //Debug.Log("v: " + v); coord = v.Split(" "[0]); //Debug.Log("m coords " + coord.Length); //Debug.Log("v2 " + coord[0]); for (int k0 = 0; k0 < coord.Length - 1; k0 = k0 + 1) { //Debug.Log("v2 " + coord[k0]); Vector3 cp1 = ParseV2Split(coord[k0], 0); //Debug.Log("cp1 " + cp1); cp.x += cp1.x; //ParseV2Split(coord[k0], 0); // ParseV2(coord, k0); cp.y += cp1.y; k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = k.p; k.outvec = k.p; spline.knots.Add(k); } #if false Vector3 cp1 = ParseV2Split(v, 0); cp.x += cp1.x; cp.y += cp1.y; k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = k.p; k.outvec = k.p; spline.knots.Add(k); #endif break; case 'l': //coord = v.Split(","[0]); coord = v.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries); for (int k0 = 0; k0 < coord.Length; k0 = k0 + 2) { cp += ParseV2(coord, k0); } spline.knots[spline.knots.Count - 1].outvec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.outvec = k.p - (k.invec - k.p); spline.knots.Add(k); break; case 'c': coord = v.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries); for (int k2 = 0; k2 < coord.Length; k2 += 6) { cP1 = cp + ParseV2(coord, k2); cP2 = cp + ParseV2(coord, k2 + 2); cp += ParseV2(coord, k2 + 4); spline.knots[spline.knots.Count - 1].outvec = SwapAxis(new Vector3(cP1.x, 0.0f, cP1.y), shape.axis); k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = SwapAxis(new Vector3(cP2.x, 0.0f, cP2.y), shape.axis); k.outvec = k.p - (k.invec - k.p); spline.knots.Add(k); } break; case 'L': //coord = v.Split(","[0]); coord = v.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries); //Debug.Log("v " + v); //Debug.Log("coords " + coord.Length); for (int k3 = 0; k3 < coord.Length; k3 = k3 + 2) { cp = ParseV2(coord, k3); } spline.knots[spline.knots.Count - 1].outvec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.outvec = k.p - (k.invec - k.p); spline.knots.Add(k); break; case 'v': //Debug.Log("v: " + v); coord = v.Split(","[0]); for (int k4 = 0; k4 < coord.Length; k4++) { cp.y += float.Parse(coord[k4]); } spline.knots[spline.knots.Count - 1].outvec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.outvec = k.p - (k.invec - k.p); spline.knots.Add(k); break; case 'V': //coord = v.Split(","[0]); coord = v.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries); for (int k9 = 0; k9 < coord.Length; k9++) { cp.y = float.Parse(coord[k9]); } spline.knots[spline.knots.Count - 1].outvec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.outvec = k.p - (k.invec - k.p); spline.knots.Add(k); break; case 'h': //coord = v.Split(","[0]); coord = v.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries); for (int k5 = 0; k5 < coord.Length; k5++) { cp.x += float.Parse(coord[k5]); } spline.knots[spline.knots.Count - 1].outvec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.outvec = k.p - (k.invec - k.p); spline.knots.Add(k); break; case 'H': coord = v.Split(","[0]); for (int k6 = 0; k6 < coord.Length; k6++) { cp.x = float.Parse(coord[k6]); } spline.knots[spline.knots.Count - 1].outvec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.outvec = k.p - (k.invec - k.p); spline.knots.Add(k); break; case 'S': //coord = v.Split(","[0]); coord = v.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries); for (int k7 = 0; k7 < coord.Length; k7 = k7 + 4) { cp = ParseV2(coord, k7 + 2); cP1 = ParseV2(coord, k7); k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = SwapAxis(new Vector3(cP1.x, 0.0f, cP1.y), shape.axis); k.outvec = k.p - (k.invec - k.p); spline.knots.Add(k); } break; case 's': coord = v.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries); for (int k7 = 0; k7 < coord.Length; k7 = k7 + 4) { cP1 = cp + ParseV2(coord, k7); cp += ParseV2(coord, k7 + 2); k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = SwapAxis(new Vector3(cP1.x, 0.0f, cP1.y), shape.axis); k.outvec = k.p - (k.invec - k.p); spline.knots.Add(k); } break; case 'C': //Debug.Log("v " + v); coord = v.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries); //Debug.Log("crds " + coord.Length); for (int k2 = 0; k2 < coord.Length; k2 += 6) { cP1 = ParseV2(coord, k2); cP2 = ParseV2(coord, k2 + 2); cp = ParseV2(coord, k2 + 4); spline.knots[spline.knots.Count - 1].outvec = SwapAxis(new Vector3(cP1.x, 0.0f, cP1.y), shape.axis); k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = SwapAxis(new Vector3(cP2.x, 0.0f, cP2.y), shape.axis); k.outvec = k.p - (k.invec - k.p); spline.knots.Add(k); } break; default: break; } } } break; } } }
public void BuildSpline(Vector3[] points, bool closed) { MegaSpline spline = new MegaSpline(); spline.knots = new List<MegaKnot>(points.Length); for ( int i = 0; i < points.Length; i++ ) { MegaKnot knot = new MegaKnot(); knot.p = points[i]; spline.knots.Add(knot); } spline.closed = closed; splines.Add(spline); AutoCurve(spline); }
public static MegaSpline Copy(MegaSpline src) { MegaSpline spl = new MegaSpline(); spl.closed = src.closed; spl.offset = src.offset; spl.rotate = src.rotate; spl.scale = src.scale; spl.length = src.length; spl.knots = new List<MegaKnot>(); //src.knots); spl.constantSpeed = src.constantSpeed; spl.subdivs = src.subdivs; for ( int i = 0; i < src.knots.Count; i++ ) { MegaKnot knot = new MegaKnot(); knot.p = src.knots[i].p; knot.invec = src.knots[i].invec; knot.outvec = src.knots[i].outvec; knot.seglength = src.knots[i].seglength; knot.length = src.knots[i].length; knot.notlocked = src.knots[i].notlocked; spl.knots.Add(knot); } spl.animations = new List<MegaKnotAnim>(src.animations); return spl; }
public override void OnInspectorGUI() { bool buildmesh = false; MegaShape shape = (MegaShape)target; EditorGUILayout.BeginHorizontal(); if ( GUILayout.Button("Add Knot") ) { if ( shape.splines == null || shape.splines.Count == 0 ) { MegaSpline spline = new MegaSpline(); // Have methods for these shape.splines.Add(spline); } //Undo.RegisterUndo(target, "Add Knot"); MegaKnot knot = new MegaKnot(); #if true // Add a point at CursorPos //sp = selected + 1; //Debug.Log("CursorPos " + CursorPos + " CursorKnot " + CursorKnot); float per = CursorPercent * 0.01f; CursorTangent = shape.splines[0].Interpolate(per + 0.01f, true, ref CursorKnot); //this.GetPositionOnSpline(i) - p; CursorPos = shape.splines[0].Interpolate(per, true, ref CursorKnot); //this.GetPositionOnSpline(i) - p; knot.p = CursorPos; //CursorTangent = //Vector3 t = shape.splines[0].knots[selected].Interpolate(0.51f, shape.splines[0].knots[0]); knot.outvec = (CursorTangent - knot.p); knot.outvec.Normalize(); knot.outvec *= shape.splines[0].knots[CursorKnot].seglength * 0.25f; knot.invec = -knot.outvec; knot.invec += knot.p; knot.outvec += knot.p; shape.splines[0].knots.Insert(CursorKnot + 1, knot); #else int sp = 0; if ( selected == -1 || shape.splines[0].knots.Count == 1 ) { shape.splines[0].knots.Add(knot); selected = shape.splines[0].knots.Count - 1; } else { if ( selected < shape.splines[0].knots.Count - 1 ) { sp = selected + 1; knot.p = shape.splines[0].knots[selected].Interpolate(0.5f, shape.splines[0].knots[selected + 1]); Vector3 t = shape.splines[0].knots[selected].Interpolate(0.51f, shape.splines[0].knots[selected + 1]); knot.outvec = (t - knot.p); //.Normalize(); knot.outvec.Normalize(); knot.outvec *= shape.splines[0].knots[selected].seglength * 0.25f; knot.invec = -knot.outvec; knot.invec += knot.p; knot.outvec += knot.p; } else { if ( shape.splines[0].closed ) { sp = selected + 1; knot.p = shape.splines[0].knots[selected].Interpolate(0.5f, shape.splines[0].knots[0]); Vector3 t = shape.splines[0].knots[selected].Interpolate(0.51f, shape.splines[0].knots[0]); knot.outvec = (t - knot.p); //.Normalize(); knot.outvec.Normalize(); knot.outvec *= shape.splines[0].knots[selected].seglength * 0.25f; knot.invec = -knot.outvec; knot.invec += knot.p; knot.outvec += knot.p; } else { sp = selected - 1; //Debug.Log("selected " + selected + " count " + shape.splines[0].knots.Count + " sp " + sp); knot.p = shape.splines[0].knots[sp].Interpolate(0.5f, shape.splines[0].knots[sp + 1]); Vector3 t = shape.splines[0].knots[sp].Interpolate(0.51f, shape.splines[0].knots[sp + 1]); knot.outvec = (t - knot.p); //.Normalize(); knot.outvec.Normalize(); knot.outvec *= shape.splines[0].knots[sp].seglength * 0.25f; knot.invec = -knot.outvec; knot.invec += knot.p; knot.outvec += knot.p; sp++; } } shape.splines[0].knots.Insert(sp, knot); selected = sp; //++; } #endif shape.CalcLength(10); EditorUtility.SetDirty(target); buildmesh = true; } if ( GUILayout.Button("Delete Knot") ) { if ( selected != -1 ) { //Undo.RegisterUndo(target, "Delete Knot"); shape.splines[0].knots.RemoveAt(selected); selected--; shape.CalcLength(10); } EditorUtility.SetDirty(target); buildmesh = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if ( GUILayout.Button("Match Handles") ) { if ( selected != -1 ) { //Undo.RegisterUndo(target, "Match Handles"); Vector3 p = shape.splines[0].knots[selected].p; Vector3 d = shape.splines[0].knots[selected].outvec - p; shape.splines[0].knots[selected].invec = p - d; shape.CalcLength(10); } EditorUtility.SetDirty(target); buildmesh = true; } if ( GUILayout.Button("Load") ) { // Load a spl file from max, so delete everything and replace LoadShape(ImportScale); buildmesh = true; } EditorGUILayout.EndHorizontal(); showcommon = EditorGUILayout.Foldout(showcommon, "Common Params"); bool rebuild = false; //Params(); if ( showcommon ) { //CursorPos = EditorGUILayout.Vector3Field("Cursor", CursorPos); CursorPercent = EditorGUILayout.FloatField("Cursor", CursorPercent); CursorPercent = Mathf.Repeat(CursorPercent, 100.0f); ImportScale = EditorGUILayout.FloatField("Import Scale", ImportScale); MegaAxis av = (MegaAxis)EditorGUILayout.EnumPopup("Axis", shape.axis); if ( av != shape.axis ) { shape.axis = av; rebuild = true; } shape.col1 = EditorGUILayout.ColorField("Col 1", shape.col1); shape.col2 = EditorGUILayout.ColorField("Col 2", shape.col2); shape.KnotCol = EditorGUILayout.ColorField("Knot Col", shape.KnotCol); shape.HandleCol = EditorGUILayout.ColorField("Handle Col", shape.HandleCol); shape.VecCol = EditorGUILayout.ColorField("Vec Col", shape.VecCol); shape.KnotSize = EditorGUILayout.FloatField("Knot Size", shape.KnotSize); shape.stepdist = EditorGUILayout.FloatField("Step Dist", shape.stepdist); if ( shape.stepdist < 0.01f ) shape.stepdist = 0.01f; shape.normalizedInterp = EditorGUILayout.Toggle("Normalized Interp", shape.normalizedInterp); shape.drawHandles = EditorGUILayout.Toggle("Draw Handles", shape.drawHandles); shape.drawKnots = EditorGUILayout.Toggle("Draw Knots", shape.drawKnots); shape.drawspline = EditorGUILayout.Toggle("Draw Spline", shape.drawspline); shape.lockhandles = EditorGUILayout.Toggle("Lock Handles", shape.lockhandles); shape.animate = EditorGUILayout.Toggle("Animate", shape.animate); if ( shape.animate ) { shape.time = EditorGUILayout.FloatField("Time", shape.time); shape.MaxTime = EditorGUILayout.FloatField("Loop Time", shape.MaxTime); shape.speed = EditorGUILayout.FloatField("Speed", shape.speed); shape.LoopMode = (MegaRepeatMode)EditorGUILayout.EnumPopup("Loop Mode", shape.LoopMode); } // Mesher shape.makeMesh = EditorGUILayout.Toggle("Make Mesh", shape.makeMesh); if ( shape.makeMesh ) { shape.meshType = (MeshShapeType)EditorGUILayout.EnumPopup("Mesh Type", shape.meshType); shape.Pivot = EditorGUILayout.Vector3Field("Pivot", shape.Pivot); shape.CalcTangents = EditorGUILayout.Toggle("Calc Tangents", shape.CalcTangents); shape.GenUV = EditorGUILayout.Toggle("Gen UV", shape.GenUV); shape.PhysUV = EditorGUILayout.Toggle("Physical UV", shape.PhysUV); shape.UVOffset = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset); shape.UVRotate = EditorGUILayout.Vector2Field("UV Rotate", shape.UVRotate); shape.UVScale = EditorGUILayout.Vector2Field("UV Scale", shape.UVScale); shape.UVOffset1 = EditorGUILayout.Vector2Field("UV Offset1", shape.UVOffset1); shape.UVRotate1 = EditorGUILayout.Vector2Field("UV Rotate1", shape.UVRotate1); shape.UVScale1 = EditorGUILayout.Vector2Field("UV Scale1", shape.UVScale1); switch ( shape.meshType ) { case MeshShapeType.Fill: shape.DoubleSided = EditorGUILayout.Toggle("Double Sided", shape.DoubleSided); shape.Height = EditorGUILayout.FloatField("Height", shape.Height); shape.HeightSegs = EditorGUILayout.IntField("HeightSegs", shape.HeightSegs); shape.UseHeightCurve = EditorGUILayout.Toggle("Use Height Crv", shape.UseHeightCurve); if ( shape.UseHeightCurve ) shape.heightCrv = EditorGUILayout.CurveField("Height Curve", shape.heightCrv); break; case MeshShapeType.Line: shape.DoubleSided = EditorGUILayout.Toggle("Double Sided", shape.DoubleSided); shape.Height = EditorGUILayout.FloatField("Height", shape.Height); shape.HeightSegs = EditorGUILayout.IntField("HeightSegs", shape.HeightSegs); shape.heightCrv = EditorGUILayout.CurveField("Height Curve", shape.heightCrv); shape.Start = EditorGUILayout.FloatField("Start", shape.Start); shape.End = EditorGUILayout.FloatField("End", shape.End); shape.Rotate = EditorGUILayout.FloatField("Rotate", shape.Rotate); break; case MeshShapeType.Tube: shape.Sides = EditorGUILayout.IntField("Sides", shape.Sides); shape.TubeStep = EditorGUILayout.FloatField("TubeStep", shape.TubeStep); shape.Start = EditorGUILayout.FloatField("Start", shape.Start); shape.End = EditorGUILayout.FloatField("End", shape.End); break; } } showsplines = EditorGUILayout.Foldout(showsplines, "Splines"); if ( showsplines ) { for ( int i = 0; i < shape.splines.Count; i++ ) { DisplaySpline(shape, shape.splines[i]); } } } if ( Params() ) { rebuild = true; } if ( GUI.changed ) { EditorUtility.SetDirty(target); //shape.CalcLength(10); buildmesh = true; } if ( rebuild ) { shape.MakeShape(); EditorUtility.SetDirty(target); buildmesh = true; } if ( buildmesh ) { shape.BuildMesh(); } }
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(); }
void ParsePath(MegaXMLNode node, MegaShape shape) { Vector3 cp = Vector3.zero; Vector2 cP1; Vector2 cP2; char[] charSeparators = new char[] { ',', ' ' }; MegaSpline spline = null; MegaKnot k; string[] coord; for ( int i = 0; i < node.values.Count; i++ ) { MegaXMLValue val = node.values[i]; switch ( val.name ) { case "d": #if UNITY_FLASH string[] coordinates = null; //string.Split(val.value, @"(?=[MmLlCcSsZzHhVv])"); #else string[] coordinates = Regex.Split(val.value, @"(?=[MmLlCcSsZzHhVv])"); #endif for ( int j = 0; j < coordinates.Length; j++ ) { if ( coordinates[j].Length > 0 ) { string v = coordinates[j].Substring(1); if ( v != null && v.Length > 0 ) { v = v.Replace("-", ",-"); while ( v.Length > 0 && (v[0] == ',' || v[0] == ' ') ) v = v.Substring(1); } switch ( coordinates[j][0] ) { case 'Z': case 'z': if ( spline != null ) { spline.closed = true; #if false Vector3 delta1 = spline.knots[0].outvec - spline.knots[0].p; spline.knots[0].invec = spline.knots[0].p - delta1; if ( spline.knots[0].p == spline.knots[spline.knots.Count - 1].p ) spline.knots.Remove(spline.knots[spline.knots.Count - 1]); #else int kc = spline.knots.Count - 1; spline.knots[0].invec = spline.knots[kc].invec; spline.knots.Remove(spline.knots[kc]); #endif } break; case 'M': spline = GetSpline(shape); spline.knots.Clear(); cp = ParseV2Split(v, 0); k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = k.p; k.outvec = k.p; spline.knots.Add(k); break; case 'm': spline = GetSpline(shape); spline.knots.Clear(); Vector3 cp1 = ParseV2Split(v, 0); cp.x += cp1.x; cp.y += cp1.y; k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = k.p; k.outvec = k.p; spline.knots.Add(k); break; case 'l': coord = v.Split(","[0]); for ( int k0 = 0; k0 < coord.Length; k0 = k0 + 2 ) cp += ParseV2(coord, k0); spline.knots[spline.knots.Count - 1].outvec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.outvec = k.p - (k.invec - k.p); spline.knots.Add(k); break; case 'c': coord = v.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries); for ( int k2 = 0; k2 < coord.Length; k2 += 6 ) { cP1 = cp + ParseV2(coord, k2); cP2 = cp + ParseV2(coord, k2 + 2); cp += ParseV2(coord, k2 + 4); spline.knots[spline.knots.Count - 1].outvec = SwapAxis(new Vector3(cP1.x, 0.0f, cP1.y), shape.axis); k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = SwapAxis(new Vector3(cP2.x, 0.0f, cP2.y), shape.axis); k.outvec = k.p - (k.invec - k.p); spline.knots.Add(k); } break; case 'L': coord = v.Split(","[0]); for ( int k3 = 0; k3 < coord.Length; k3 = k3 + 2 ) cp = ParseV2(coord, k3); spline.knots[spline.knots.Count - 1].outvec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.outvec = k.p - (k.invec - k.p); spline.knots.Add(k); break; case 'v': //Debug.Log("v: " + v); coord = v.Split(","[0]); for ( int k4 = 0; k4 < coord.Length; k4++ ) cp.y += float.Parse(coord[k4]); spline.knots[spline.knots.Count - 1].outvec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.outvec = k.p - (k.invec - k.p); spline.knots.Add(k); break; case 'V': coord = v.Split(","[0]); for ( int k9 = 0; k9 < coord.Length; k9++ ) cp.y = float.Parse(coord[k9]); spline.knots[spline.knots.Count - 1].outvec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.outvec = k.p - (k.invec - k.p); spline.knots.Add(k); break; case 'h': coord = v.Split(","[0]); for ( int k5 = 0; k5 < coord.Length; k5++ ) cp.x += float.Parse(coord[k5]); spline.knots[spline.knots.Count - 1].outvec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.outvec = k.p - (k.invec - k.p); spline.knots.Add(k); break; case 'H': coord = v.Split(","[0]); for ( int k6 = 0; k6 < coord.Length; k6++ ) cp.x = float.Parse(coord[k6]); spline.knots[spline.knots.Count - 1].outvec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.outvec = k.p - (k.invec - k.p); spline.knots.Add(k); break; case 'S': coord = v.Split(","[0]); for ( int k7 = 0; k7 < coord.Length; k7 = k7 + 4 ) { cp = ParseV2(coord, k7 + 2); cP1 = ParseV2(coord, k7); k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = SwapAxis(new Vector3(cP1.x, 0.0f, cP1.y), shape.axis); k.outvec = k.p - (k.invec - k.p); spline.knots.Add(k); } break; case 's': coord = v.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries); for ( int k7 = 0; k7 < coord.Length; k7 = k7 + 4 ) { cP1 = cp + ParseV2(coord, k7); cp += ParseV2(coord, k7 + 2); k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = SwapAxis(new Vector3(cP1.x, 0.0f, cP1.y), shape.axis); k.outvec = k.p - (k.invec - k.p); spline.knots.Add(k); } break; case 'C': coord = v.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries); for ( int k2 = 0; k2 < coord.Length; k2 += 6 ) { cP1 = ParseV2(coord, k2); cP2 = ParseV2(coord, k2 + 2); cp = ParseV2(coord, k2 + 4); spline.knots[spline.knots.Count - 1].outvec = SwapAxis(new Vector3(cP1.x, 0.0f, cP1.y), shape.axis); k = new MegaKnot(); k.p = SwapAxis(new Vector3(cp.x, 0.0f, cp.y), shape.axis); k.invec = SwapAxis(new Vector3(cP2.x, 0.0f, cP2.y), shape.axis); k.outvec = k.p - (k.invec - k.p); spline.knots.Add(k); } break; default: break; } } } break; } } }
public void BuildSpline(int curve, Vector3[] points, bool closed) { if ( curve >= 0 && curve < splines.Count ) { MegaSpline spline = splines[curve]; spline.knots = new List<MegaKnot>(points.Length); for ( int i = 0; i < points.Length; i++ ) { MegaKnot knot = new MegaKnot(); knot.p = points[i]; spline.knots.Add(knot); } spline.closed = closed; AutoCurve(spline); } }
bool SplineParse(BinaryReader br, string cid) { MegaShape ms = (MegaShape)target; MegaSpline ps = ms.splines[ms.splines.Count - 1]; switch ( cid ) { case "Transform": Vector3 pos = ReadP3(br); Vector3 rot = ReadP3(br); Vector3 scl = ReadP3(br); rot.y = -rot.y; ms.transform.position = pos; ms.transform.rotation = Quaternion.Euler(rot * Mathf.Rad2Deg); ms.transform.localScale = scl; break; case "Flags": int count = br.ReadInt32(); ps.closed = (br.ReadInt32() == 1); count = br.ReadInt32(); ps.knots = new List<MegaKnot>(count); ps.length = 0.0f; break; case "Knots": for ( int i = 0; i < ps.knots.Capacity; i++ ) { MegaKnot pk = new MegaKnot(); pk.p = ReadP3(br); pk.invec = ReadP3(br); pk.outvec = ReadP3(br); pk.seglength = br.ReadSingle(); ps.length += pk.seglength; pk.length = ps.length; ps.knots.Add(pk); } break; } return true; }
public void AddToSpline(int curve, Vector3 point) { if ( curve >= 0 && curve < splines.Count ) { MegaSpline spline = splines[curve]; MegaKnot knot = new MegaKnot(); knot.p = point; spline.knots.Add(knot); AutoCurve(spline, spline.knots.Count - 2, spline.knots.Count - 1); } }
void DisplayKnot(MegaShape shape, MegaSpline spline, MegaKnot knot) { bool recalc = false; Vector3 p = EditorGUILayout.Vector3Field("Pos", knot.p); delta = p - knot.p; knot.invec += delta; knot.outvec += delta; if ( knot.p != p ) { recalc = true; knot.p = p; } if ( recalc ) { shape.CalcLength(); //10); } }
public Vector3 InterpolateCS(float t, MegaKnot k) { if ( lengths == null || lengths.Length == 0 ) return Interpolate(t, k); float u = (t * seglength) + lengths[0]; int high = lengths.Length - 1; int low = -1; int probe = 0; //int i = lengths.Length / 2; while ( high - low > 1 ) { probe = (high + low) / 2; if ( u >= lengths[probe] ) { if ( u < lengths[probe + 1] ) break; low = probe; } else high = probe; } //for ( i = 0; i < lengths.Length - 1; i++ ) //{ // if ( u < lengths[i] ) // { // break; // } //} float alpha = (u - lengths[probe]) / (lengths[probe + 1] - lengths[probe]); return Vector3.Lerp(points[probe], points[probe + 1], alpha); }
public override void OnInspectorGUI() { //undoManager.CheckUndo(); bool buildmesh = false; MegaShape shape = (MegaShape)target; EditorGUILayout.BeginHorizontal(); int curve = shape.selcurve; if ( GUILayout.Button("Add Knot") ) { if ( shape.splines == null || shape.splines.Count == 0 ) { MegaSpline spline = new MegaSpline(); // Have methods for these shape.splines.Add(spline); } //Undo.RegisterUndo(target, "Add Knot"); MegaKnot knot = new MegaKnot(); // Add a point at CursorPos //sp = selected + 1; //Debug.Log("CursorPos " + CursorPos + " CursorKnot " + CursorKnot); float per = shape.CursorPercent * 0.01f; CursorTangent = shape.splines[curve].Interpolate(per + 0.01f, true, ref CursorKnot); //this.GetPositionOnSpline(i) - p; CursorPos = shape.splines[curve].Interpolate(per, true, ref CursorKnot); //this.GetPositionOnSpline(i) - p; knot.p = CursorPos; //CursorTangent = //Vector3 t = shape.splines[0].knots[selected].Interpolate(0.51f, shape.splines[0].knots[0]); knot.outvec = (CursorTangent - knot.p); knot.outvec.Normalize(); knot.outvec *= shape.splines[curve].knots[CursorKnot].seglength * 0.25f; knot.invec = -knot.outvec; knot.invec += knot.p; knot.outvec += knot.p; shape.splines[curve].knots.Insert(CursorKnot + 1, knot); shape.CalcLength(); //10); EditorUtility.SetDirty(target); buildmesh = true; } if ( GUILayout.Button("Delete Knot") ) { if ( selected != -1 ) { //Undo.RegisterUndo(target, "Delete Knot"); shape.splines[curve].knots.RemoveAt(selected); selected--; shape.CalcLength(); //10); } EditorUtility.SetDirty(target); buildmesh = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if ( GUILayout.Button("Match Handles") ) { if ( selected != -1 ) { //Undo.RegisterUndo(target, "Match Handles"); Vector3 p = shape.splines[curve].knots[selected].p; Vector3 d = shape.splines[curve].knots[selected].outvec - p; shape.splines[curve].knots[selected].invec = p - d; shape.CalcLength(); //10); } EditorUtility.SetDirty(target); buildmesh = true; } if ( GUILayout.Button("Load") ) { // Load a spl file from max, so delete everything and replace LoadShape(ImportScale); buildmesh = true; } if ( GUILayout.Button("Load SXL") ) { // Load a spl file from max, so delete everything and replace LoadSXL(ImportScale); buildmesh = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if ( GUILayout.Button("AutoCurve") ) { shape.AutoCurve(); EditorUtility.SetDirty(target); buildmesh = true; } if ( GUILayout.Button("Reverse") ) { shape.Reverse(curve); EditorUtility.SetDirty(target); buildmesh = true; } EditorGUILayout.EndHorizontal(); if ( GUILayout.Button("Apply Scaling") ) { shape.Scale(shape.transform.localScale); EditorUtility.SetDirty(target); shape.transform.localScale = Vector3.one; buildmesh = true; } //outline = EditorGUILayout.FloatField("Outline", outline); //if ( GUILayout.Button("Outline") ) //{ // shape.OutlineSpline(shape, shape.selcurve, outline, true); // EditorUtility.SetDirty(target); // buildmesh = true; //} if ( GUILayout.Button("Import SVG") ) { LoadSVG(ImportScale); buildmesh = true; } showcommon = EditorGUILayout.Foldout(showcommon, "Common Params"); bool rebuild = false; //Params(); if ( showcommon ) { //CursorPos = EditorGUILayout.Vector3Field("Cursor", CursorPos); shape.CursorPercent = EditorGUILayout.FloatField("Cursor", shape.CursorPercent); shape.CursorPercent = Mathf.Repeat(shape.CursorPercent, 100.0f); ImportScale = EditorGUILayout.FloatField("Import Scale", ImportScale); MegaAxis av = (MegaAxis)EditorGUILayout.EnumPopup("Axis", shape.axis); if ( av != shape.axis ) { shape.axis = av; rebuild = true; } if ( shape.splines.Count > 1 ) { //shape.selcurve = EditorGUILayout.IntField("Curve", shape.selcurve); shape.selcurve = EditorGUILayout.IntSlider("Curve", shape.selcurve, 0, shape.splines.Count - 1); } if ( shape.selcurve < 0 ) shape.selcurve = 0; if ( shape.selcurve > shape.splines.Count - 1 ) shape.selcurve = shape.splines.Count - 1; EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Colors"); //shape.col1 = EditorGUILayout.ColorField("Col 1", shape.col1); //shape.col2 = EditorGUILayout.ColorField("Col 2", shape.col2); shape.col1 = EditorGUILayout.ColorField(shape.col1); shape.col2 = EditorGUILayout.ColorField(shape.col2); EditorGUILayout.EndHorizontal(); //shape.KnotCol = EditorGUILayout.ColorField("Knot Col", shape.KnotCol); //shape.HandleCol = EditorGUILayout.ColorField("Handle Col", shape.HandleCol); shape.VecCol = EditorGUILayout.ColorField("Vec Col", shape.VecCol); shape.KnotSize = EditorGUILayout.FloatField("Knot Size", shape.KnotSize); shape.stepdist = EditorGUILayout.FloatField("Step Dist", shape.stepdist); MegaSpline spline = shape.splines[shape.selcurve]; if ( shape.stepdist < 0.01f ) shape.stepdist = 0.01f; shape.dolateupdate = EditorGUILayout.Toggle("Do Late Update", shape.dolateupdate); shape.normalizedInterp = EditorGUILayout.Toggle("Normalized Interp", shape.normalizedInterp); spline.constantSpeed = EditorGUILayout.Toggle("Constant Speed", spline.constantSpeed); int subdivs = EditorGUILayout.IntField("Calc Subdivs", spline.subdivs); if ( subdivs < 2 ) subdivs = 2; if ( subdivs != spline.subdivs ) { //spline.subdivs = subdivs; spline.CalcLength(subdivs); } shape.drawHandles = EditorGUILayout.Toggle("Draw Handles", shape.drawHandles); shape.drawKnots = EditorGUILayout.Toggle("Draw Knots", shape.drawKnots); shape.drawspline = EditorGUILayout.Toggle("Draw Spline", shape.drawspline); shape.lockhandles = EditorGUILayout.Toggle("Lock Handles", shape.lockhandles); shape.autosmooth = EditorGUILayout.Toggle("Auto Smooth", shape.autosmooth); shape.handleType = (MegaHandleType)EditorGUILayout.EnumPopup("Handle Type", shape.handleType); showlabels = EditorGUILayout.Toggle("Labels", showlabels); hidewire = EditorGUILayout.Toggle("Hide Wire", hidewire); EditorUtility.SetSelectedWireframeHidden(shape.renderer, hidewire); shape.animate = EditorGUILayout.Toggle("Animate", shape.animate); if ( shape.animate ) { shape.time = EditorGUILayout.FloatField("Time", shape.time); shape.MaxTime = EditorGUILayout.FloatField("Loop Time", shape.MaxTime); shape.speed = EditorGUILayout.FloatField("Speed", shape.speed); shape.LoopMode = (MegaRepeatMode)EditorGUILayout.EnumPopup("Loop Mode", shape.LoopMode); } if ( shape.splines.Count > 0 ) { //shape.selcurve = EditorGUILayout.IntField("Curve", shape.selcurve); if ( spline.outlineSpline != -1 ) { int outlineSpline = EditorGUILayout.IntSlider("Outline Spl", spline.outlineSpline, 0, shape.splines.Count - 1); float outline = EditorGUILayout.FloatField("Outline", spline.outline); if ( outline != spline.outline || outlineSpline != spline.outlineSpline ) { spline.outlineSpline = outlineSpline; spline.outline = outline; if ( outlineSpline != shape.selcurve ) { shape.OutlineSpline(shape.splines[spline.outlineSpline], spline, spline.outline, true); spline.CalcLength(); //10); EditorUtility.SetDirty(target); buildmesh = true; } } } else { outline = EditorGUILayout.FloatField("Outline", outline); if ( GUILayout.Button("Outline") ) { shape.OutlineSpline(shape, shape.selcurve, outline, true); shape.splines[shape.splines.Count - 1].outline = outline; shape.splines[shape.splines.Count - 1].outlineSpline = shape.selcurve; shape.selcurve = shape.splines.Count - 1; EditorUtility.SetDirty(target); buildmesh = true; } } } // Mesher shape.makeMesh = EditorGUILayout.Toggle("Make Mesh", shape.makeMesh); if ( shape.makeMesh ) { shape.meshType = (MeshShapeType)EditorGUILayout.EnumPopup("Mesh Type", shape.meshType); shape.Pivot = EditorGUILayout.Vector3Field("Pivot", shape.Pivot); shape.CalcTangents = EditorGUILayout.Toggle("Calc Tangents", shape.CalcTangents); shape.GenUV = EditorGUILayout.Toggle("Gen UV", shape.GenUV); EditorGUILayout.BeginVertical("Box"); switch ( shape.meshType ) { case MeshShapeType.Fill: shape.DoubleSided = EditorGUILayout.Toggle("Double Sided", shape.DoubleSided); shape.Height = EditorGUILayout.FloatField("Height", shape.Height); //shape.HeightSegs = EditorGUILayout.IntField("HeightSegs", shape.HeightSegs); shape.UseHeightCurve = EditorGUILayout.Toggle("Use Height Crv", shape.UseHeightCurve); if ( shape.UseHeightCurve ) { shape.heightCrv = EditorGUILayout.CurveField("Height Curve", shape.heightCrv); shape.heightOff = EditorGUILayout.Slider("Height Off", shape.heightOff, -1.0f, 1.0f); } shape.mat1 = (Material)EditorGUILayout.ObjectField("Top Mat", shape.mat1, typeof(Material), true); shape.mat2 = (Material)EditorGUILayout.ObjectField("Bot Mat", shape.mat2, typeof(Material), true); shape.mat3 = (Material)EditorGUILayout.ObjectField("Side Mat", shape.mat3, typeof(Material), true); shape.PhysUV = EditorGUILayout.Toggle("Physical UV", shape.PhysUV); shape.UVOffset = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset); shape.UVRotate = EditorGUILayout.Vector2Field("UV Rotate", shape.UVRotate); shape.UVScale = EditorGUILayout.Vector2Field("UV Scale", shape.UVScale); shape.UVOffset1 = EditorGUILayout.Vector2Field("UV Offset1", shape.UVOffset1); shape.UVRotate1 = EditorGUILayout.Vector2Field("UV Rotate1", shape.UVRotate1); shape.UVScale1 = EditorGUILayout.Vector2Field("UV Scale1", shape.UVScale1); break; //case MeshShapeType.Line: //shape.DoubleSided = EditorGUILayout.Toggle("Double Sided", shape.DoubleSided); //shape.Height = EditorGUILayout.FloatField("Height", shape.Height); //shape.HeightSegs = EditorGUILayout.IntField("HeightSegs", shape.HeightSegs); //shape.heightCrv = EditorGUILayout.CurveField("Height Curve", shape.heightCrv); //shape.Start = EditorGUILayout.FloatField("Start", shape.Start); //shape.End = EditorGUILayout.FloatField("End", shape.End); //shape.Rotate = EditorGUILayout.FloatField("Rotate", shape.Rotate); //break; case MeshShapeType.Tube: shape.TubeStart = EditorGUILayout.Slider("Start", shape.TubeStart, -1.0f, 2.0f); shape.TubeLength = EditorGUILayout.Slider("Length", shape.TubeLength, 0.0f, 1.0f); shape.rotate = EditorGUILayout.FloatField("Rotate", shape.rotate); shape.tsides = EditorGUILayout.IntField("Sides", shape.tsides); shape.tradius = EditorGUILayout.FloatField("Radius", shape.tradius); shape.offset = EditorGUILayout.FloatField("Offset", shape.offset); //shape.SegsPerUnit = EditorGUILayout.FloatField("Segs", shape.SegsPerUnit); shape.scaleX = EditorGUILayout.CurveField("Scale X", shape.scaleX); shape.unlinkScale = EditorGUILayout.BeginToggleGroup("unlink Scale", shape.unlinkScale); shape.scaleY = EditorGUILayout.CurveField("Scale Y", shape.scaleY); EditorGUILayout.EndToggleGroup(); shape.strands = EditorGUILayout.IntField("Strands", shape.strands); if ( shape.strands > 1 ) { shape.strandRadius = EditorGUILayout.FloatField("Strand Radius", shape.strandRadius); shape.TwistPerUnit = EditorGUILayout.FloatField("Twist", shape.TwistPerUnit); shape.startAng = EditorGUILayout.FloatField("Start Twist", shape.startAng); } shape.UVOffset = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset); shape.uvtilex = EditorGUILayout.FloatField("UV Tile X", shape.uvtilex); shape.uvtiley = EditorGUILayout.FloatField("UV Tile Y", shape.uvtiley); shape.cap = EditorGUILayout.Toggle("Cap", shape.cap); shape.RopeUp = (MegaAxis)EditorGUILayout.EnumPopup("Up", shape.RopeUp); shape.mat1 = (Material)EditorGUILayout.ObjectField("Mat", shape.mat1, typeof(Material), true); //shape.Sides = EditorGUILayout.IntField("Sides", shape.Sides); //shape.TubeStep = EditorGUILayout.FloatField("TubeStep", shape.TubeStep); //shape.Start = EditorGUILayout.FloatField("Start", shape.Start); //shape.End = EditorGUILayout.FloatField("End", shape.End); break; case MeshShapeType.Ribbon: shape.TubeStart = EditorGUILayout.Slider("Start", shape.TubeStart, -1.0f, 2.0f); shape.TubeLength = EditorGUILayout.Slider("Length", shape.TubeLength, 0.0f, 1.0f); shape.boxwidth = EditorGUILayout.FloatField("Width", shape.boxwidth); shape.raxis = (MegaAxis)EditorGUILayout.EnumPopup("Axis", shape.raxis); shape.rotate = EditorGUILayout.FloatField("Rotate", shape.rotate); shape.ribsegs = EditorGUILayout.IntField("Segs", shape.ribsegs); if ( shape.ribsegs < 1 ) shape.ribsegs = 1; shape.offset = EditorGUILayout.FloatField("Offset", shape.offset); shape.scaleX = EditorGUILayout.CurveField("Scale X", shape.scaleX); shape.strands = EditorGUILayout.IntField("Strands", shape.strands); if ( shape.strands > 1 ) { shape.strandRadius = EditorGUILayout.FloatField("Strand Radius", shape.strandRadius); shape.TwistPerUnit = EditorGUILayout.FloatField("Twist", shape.TwistPerUnit); shape.startAng = EditorGUILayout.FloatField("Start Twist", shape.startAng); //shape.SegsPerUnit = EditorGUILayout.FloatField("Segs", shape.SegsPerUnit); } shape.UVOffset = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset); shape.uvtilex = EditorGUILayout.FloatField("UV Tile X", shape.uvtilex); shape.uvtiley = EditorGUILayout.FloatField("UV Tile Y", shape.uvtiley); shape.RopeUp = (MegaAxis)EditorGUILayout.EnumPopup("Up", shape.RopeUp); shape.mat1 = (Material)EditorGUILayout.ObjectField("Mat", shape.mat1, typeof(Material), true); break; case MeshShapeType.Box: shape.TubeStart = EditorGUILayout.Slider("Start", shape.TubeStart, -1.0f, 2.0f); shape.TubeLength = EditorGUILayout.Slider("Length", shape.TubeLength, 0.0f, 1.0f); shape.rotate = EditorGUILayout.FloatField("Rotate", shape.rotate); shape.boxwidth = EditorGUILayout.FloatField("Box Width", shape.boxwidth); shape.boxheight = EditorGUILayout.FloatField("Box Height", shape.boxheight); shape.offset = EditorGUILayout.FloatField("Offset", shape.offset); //shape.strandRadius = EditorGUILayout.FloatField("Strand Radius", shape.strandRadius); //shape.strandRadius = EditorGUILayout.FloatField("Strand Radius", shape.strandRadius); //shape.SegsPerUnit = EditorGUILayout.FloatField("Segs", shape.SegsPerUnit); shape.scaleX = EditorGUILayout.CurveField("Scale X", shape.scaleX); shape.unlinkScale = EditorGUILayout.BeginToggleGroup("unlink Scale", shape.unlinkScale); shape.scaleY = EditorGUILayout.CurveField("Scale Y", shape.scaleY); EditorGUILayout.EndToggleGroup(); shape.strands = EditorGUILayout.IntField("Strands", shape.strands); if ( shape.strands > 1 ) { shape.tradius = EditorGUILayout.FloatField("Radius", shape.tradius); shape.TwistPerUnit = EditorGUILayout.FloatField("Twist", shape.TwistPerUnit); shape.startAng = EditorGUILayout.FloatField("Start Twist", shape.startAng); } shape.UVOffset = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset); shape.uvtilex = EditorGUILayout.FloatField("UV Tile X", shape.uvtilex); shape.uvtiley = EditorGUILayout.FloatField("UV Tile Y", shape.uvtiley); shape.cap = EditorGUILayout.Toggle("Cap", shape.cap); shape.RopeUp = (MegaAxis)EditorGUILayout.EnumPopup("Up", shape.RopeUp); shape.mat1 = (Material)EditorGUILayout.ObjectField("Mat", shape.mat1, typeof(Material), true); //shape.Sides = EditorGUILayout.IntField("Sides", shape.Sides); //shape.TubeStep = EditorGUILayout.FloatField("TubeStep", shape.TubeStep); //shape.Start = EditorGUILayout.FloatField("Start", shape.Start); //shape.End = EditorGUILayout.FloatField("End", shape.End); break; } if ( shape.strands < 1 ) shape.strands = 1; EditorGUILayout.EndVertical(); } else { //shape.shapemesh = null; shape.ClearMesh(); } showsplines = EditorGUILayout.Foldout(showsplines, "Spline Data"); if ( showsplines ) { EditorGUILayout.BeginVertical("Box"); if ( shape.splines != null && shape.splines.Count > 0 ) DisplaySpline(shape, shape.splines[shape.selcurve]); EditorGUILayout.EndVertical(); #if false for ( int i = 0; i < shape.splines.Count; i++ ) { // We should only show the selected curve EditorGUILayout.BeginVertical("Box"); DisplaySpline(shape, shape.splines[i]); EditorGUILayout.EndVertical(); } #endif } EditorGUILayout.BeginHorizontal(); Color col = GUI.backgroundColor; GUI.backgroundColor = Color.green; if ( GUILayout.Button("Add") ) { // Create a new spline in the shape MegaSpline spl = MegaSpline.Copy(shape.splines[shape.selcurve]); shape.splines.Add(spl); shape.selcurve = shape.splines.Count - 1; EditorUtility.SetDirty(shape); buildmesh = true; } if ( shape.splines.Count > 1 ) { GUI.backgroundColor = Color.red; if ( GUILayout.Button("Delete") ) { // Delete current spline shape.splines.RemoveAt(shape.selcurve); for ( int i = 0; i < shape.splines.Count; i++ ) { if ( shape.splines[i].outlineSpline == shape.selcurve ) shape.splines[i].outlineSpline = -1; if ( shape.splines[i].outlineSpline > shape.selcurve ) shape.splines[i].outlineSpline--; } shape.selcurve--; if ( shape.selcurve < 0 ) shape.selcurve = 0; EditorUtility.SetDirty(shape); buildmesh = true; } } GUI.backgroundColor = col; EditorGUILayout.EndHorizontal(); } if ( !shape.imported ) { if ( Params() ) { rebuild = true; } } if ( GUI.changed ) { EditorUtility.SetDirty(target); //shape.CalcLength(10); buildmesh = true; } if ( rebuild ) { shape.MakeShape(); EditorUtility.SetDirty(target); buildmesh = true; } if ( buildmesh ) { if ( shape.makeMesh ) { shape.SetMats(); shape.BuildMesh(); } } //undoManager.CheckDirty(); }
public void Reverse() { List<MegaKnot> newknots = new List<MegaKnot>(); for ( int i = knots.Count - 1; i >= 0; i-- ) { MegaKnot k = new MegaKnot(); k.p = knots[i].p; k.invec = knots[i].outvec; k.outvec = knots[i].invec; newknots.Add(k); } knots = newknots; CalcLength(); //(10); }
public Vector3 Tangent(float t, MegaKnot k) { Vector3 vel; float a = t; float b = 1.0f - t; float b2 = b * b; float a2 = a * a; vel.x = (-3.0f * p.x * b2) + (3.0f * outvec.x * b * (b - 2.0f * a)) + (3.0f * k.invec.x * a * (2.0f * b - a)) + (k.p.x * 3.0f * a2); vel.y = (-3.0f * p.y * b2) + (3.0f * outvec.y * b * (b - 2.0f * a)) + (3.0f * k.invec.y * a * (2.0f * b - a)) + (k.p.y * 3.0f * a2); vel.z = (-3.0f * p.z * b2) + (3.0f * outvec.z * b * (b - 2.0f * a)) + (3.0f * k.invec.z * a * (2.0f * b - a)) + (k.p.z * 3.0f * a2); //float d = vel.sqrMagnitude; return vel; }