private static void AnglesToArcs(CornerRounderContext context) { PrepareRadiusInfo(context); CornerRounderConfig config = context.config; RadiusStrategy strategy = config.radiusStrategy; if (strategy == RadiusStrategy.Never) { return; } LinkedList <CornerInfo> cornerInfo = context.cornerInfo; LinkedListNode <CornerInfo> current = cornerInfo.First; while (current != null) { if (current.Previous != null && current.Next != null) { CornerInfo c0 = current.Previous.Value; CornerInfo c1 = current.Value; CornerInfo c2 = current.Next.Value; Vector3 p0 = c0.vertex; Vector3 p1 = c1.vertex; Vector3 p2 = c2.vertex; float radius = c1.radiusAdjusted; if (radius != 0) { float halfAngle = c1.angle * 0.5f; float tan = Mathf.Tan(halfAngle); float cutLen = radius / tan; // 截断点 Vector3 cut1 = p1 + (p0 - p1).normalized * cutLen; Vector3 cut2 = p1 + (p2 - p1).normalized * cutLen; // 顶点到圆心距离 float vertexToCenter = radius / Mathf.Sin(halfAngle); // 圆心 Vector3 center = ((cut1 - p1) + (cut2 - p1)).normalized * vertexToCenter + p1; CornerInfo value = current.Value; CornerInfo.Round(ref value, center, cut1, cut2); current.Value = value; } } current = current.Next; } }
public void CalculateFOV(int startx, int starty, float force, float decay, RadiusStrategy rStrat) { m_StartX = startx; m_StartY = starty; m_Force = force; m_Decay = decay; m_RadiusStrategy = rStrat; m_Radius = (force / decay); m_Board.Visit(startx, starty); foreach (Direction d in Direction.DIAGONALS) { CastLight(1, 1.0f, 0.0f, 0, d.m_DeltaX, d.m_DeltaY, 0); CastLight(1, 1.0f, 0.0f, d.m_DeltaX, 0, 0, d.m_DeltaY); } }
private static void PrepareRadiusInfo(CornerRounderContext context) { CornerRounderConfig config = context.config; RadiusStrategy strategy = config.radiusStrategy; if (strategy == RadiusStrategy.Never) { return; } LinkedList <CornerInfo> cornerInfo = context.cornerInfo; LinkedListNode <CornerInfo> current = cornerInfo.First; while (current != null) { if (current.Previous != null && current.Next != null) { CornerInfo info = current.Value; float angle = MathUtils.Angle(current.Previous.Value, current.Value, current.Next.Value); info.angle = angle; switch (strategy) { case RadiusStrategy.Unified: info.radiusExpected = config.radiusTarget; break; case RadiusStrategy.Adaptive: info.radiusExpected = Mathf.Lerp(config.radiusMin, config.radiusMax, angle / 3.14f); break; } current.Value = info; } current = current.Next; } // 重置 再循环一遍 current = cornerInfo.First; while (current != null) { if (current.Previous != null && current.Next != null) { CornerInfo c0 = current.Previous.Value; CornerInfo c1 = current.Value; CornerInfo c2 = current.Next.Value; bool previousIsDirty = RadiusAdjust(ref c0, ref c1, ref c2); current.Previous.Value = c0; current.Value = c1; current.Next.Value = c2; if (previousIsDirty) { current = current.Previous; } } current = current.Next; } }