/// Playback case: /// - Update stroke based on the passed transform (in local coordinates) /// - Do _not_ apply any normal adjustment; it's baked into the control point /// - Do not update the mesh /// TODO: replace with a bulk-ControlPoint API public void UpdateLineFromControlPoint(PointerManager.ControlPoint cp) { float scale = m_CurrentLine.StrokeScale; m_CurrentLine.UpdatePosition_LS( TrTransform.TRS(cp.m_Pos, cp.m_Orient, scale), cp.m_Pressure); }
protected override bool IsControlPointReady(PointerManager.ControlPoint controlPoint) { float meters_LS = (controlPoint.m_Pos - m_lastPosition).magnitude * App.UNITS_TO_METERS; float pointerToLocal = m_stroke.m_BrushScale; float meters_PS = meters_LS / pointerToLocal; m_parent.TryDecrementDistance(meters_PS); bool isReady = m_parent.HasMetersRemaining || m_playBackAtStrokeGranularity; if (isReady) { m_lastPosition = controlPoint.m_Pos; } return isReady; }
public static void AddPointToStroke(int index) { var stroke = SketchMemoryScript.m_Instance.GetStrokeAtIndex(index); var prevCP = stroke.m_ControlPoints[stroke.m_ControlPoints.Length - 1]; Array.Resize(ref stroke.m_ControlPoints, stroke.m_ControlPoints.Length + 1); PointerManager.ControlPoint cp = new PointerManager.ControlPoint { m_Pos = ApiManager.Instance.BrushPosition, m_Orient = ApiManager.Instance.BrushRotation, m_Pressure = prevCP.m_Pressure, m_TimestampMs = prevCP.m_TimestampMs }; stroke.m_ControlPoints[stroke.m_ControlPoints.Length - 1] = cp; stroke.Uncreate(); stroke.m_ControlPointsToDrop = Enumerable.Repeat(false, stroke.m_ControlPoints.Length).ToArray(); stroke.Recreate(null, stroke.Canvas); }
// Continue drawing stroke for this frame. public void Update() { if (m_isDone) { return; } var rPointerScript = m_pointer; var rPointerObject = m_pointer.gameObject; bool needMeshUpdate = false; bool needPointerUpdate = false; bool strokeFinished = false; var lastCp = new PointerManager.ControlPoint(); OverlayManager.m_Instance.UpdateProgress(SketchMemoryScript.m_Instance.GetDrawnPercent()); RdpStrokeSimplifier simplifier = QualityControls.m_Instance.StrokeSimplifier; if (simplifier.Level > 0.0f) { simplifier.CalculatePointsToDrop(m_stroke, m_pointer.CurrentBrushScript); } while (true) { if (m_nextControlPoint >= m_stroke.m_ControlPoints.Length) { needMeshUpdate = true; // Is this really necessary? strokeFinished = true; break; } var cp = m_stroke.m_ControlPoints[m_nextControlPoint]; if (!IsControlPointReady(cp)) { break; } if (!m_stroke.m_ControlPointsToDrop[m_nextControlPoint]) { rPointerScript.UpdateLineFromControlPoint(cp); needMeshUpdate = true; lastCp = cp; needPointerUpdate = true; } ++m_nextControlPoint; } if (needMeshUpdate) { rPointerScript.UpdateLineVisuals(); } if (needPointerUpdate) { // This is only really done for visual reasons var xf_GS = Coords.CanvasPose * TrTransform.TR(lastCp.m_Pos, lastCp.m_Orient); xf_GS.scale = rPointerObject.transform.GetUniformScale(); Coords.AsGlobal[rPointerObject.transform] = xf_GS; rPointerScript.SetPressure(lastCp.m_Pressure); } if (strokeFinished) { rPointerScript.EndLineFromMemory(m_stroke); m_isDone = true; } }
protected abstract bool IsControlPointReady(PointerManager.ControlPoint controlPoint);
public static void Export(string writeFileName) { string ext = Path.GetExtension(writeFileName).ToLower(); Debug.Log("Found extension " + ext); bool useZip = (ext == ".latk" || ext == ".zip"); List <string> FINAL_LAYER_LIST = new List <string>(); for (int hh = 0; hh < layerNum; hh++) { int currentLayer = hh; List <string> sb = new List <string>(); List <string> sbHeader = new List <string>(); sbHeader.Add("\t\t\t\t\t\"frames\":["); sb.Add(string.Join("\n", sbHeader.ToArray())); for (int h = 0; h < frameNum; h++) { int currentFrame = h; List <string> sbbHeader = new List <string>(); sbbHeader.Add("\t\t\t\t\t\t{"); sbbHeader.Add("\t\t\t\t\t\t\t\"strokes\":["); sb.Add(string.Join("\n", sbbHeader.ToArray())); LinkedListNode <Stroke> node = SketchMemoryScript.m_Instance.GetMemoryList.First; if (node == null) { continue; } Stroke stroke = node.Value; for (int i = 0; i < SketchMemoryScript.m_Instance.StrokeCount; i++) { // Simpler way to access strokes in the linked list by index, but possibly more expensive //Stroke stroke = SketchMemoryScript.m_Instance.GetStrokeAtIndex(i); if (i > 0) { node = node.Next; stroke = node.Value; } List <string> sbb = new List <string>(); sbb.Add("\t\t\t\t\t\t\t\t{"); float r = stroke.m_Color.r; float g = stroke.m_Color.g; float b = stroke.m_Color.b; sbb.Add("\t\t\t\t\t\t\t\t\t\"color\":[" + r + ", " + g + ", " + b + "],"); if (stroke.IsGeometryEnabled && stroke.m_ControlPoints.Length > 0) { sbb.Add("\t\t\t\t\t\t\t\t\t\"points\":["); for (int j = 0; j < stroke.m_ControlPoints.Length; j++) { PointerManager.ControlPoint point = stroke.m_ControlPoints[j]; float x = point.m_Pos.x; float y = point.m_Pos.y; float z = point.m_Pos.z; float pressureVal = point.m_Pressure; if (j == stroke.m_ControlPoints.Length - 1) { sbb.Add("\t\t\t\t\t\t\t\t\t\t{\"co\":[" + x + ", " + y + ", " + z + "], \"pressure\":" + pressureVal + ", \"strength\":1}"); sbb.Add("\t\t\t\t\t\t\t\t\t]"); } else { sbb.Add("\t\t\t\t\t\t\t\t\t\t{\"co\":[" + x + ", " + y + ", " + z + "], \"pressure\":" + pressureVal + ", \"strength\":1},"); } } } else { sbb.Add("\t\t\t\t\t\t\t\t\t\"points\":[]"); } if (i == SketchMemoryScript.m_Instance.StrokeCount - 1) { sbb.Add("\t\t\t\t\t\t\t\t}"); } else { sbb.Add("\t\t\t\t\t\t\t\t},"); } sb.Add(string.Join("\n", sbb.ToArray())); } List <string> sbFooter = new List <string>(); if (h == frameNum - 1) { sbFooter.Add("\t\t\t\t\t\t\t]"); sbFooter.Add("\t\t\t\t\t\t}"); } else { sbFooter.Add("\t\t\t\t\t\t\t]"); sbFooter.Add("\t\t\t\t\t\t},"); } sb.Add(string.Join("\n", sbFooter.ToArray())); } FINAL_LAYER_LIST.Add(string.Join("\n", sb.ToArray())); } Debug.Log("+++ Parsing finished. Begin file writing."); List <string> s = new List <string>(); s.Add("{"); s.Add("\t\"creator\": \"unity\","); s.Add("\t\"grease_pencil\":["); s.Add("\t\t{"); s.Add("\t\t\t\"layers\":["); for (int i = 0; i < layerNum; i++) { int currentLayer = i; s.Add("\t\t\t\t{"); { s.Add("\t\t\t\t\t\"name\": \"OpenBrushLayer " + (currentLayer + 1) + "\","); } s.Add(FINAL_LAYER_LIST[currentLayer]); s.Add("\t\t\t\t\t]"); if (currentLayer < layerNum - 1) { s.Add("\t\t\t\t},"); } else { s.Add("\t\t\t\t}"); } } s.Add(" ]"); // end layers s.Add(" }"); s.Add(" ]"); s.Add("}"); if (useZip) { saveJsonAsZip(writeFileName, string.Join("\n", s.ToArray())); } else { File.WriteAllText(writeFileName, string.Join("\n", s.ToArray())); } Debug.Log("*** Wrote " + writeFileName); }
protected override bool IsControlPointReady(PointerManager.ControlPoint controlPoint) { // TODO: API accepts time source function return((controlPoint.m_TimestampMs / 1000F) <= App.Instance.CurrentSketchTime); }