update 0.6.4
This commit is contained in:
@@ -1,82 +1,21 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using XericLibrary.Runtime.Blueprint.Render;
|
||||
using XericLibrary.Runtime.UIGraph;
|
||||
|
||||
namespace XericLibrary.Runtime.Blueprint.QuickGraph
|
||||
{
|
||||
/// <summary>按源节点 Chunk 提交连线的渲染工具;所有局部坐标由基类 submission 提供。</summary>
|
||||
[BlueprintTool(phase: ToolPhase.Render, order: 110)]
|
||||
[BlueprintTheme("QuickGraph")]
|
||||
[BlueprintTool(phase: ToolPhase.Render, order: 110)] [BlueprintTheme("QuickGraph")]
|
||||
public class WireCanvasRenderTool : BlueprintCanvasRenderTool<BlueprintCurveRenderer>
|
||||
{
|
||||
private QuickGraphWireRenderConfig _defaultConfig;
|
||||
private QuickGraphRenderStyleResolver _styleResolver;
|
||||
private int _appliedStyleRevision = -1;
|
||||
private QuickGraphWireRenderConfig Config
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ToolConfig is QuickGraphWireRenderConfig external) return external;
|
||||
if (_defaultConfig == null) _defaultConfig = ScriptableObject.CreateInstance<QuickGraphWireRenderConfig>();
|
||||
return _defaultConfig;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnInitialize()
|
||||
{
|
||||
base.OnInitialize();
|
||||
_styleResolver = new QuickGraphRenderStyleResolver(Graph, wireFallback: ConfigStyle);
|
||||
_styleResolver.Changed += OnStyleChanged;
|
||||
ApplyWireGeometry(_styleResolver.Snapshot.Wire, true);
|
||||
}
|
||||
public override void OnConfigChanged()
|
||||
{
|
||||
_styleResolver?.Refresh();
|
||||
if (_styleResolver == null) ApplyWireGeometry(ConfigStyle(), true);
|
||||
base.OnConfigChanged();
|
||||
}
|
||||
private QuickGraphWireRenderStyle ConfigStyle()
|
||||
{
|
||||
var cfg = Config;
|
||||
return new QuickGraphWireRenderStyle { Width = cfg.WireWidth, HitRadius = cfg.HitTestRadius, SourceHandle = cfg.SourceHandleLength, TargetHandle = cfg.TargetHandleLength, ArrowShape = cfg.ArrowShape, ArrowReversed = cfg.ArrowReversed, ArrowProgress = cfg.ArrowProgress, ArrowWidth = cfg.ArrowWidth, ArrowHeight = cfg.ArrowHeight, ArrowDepth = cfg.ArrowDepthCompensation, Tessellation = cfg.TessellationSegments };
|
||||
}
|
||||
private void OnStyleChanged(QuickGraphRenderStyleSnapshot snapshot)
|
||||
{
|
||||
if ((snapshot.Changes & (QuickGraphRenderStyleChange.WireGeometry | QuickGraphRenderStyleChange.WireAppearance)) == 0) return;
|
||||
ApplyWireGeometry(snapshot.Wire, (snapshot.Changes & QuickGraphRenderStyleChange.WireGeometry) != 0);
|
||||
Graph?.MarkAllElementsDirty();
|
||||
}
|
||||
private void ApplyWireGeometry(QuickGraphWireRenderStyle style, bool force)
|
||||
{
|
||||
if (Graph == null || (!force && _appliedStyleRevision == _styleResolver.Snapshot.Revision)) return;
|
||||
Graph.SetWireGeometrySettings(new BlueprintWireGeometrySettings { SourceHandleLength = style.SourceHandle, TargetHandleLength = style.TargetHandle, WireWidth = style.Width, HitTestRadius = style.HitRadius });
|
||||
foreach (var wire in Graph.Wires) Graph.UpdateWireGeometry(wire);
|
||||
_appliedStyleRevision = _styleResolver != null ? _styleResolver.Snapshot.Revision : _appliedStyleRevision + 1;
|
||||
}
|
||||
|
||||
protected override BlueprintCurveRenderer BuildChunkRenderer(GameObject chunkGo) => chunkGo.AddComponent<BlueprintCurveRenderer>();
|
||||
protected override void ClearChunkData(BlueprintCurveRenderer renderer) => renderer.ClearAll();
|
||||
protected override void SetChunkDirty(BlueprintCurveRenderer renderer) => renderer.RebuildAll();
|
||||
protected override bool AcceptsElement(IBlueprintElement element) => element is BlueprintWire;
|
||||
protected override void AppendElementData(BlueprintCurveRenderer renderer, IBlueprintElement element, ulong chunkID)
|
||||
{
|
||||
if (!(element is BlueprintWire wire) || wire.SourcePort == null || wire.TargetPort == null || wire.SourcePort.OwnerNode == null || wire.TargetPort.OwnerNode == null) return;
|
||||
var style = _styleResolver != null ? _styleResolver.Snapshot.Wire : ConfigStyle();
|
||||
wire.GetControlPoints(out var startCanvas, out var handle1Canvas, out var handle2Canvas, out var endCanvas);
|
||||
var submission = CurrentElementSubmission;
|
||||
var ctrlPts = new[] { submission.ToChunkLocal(startCanvas), submission.ToChunkLocal(handle1Canvas), submission.ToChunkLocal(handle2Canvas), submission.ToChunkLocal(endCanvas) };
|
||||
var widths = new[] { style.Width, style.Width, style.Width, style.Width };
|
||||
Color32 srcColor = wire.SourcePort.OwnerNode.NodeColor;
|
||||
Color32 tgtColor = wire.TargetPort.OwnerNode.NodeColor;
|
||||
var arrow = new ArrowHeadData { shape = style.ArrowShape, reversed = style.ArrowReversed, progress = style.ArrowProgress, width = style.ArrowWidth, height = style.ArrowHeight, depthCompensation = style.ArrowDepth, color = tgtColor };
|
||||
var entry = new CurveCacheEntry { startColor = srcColor, endColor = tgtColor, tessellationSegments = Mathf.Max(2, Mathf.RoundToInt(style.Tessellation * Graph.CurrentLodSettings.WireTessellationMultiplier)) };
|
||||
renderer.AddCurve(entry, ctrlPts, widths, new[] { arrow });
|
||||
}
|
||||
public override void OnDestroy()
|
||||
{
|
||||
if (_styleResolver != null) _styleResolver.Changed -= OnStyleChanged;
|
||||
_styleResolver?.Dispose(); _styleResolver = null;
|
||||
base.OnDestroy();
|
||||
}
|
||||
private QuickGraphRenderStyleResolver _styles; private int _revision = -1;
|
||||
private readonly HashSet<string> _invalidWireWarningLogged = new HashSet<string>();
|
||||
public override void OnInitialize() { base.OnInitialize(); _styles = new QuickGraphRenderStyleResolver(Graph); _styles.Changed += OnStyleChanged; ApplyGeometry(_styles.Snapshot.Wire, true); }
|
||||
public override void OnConfigChanged() => _styles?.Refresh();
|
||||
private void OnStyleChanged(QuickGraphRenderStyleSnapshot snapshot) { ApplyGeometry(snapshot.Wire, true); Graph?.MarkAllElementsDirty(); }
|
||||
private void ApplyGeometry(QuickGraphWireRenderStyle style, bool force) { if (Graph == null || (!force && _revision == _styles.Snapshot.Revision)) return; Graph.SetWireGeometrySettings(new BlueprintWireGeometrySettings { SourceHandleLength = style.SourceHandle, TargetHandleLength = style.TargetHandle, WireWidth = style.Width, HitTestRadius = style.HitRadius }); foreach (var wire in Graph.Wires) Graph.UpdateWireGeometry(wire); _revision = _styles.Snapshot.Revision; }
|
||||
protected override BlueprintCurveRenderer BuildChunkRenderer(GameObject go) => go.AddComponent<BlueprintCurveRenderer>(); protected override void ClearChunkData(BlueprintCurveRenderer renderer) => renderer.ClearAll(); protected override void SetChunkDirty(BlueprintCurveRenderer renderer) => renderer.RebuildAll(); protected override bool AcceptsElement(IBlueprintElement element) => element is BlueprintWire;
|
||||
protected override void AppendElementData(BlueprintCurveRenderer renderer, IBlueprintElement element, ulong chunkID) { if (!(element is BlueprintWire wire)) return; if (wire.SourcePort == null || wire.TargetPort == null || wire.SourcePort.OwnerNode == null || wire.TargetPort.OwnerNode == null) { ReportInvalidWire(wire); return; } var style = _styles.Snapshot.Wire; wire.GetControlPoints(out var a, out var b, out var c, out var d); var submit = CurrentElementSubmission; var points = new[] { submit.ToChunkLocal(a), submit.ToChunkLocal(b), submit.ToChunkLocal(c), submit.ToChunkLocal(d) }; Color32 src = style.UseNodeColorGradient ? wire.SourcePort.OwnerNode.NodeColor : style.Color; Color32 dst = style.UseNodeColorGradient ? wire.TargetPort.OwnerNode.NodeColor : style.Color; var arrow = new ArrowHeadData { shape = style.ArrowShape, reversed = style.ArrowReversed, progress = style.ArrowProgress, width = style.ArrowWidth, height = style.ArrowHeight, depthCompensation = style.ArrowDepth, color = dst }; renderer.AddCurve(new CurveCacheEntry { startColor = src, endColor = dst, tessellationSegments = Mathf.RoundToInt(style.Tessellation * Graph.CurrentLodSettings.WireTessellationMultiplier) }, points, new[] { style.Width, style.Width, style.Width, style.Width }, new[] { arrow }); }
|
||||
private void ReportInvalidWire(BlueprintWire wire) { if (!_invalidWireWarningLogged.Add(wire.ElementId)) return; var missing = new List<string>(); if (wire.SourcePort == null) missing.Add("SourcePort"); else if (wire.SourcePort.OwnerNode == null) missing.Add("SourcePort.OwnerNode"); if (wire.TargetPort == null) missing.Add("TargetPort"); else if (wire.TargetPort.OwnerNode == null) missing.Add("TargetPort.OwnerNode"); Debug.LogWarning($"[WireCanvasRenderTool] 跳过无效 wire: GraphId={Graph.GraphId}, WireId={wire.ElementId}, missing={string.Join(", ", missing)}。"); }
|
||||
public override void OnDestroy() { if (_styles != null) _styles.Changed -= OnStyleChanged; _styles?.Dispose(); _styles = null; _invalidWireWarningLogged.Clear(); base.OnDestroy(); }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user