public virtual void AfterStroke(PlaytimePainter pntr, BrushConfig br, StrokeVector st) { pntr.AfterStroke(st); if (!br.IsSingleBufferBrush() && !br.IsA3Dbrush(pntr)) { TexMGMT.UpdateBufferSegment(); } if ((br.useMask) && (st.mouseUp) && (br.randomMaskOffset)) { br.maskOffset = new Vector2(UnityEngine.Random.Range(0f, 1f), UnityEngine.Random.Range(0f, 1f)); } foreach (var p in pntr.plugins) { p.AfterGPUStroke(pntr, br, st, this); } }
public override void PaintRenderTexture(PlaytimePainter pntr, BrushConfig br, StrokeVector st) { BeforeStroke(pntr, br, st); ImageData id = pntr.ImgData; if ((st.firstStroke) || (br.decalContinious)) { if (br.decalRotationMethod == DecalRotationMethod.StrokeDirection) { Vector2 delta = st.uvTo - previousUV; // if ((st.firstStroke) || (delta.magnitude*id.width > br.Size(false)*0.25f)) { float portion = Mathf.Clamp01(delta.magnitude * id.width * 4 / br.Size(false)); float newAngle = Vector2.SignedAngle(Vector2.up, delta) + br.decalAngleModifier; br.decalAngle = Mathf.LerpAngle(br.decalAngle, newAngle, portion); previousUV = st.uvTo; //} } if (TexMGMT.BigRT_pair == null) { TexMGMT.UpdateBuffersState(); } TexMGMT.ShaderPrepareStroke(br, 1, id, st, pntr); Transform tf = Rtbrush; tf.localScale = Vector3.one * br.Size(false); tf.localRotation = Quaternion.Euler(new Vector3(0, 0, br.decalAngle)); BrushMesh = brushMeshGenerator.inst().GetQuad(); st.uvTo = st.uvTo.To01Space(); Vector2 deltauv = st.Delta_uv; /* * * int strokes = Mathf.Max(1, (br.decalContinious && (!st.firstStroke)) ? (int)(deltauv.magnitude*id.width/br.Size(false)) : 1); * * deltauv /= strokes; * * for (int i = 0; i < strokes; i++) { * st.uvFrom += deltauv;*/ Vector2 uv = st.uvTo; if ((br.decalRotationMethod == DecalRotationMethod.StrokeDirection) && (!st.firstStroke)) { float length = Mathf.Max(deltauv.magnitude * 2 * id.width / br.Size(false), 1); Vector3 scale = tf.localScale; if ((Mathf.Abs(Mathf.Abs(br.decalAngleModifier) - 90)) < 40) { scale.x *= length; } else { scale.y *= length; } tf.localScale = scale; uv -= deltauv * ((length - 1) * 0.5f / length); } tf.localPosition = StrokeVector.BrushWorldPositionFrom(uv); TexMGMT.Render(); AfterStroke(pntr, br, st); } else { pntr.AfterStroke(st); } }
public virtual void PaintToTexture2D(PlaytimePainter pntr, BrushConfig br, StrokeVector st) { Vector2 delta_uv = st.uvTo - st.uvFrom; if (delta_uv.magnitude > (0.2f + st.avgBrushSpeed * 3)) { delta_uv = Vector2.zero; // This is made to avoid glitch strokes on seams } else { st.avgBrushSpeed = (st.avgBrushSpeed + delta_uv.magnitude) / 2; } float alpha = Mathf.Clamp01(br.speed * (Application.isPlaying ? Time.deltaTime : 0.1f)); bool worldSpace = pntr.NeedsGrid(); var id = pntr.ImgData; float uvDist = (delta_uv.magnitude * id.width * 8 / br.Size(false)); float worldDist = st.Delta_WorldPos.magnitude; float steps = (int)Mathf.Max(1, worldSpace ? worldDist : uvDist); delta_uv /= steps; Vector3 deltaPos = st.Delta_WorldPos / steps; st.uvFrom += delta_uv; st.posFrom += deltaPos; Blit_Functions.PaintTexture2DMethod pluginBlit = null; if (pluginBlit == null && tex2DPaintPlugins != null) { foreach (Blit_Functions.PaintTexture2DMethod p in tex2DPaintPlugins.GetInvocationList()) { if (p(st, alpha, id, br, pntr)) { pluginBlit = p; break; } } } if (pluginBlit == null) { pluginBlit = Blit_Functions.Paint; pluginBlit(st, alpha, id, br, pntr); } for (float i = 1; i < steps; i++) { st.uvFrom += delta_uv; st.posFrom += deltaPos; pluginBlit(st, alpha, id, br, pntr); } pntr.AfterStroke(st); }