/// Duplicates a stroke. Duplicated strokes have a timestamp that corresponds to the current time. public Stroke DuplicateStroke(Stroke srcStroke, CanvasScript canvas, TrTransform?transform) { Stroke duplicate = new Stroke(srcStroke); if (srcStroke.m_Type == Stroke.Type.BatchedBrushStroke) { if (transform == null) { duplicate.CopyGeometry(canvas, srcStroke); } else { // If this fires, consider adding transform support to CreateGeometryByCopying Debug.LogWarning("Unexpected: Taking slow DuplicateStroke path"); duplicate.Recreate(transform, canvas); } } else { duplicate.Recreate(transform, canvas); } UpdateTimestampsToCurrentSketchTime(duplicate); MemoryListAdd(duplicate); return(duplicate); }
protected override void OnRedo() { AudioManager.m_Instance.PlayRedoSound(CommandAudioPosition); switch (m_Stroke.m_Type) { case Stroke.Type.BrushStroke: { GameObject gameObj = m_Stroke.m_Object; if (gameObj) { BaseBrushScript rBrushScript = gameObj.GetComponent<BaseBrushScript>(); if (rBrushScript) { rBrushScript.HideBrush(false); } } break; } case Stroke.Type.BatchedBrushStroke: { var batch = m_Stroke.m_BatchSubset.m_ParentBatch; batch.EnableSubset(m_Stroke.m_BatchSubset); break; } case Stroke.Type.NotCreated: Debug.LogError("Unexpected: redo NotCreated stroke"); m_Stroke.Recreate(); break; } if (m_Widget != null) { m_Widget.AdjustLift(m_LineLength_CS); } TiltMeterScript.m_Instance.AdjustMeter(m_Stroke, up: true); }
private static void SanityCheckVersusReplacementBrush(Stroke oldStroke) { BrushDescriptor desc = BrushCatalog.m_Instance.GetBrush(oldStroke.m_BrushGuid); BrushDescriptor replacementDesc = desc.m_Supersedes; if (replacementDesc == null) { return; } // Make a copy, since Begin/EndLineFromMemory mutate little bits of MemoryBrushStroke Stroke newStroke = new Stroke { m_BrushGuid = replacementDesc.m_Guid, m_IntendedCanvas = oldStroke.Canvas, m_ControlPoints = oldStroke.m_ControlPoints, m_BrushScale = oldStroke.m_BrushScale, m_BrushSize = oldStroke.m_BrushSize, m_Color = oldStroke.m_Color, m_Seed = oldStroke.m_Seed }; Array.Copy(oldStroke.m_ControlPointsToDrop, newStroke.m_ControlPointsToDrop, oldStroke.m_ControlPointsToDrop.Length); newStroke.Recreate(TrTransform.T(new Vector3(0.5f, 0, 0))); }
private void ApplyColorAndBrushToObject(Color color, Guid brushGuid) { m_TargetStroke.m_Color = ColorPickerUtils.ClampLuminance( color, BrushCatalog.m_Instance.GetBrush(brushGuid).m_ColorLuminanceMin); m_TargetStroke.m_BrushGuid = brushGuid; m_TargetStroke.InvalidateCopy(); m_TargetStroke.Uncreate(); m_TargetStroke.Recreate(); }
public static void MultiPositionPathsToStrokes(List <List <Vector3> > positions, List <List <Quaternion> > orientations, List <List <float> > pressures, Vector3 origin, float scale = 1f, bool breakOnOrigin = false, bool rawStrokes = false) { var brush = PointerManager.m_Instance.MainPointer.CurrentBrush; uint time = 0; float minPressure = PointerManager.m_Instance.MainPointer.CurrentBrush.PressureSizeMin(false); float defaultPressure = Mathf.Lerp(minPressure, 1f, 0.5f); var group = App.GroupManager.NewUnusedGroup(); for (var pathIndex = 0; pathIndex < positions.Count; pathIndex++) { // Single joined paths var positionList = positions[pathIndex]; if (positionList.Count < 2) { continue; } float lineLength = 0; var controlPoints = new List <PointerManager.ControlPoint>(); for (var vertexIndex = 0; vertexIndex < positionList.Count - 1; vertexIndex++) { var position = positionList[vertexIndex]; Quaternion orientation = orientations?.Any() == true ? orientations[pathIndex][vertexIndex] : Quaternion.identity; float pressure = pressures?.Any() == true ? pressures[pathIndex][vertexIndex] : defaultPressure; var nextPosition = positionList[(vertexIndex + 1) % positionList.Count]; // Fix for trailing zeros from SVG. // TODO Find out why and fix it properly if (breakOnOrigin && nextPosition == Vector3.zero) { break; } if (rawStrokes) { controlPoints.Add(new PointerManager.ControlPoint() { m_Pos = position, m_Orient = orientation, m_Pressure = pressure, m_TimestampMs = time++ }); } else { // Create extra control points if needed // Procedural strokes need to have extra control points added to avoid being smoothed out. for (float step = 0; step <= 1f; step += 0.25f) { controlPoints.Add(new PointerManager.ControlPoint { m_Pos = (position + (nextPosition - position) * step) * scale + origin, m_Orient = orientation, m_Pressure = pressure, m_TimestampMs = time++ }); } } lineLength += (nextPosition - position).magnitude; // TODO Does this need scaling? Should be in Canvas space } var stroke = new Stroke { m_Type = Stroke.Type.NotCreated, m_IntendedCanvas = App.Scene.ActiveCanvas, m_BrushGuid = brush.m_Guid, m_BrushScale = 1f, m_BrushSize = PointerManager.m_Instance.MainPointer.BrushSizeAbsolute, m_Color = App.BrushColor.CurrentColor, m_Seed = 0, m_ControlPoints = controlPoints.ToArray(), }; stroke.m_ControlPointsToDrop = Enumerable.Repeat(false, stroke.m_ControlPoints.Length).ToArray(); stroke.Group = @group; stroke.Recreate(null, App.Scene.ActiveCanvas); if (pathIndex != 0) { stroke.m_Flags = SketchMemoryScript.StrokeFlags.IsGroupContinue; } SketchMemoryScript.m_Instance.MemoryListAdd(stroke); SketchMemoryScript.m_Instance.PerformAndRecordCommand( new BrushStrokeCommand(stroke, WidgetManager.m_Instance.ActiveStencil, 123) // TODO calc length ); } }