From 5791171851747947cb2d6a6b3117907657bfb576 Mon Sep 17 00:00:00 2001 From: ZZYZX <zzyzx@virtual> Date: Sun, 4 Feb 2018 06:16:46 +0200 Subject: [PATCH] Added proper spotlight preview in 2D mode --- Source/Core/GZBuilder/Data/LinksCollector.cs | 139 ++++++++++++++++--- 1 file changed, 122 insertions(+), 17 deletions(-) diff --git a/Source/Core/GZBuilder/Data/LinksCollector.cs b/Source/Core/GZBuilder/Data/LinksCollector.cs index 20dea32b7..53e73ca04 100755 --- a/Source/Core/GZBuilder/Data/LinksCollector.cs +++ b/Source/Core/GZBuilder/Data/LinksCollector.cs @@ -527,9 +527,9 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data return lines; } - #endregion + #endregion - #region ================== GetDynamicLightShapes + #region ================== GetDynamicLightShapes public static List<Line3D> GetPointLightShape(Thing t, bool highlight, GZGeneral.LightData ld, int linealpha) { @@ -592,27 +592,132 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data return circles; } + private static Vector3D GetRotatedVertex(Vector3D bp, float angle, float pitch) + { + Vector3D bp_rotated = bp; + bp_rotated.x = bp.x * (float)Math.Cos(pitch) - bp.z * (float)Math.Sin(pitch); + bp_rotated.z = bp.z * (float)Math.Cos(pitch) + bp.x * (float)Math.Sin(pitch); + bp = bp_rotated; + bp_rotated.x = bp.x * (float)Math.Cos(angle) - bp.y * (float)Math.Sin(angle); + bp_rotated.y = bp.y * (float)Math.Cos(angle) + bp.x * (float)Math.Sin(angle); + return bp_rotated; + } + public static List<Line3D> GetSpotLightShape(Thing t, bool highlight, GZGeneral.LightData ld, int linealpha) { + PixelColor color; + if (t.Fields.ContainsKey("arg0str")) + { + ZDoom.ZDTextParser.GetColorFromString(t.Fields["arg0str"].Value.ToString(), out color); + color.a = (byte)linealpha; + } + else color = new PixelColor((byte)linealpha, (byte)((t.Args[0] & 0xFF0000) >> 16), (byte)((t.Args[0] & 0x00FF00) >> 8), (byte)((t.Args[0] & 0x0000FF))); + + if (highlight) + { + color = General.Colors.Highlight.WithAlpha((byte)linealpha); + } + + PixelColor color_secondary = color; + color_secondary.a /= 2; + List<Line3D> shapes = new List<Line3D>(); float lAngle1 = Angle2D.DegToRad(t.Args[1] / 2); float lAngle2 = Angle2D.DegToRad(t.Args[2] / 2); - float lRadius = t.Args[3]; - float lDirY = (float)Math.Sin(-lAngle1) * lRadius; - float lDirX = (float)Math.Cos(-lAngle1) * lRadius; - shapes.Add(new Line3D(new Vector3D(0, 0, 0), new Vector3D(lDirX, lDirY, 0))); - shapes.Add(new Line3D(new Vector3D(0, 0, 0), new Vector3D(lDirX, -lDirY, 0))); + float lRadius = t.Args[3]*2; + float lDirY1 = (float)Math.Sin(-lAngle1) * lRadius; + float lDirX1 = (float)Math.Cos(-lAngle1) * lRadius; + float lDirY2 = (float)Math.Sin(-lAngle2) * lRadius; + float lDirX2 = (float)Math.Cos(-lAngle2) * lRadius; + + IEnumerable<Line3D> circleLines = MakeCircleLines(new Vector3D(0, 0, 0), color, (float)Math.Abs(lDirY1), CIRCLE_SIDES); + foreach (Line3D l3d in circleLines) + { + shapes.Add(new Line3D(new Vector3D(lDirX1, l3d.Start.x, l3d.Start.y), + new Vector3D(lDirX1, l3d.End.x, l3d.End.y), + color, false)); + } + + if (lAngle2 != lAngle1) + { + circleLines = MakeCircleLines(new Vector3D(0, 0, 0), color_secondary, (float)Math.Abs(lDirY2), CIRCLE_SIDES); + foreach (Line3D l3d in circleLines) + { + shapes.Add(new Line3D(new Vector3D(lDirX2, l3d.Start.x, l3d.Start.y), + new Vector3D(lDirX2, l3d.End.x, l3d.End.y), + color_secondary, false)); + } + } + + // draw another circle to show the front cone shape + int numsides = CIRCLE_SIDES * 2; + float anglestep = Angle2D.PI2 / numsides; + for (int j = -1; j <= 1; j++) + { + if (j == 0) continue; + List<Line3D> tmplines = new List<Line3D>(); + PixelColor ccol = color; + for (int i = 1; i < numsides + 1; i++) + { + float angc = j * i * anglestep; + float angp = j * (i - 1) * anglestep; + if (i * anglestep > lAngle1 && ccol.a == color.a) + { + shapes.Add(new Line3D(new Vector3D((float)Math.Cos(angp) * lRadius, (float)Math.Sin(angp) * lRadius, 0), + new Vector3D((float)Math.Cos(j * lAngle1) * lRadius, (float)Math.Sin(j * lAngle1) * lRadius, 0), + ccol, false)); + shapes.Add(new Line3D(new Vector3D((float)Math.Cos(j * lAngle1) * lRadius, (float)Math.Sin(j * lAngle1) * lRadius, 0), + new Vector3D((float)Math.Cos(angc) * lRadius, (float)Math.Sin(angc) * lRadius, 0), + color_secondary, false)); + ccol = color_secondary; + } + else if (i * anglestep > lAngle2) + { + angc = j * lAngle2; + shapes.Add(new Line3D(new Vector3D((float)Math.Cos(angp) * lRadius, (float)Math.Sin(angp) * lRadius, 0), + new Vector3D((float)Math.Cos(angc) * lRadius, (float)Math.Sin(angc) * lRadius, 0), + ccol, false)); + break; + } + else + { + shapes.Add(new Line3D(new Vector3D((float)Math.Cos(angp) * lRadius, (float)Math.Sin(angp) * lRadius, 0), + new Vector3D((float)Math.Cos(angc) * lRadius, (float)Math.Sin(angc) * lRadius, 0), + ccol, false)); + } + } + } + + shapes.Add(new Line3D(new Vector3D(0, 0, 0), new Vector3D(lDirX1, lDirY1, 0), color, false)); + shapes.Add(new Line3D(new Vector3D(0, 0, 0), new Vector3D(lDirX1, -lDirY1, 0), color, false)); + if (lAngle2 != lAngle1) + { + shapes.Add(new Line3D(new Vector3D(0, 0, 0), new Vector3D(lDirX2, lDirY2, 0), color_secondary, false)); + shapes.Add(new Line3D(new Vector3D(0, 0, 0), new Vector3D(lDirX2, -lDirY2, 0), color_secondary, false)); + } + + // do translation and rotation + foreach (Line3D l3d in shapes) + { + // rotate + l3d.Start = GetRotatedVertex(l3d.Start, t.Angle-1.5708f, Angle2D.DegToRad(t.Pitch)); + l3d.End = GetRotatedVertex(l3d.End, t.Angle-1.5708f, Angle2D.DegToRad(t.Pitch)); + // translate + l3d.Start += t.Position; + l3d.End += t.Position; + } + return shapes; } public static List<Line3D> GetDynamicLightShapes(IEnumerable<Thing> things, bool highlight) - { - List<Line3D> circles = new List<Line3D>(); - if(General.Map.DOOM) return circles; + { + List<Line3D> circles = new List<Line3D>(); + if (General.Map.DOOM) return circles; - const int linealpha = 128; - foreach(Thing t in things) - { + const int linealpha = 128; + foreach (Thing t in things) + { GZGeneral.LightData ld = t.DynamicLightType; if (ld == null) continue; @@ -626,11 +731,11 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data List<Line3D> lshape = GetSpotLightShape(t, highlight, ld, linealpha); circles.AddRange(lshape); } - } + } - // Done - return circles; - } + // Done + return circles; + } #endregion -- GitLab