-
Notifications
You must be signed in to change notification settings - Fork 191
Expand file tree
/
Copy pathRadBeamRenderable.cs
More file actions
90 lines (72 loc) · 3.01 KB
/
RadBeamRenderable.cs
File metadata and controls
90 lines (72 loc) · 3.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using OpenRA.Graphics;
using OpenRA.Primitives;
namespace OpenRA.Mods.RA2.Graphics
{
public readonly struct RadBeamRenderable : IRenderable, IFinalizedRenderable
{
readonly WVec sourceToTarget;
readonly WDist width;
readonly Color color;
readonly WDist amplitude;
readonly WDist wavelength;
readonly int quantizationCount;
public RadBeamRenderable(WPos pos, int zOffset, WVec sourceToTarget, WDist width, Color color, WDist amplitude, WDist wavelength, int quantizationCount)
{
Pos = pos;
ZOffset = zOffset;
this.sourceToTarget = sourceToTarget;
this.width = width;
this.color = color;
this.amplitude = amplitude;
this.wavelength = wavelength;
this.quantizationCount = quantizationCount;
}
public WPos Pos { get; }
public PaletteReference Palette => null;
public int ZOffset { get; }
public bool IsDecoration => true;
public IRenderable WithZOffset(int newOffset) => new RadBeamRenderable(Pos, ZOffset, sourceToTarget, width, color, amplitude, wavelength, quantizationCount);
public IRenderable OffsetBy(in WVec vec) => new RadBeamRenderable(Pos + vec, ZOffset, sourceToTarget, width, color, amplitude, wavelength, quantizationCount);
public IRenderable AsDecoration() => this;
public IFinalizedRenderable PrepareRender(WorldRenderer wr) => this;
public void Render(WorldRenderer wr)
{
if (sourceToTarget == WVec.Zero)
return;
// WAngle.Sin(x) = 1024 * Math.Sin(2pi/1024 * x)
// forward step, pointing from src to target.
// QuantizationCont * forwardStep == One cycle of beam in src2target direction.
var forwardStep = wavelength.Length * sourceToTarget / (quantizationCount * sourceToTarget.Length);
var cycleCount = sourceToTarget.Length / wavelength.Length;
if (sourceToTarget.Length % wavelength.Length != 0)
cycleCount++; // I'm emulating Math.Ceil
var screenWidth = wr.ScreenVector(new WVec(width, WDist.Zero, WDist.Zero))[0];
var angle = new WAngle(0);
var angleStep = new WAngle(1024 / quantizationCount);
// last point the rad beam "reached"
var pos = Pos; // where we are
var last = wr.Screen3DPosition(pos); // we start from the shooter
for (var i = 0; i < cycleCount * quantizationCount; i++)
{
var y = new WVec(0, 0, amplitude.Length * angle.Sin() / 1024);
var end = wr.Screen3DPosition(pos + y);
Game.Renderer.WorldRgbaColorRenderer.DrawLine(last, end, screenWidth, color);
pos += forwardStep; // keep moving along x axis
last = end;
angle += angleStep;
}
}
public void RenderDebugGeometry(WorldRenderer wr) { }
public Rectangle ScreenBounds(WorldRenderer wr) => Rectangle.Empty;
}
}