You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
2.9 KiB
C#
91 lines
2.9 KiB
C#
1 year ago
|
using RPiRgbLEDMatrix;
|
||
|
using System.Numerics;
|
||
|
|
||
|
const float MaxModuleSpeed = 0.1f;
|
||
|
const float FOV = 60f;
|
||
|
const float Scale = 1.1f;
|
||
|
const float LerpPow = 0.002f;
|
||
|
const int ChangePerFrames = 50;
|
||
|
|
||
|
using var leds = new RGBLedMatrix(32, 1, 1);
|
||
|
var canvas = leds.CreateOffscreenCanvas();
|
||
|
|
||
|
var (centerX, centerY) = (canvas.Width / 2, canvas.Height / 2);
|
||
|
|
||
|
var rnd = new Random();
|
||
|
var angleSpeed = new Vector3();
|
||
|
var nextAngleSpeed = new Vector3();
|
||
|
var frame = -1;
|
||
|
|
||
|
var rotateMatrix = Matrix4x4.Identity;
|
||
|
var scaleMatrix = Matrix4x4.CreateScale(Scale);
|
||
|
var projectMatrix = Matrix4x4.CreatePerspectiveFieldOfView(FOV / 180 * MathF.PI, 1, 0.1f, 100f);
|
||
|
var cameraMatrix = Matrix4x4.CreateLookAt(new(0, 0, 4), new(0, 0, 0), new(0, 1, 0));
|
||
|
|
||
|
// run until user presses Ctrl+C
|
||
|
var running = true;
|
||
|
Console.CancelKeyPress += (_, e) =>
|
||
|
{
|
||
|
running = false;
|
||
|
e.Cancel = true; // do not terminate program with Ctrl+C, we need to dispose
|
||
|
};
|
||
|
while (running)
|
||
|
{
|
||
|
var frameStart = Environment.TickCount64;
|
||
|
|
||
|
// update angle speed
|
||
|
frame = (frame + 1) % ChangePerFrames;
|
||
|
if(frame == 0)
|
||
|
nextAngleSpeed = new Vector3(
|
||
|
(rnd.NextSingle() * 2 - 1) * MaxModuleSpeed,
|
||
|
(rnd.NextSingle() * 2 - 1) * MaxModuleSpeed,
|
||
|
(rnd.NextSingle() * 2 - 1) * MaxModuleSpeed
|
||
|
);
|
||
|
|
||
|
angleSpeed = Vector3.Lerp(angleSpeed, nextAngleSpeed, LerpPow);
|
||
|
|
||
|
// update matrices
|
||
|
rotateMatrix *= Matrix4x4.CreateRotationX(angleSpeed.X);
|
||
|
rotateMatrix *= Matrix4x4.CreateRotationY(angleSpeed.Y);
|
||
|
rotateMatrix *= Matrix4x4.CreateRotationZ(angleSpeed.Z);
|
||
|
var matrix = scaleMatrix * rotateMatrix * cameraMatrix * projectMatrix;
|
||
|
|
||
|
// calculate points
|
||
|
var top1 = Vector4.Transform(new Vector3( 1, 1, 1), matrix);
|
||
|
var top2 = Vector4.Transform(new Vector3(-1, 1, 1), matrix);
|
||
|
var top3 = Vector4.Transform(new Vector3(-1, 1, -1), matrix);
|
||
|
var top4 = Vector4.Transform(new Vector3( 1, 1, -1), matrix);
|
||
|
|
||
|
var bot1 = Vector4.Transform(new Vector3( 1, -1, 1), matrix);
|
||
|
var bot2 = Vector4.Transform(new Vector3(-1, -1, 1), matrix);
|
||
|
var bot3 = Vector4.Transform(new Vector3(-1, -1, -1), matrix);
|
||
|
var bot4 = Vector4.Transform(new Vector3( 1, -1, -1), matrix);
|
||
|
|
||
|
// draw
|
||
|
canvas.Fill(new(0, 0, 0));
|
||
|
DrawLine(top1, top2);
|
||
|
DrawLine(top2, top3);
|
||
|
DrawLine(top3, top4);
|
||
|
DrawLine(top4, top1);
|
||
|
|
||
|
DrawLine(bot1, bot2);
|
||
|
DrawLine(bot2, bot3);
|
||
|
DrawLine(bot3, bot4);
|
||
|
DrawLine(bot4, bot1);
|
||
|
|
||
|
DrawLine(top1, bot1);
|
||
|
DrawLine(top2, bot2);
|
||
|
DrawLine(top3, bot3);
|
||
|
DrawLine(top4, bot4);
|
||
|
|
||
|
leds.SwapOnVsync(canvas);
|
||
|
// force 30 FPS
|
||
|
var elapsed = Environment.TickCount64 - frameStart;
|
||
|
if (elapsed < 33) Thread.Sleep(33 - (int)elapsed);
|
||
|
}
|
||
|
|
||
|
void DrawLine(Vector4 a, Vector4 b) => canvas.DrawLine(
|
||
|
(int)(a.X * a.W + centerX), (int)(a.Y * a.W + centerY),
|
||
|
(int)(b.X * b.W + centerX), (int)(b.Y * b.W + centerY),
|
||
|
new(255, 255, 255));
|