about summary refs log tree commit diff
path: root/Jenny/Commands/ImgCommand.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Jenny/Commands/ImgCommand.cs')
-rw-r--r--Jenny/Commands/ImgCommand.cs134
1 files changed, 134 insertions, 0 deletions
diff --git a/Jenny/Commands/ImgCommand.cs b/Jenny/Commands/ImgCommand.cs
new file mode 100644
index 0000000..9a4ed0c
--- /dev/null
+++ b/Jenny/Commands/ImgCommand.cs
@@ -0,0 +1,134 @@
+using System.Diagnostics;
+using System.Numerics;
+using ArcaneLibs;
+using ArcaneLibs.Extensions;
+using LibMatrix.EventTypes.Spec;
+using LibMatrix.Utilities.Bot.Interfaces;
+
+namespace Jenny.Commands;
+
+public class ImgCommand : ICommand {
+    public string Name { get; } = "img";
+    public string[]? Aliases { get; } = [];
+    public string Description { get; }
+    public bool Unlisted { get; } = true;
+
+    public async Task Invoke(CommandContext ctx) {
+        int count = 1;
+        if (ctx.Args is { Length: 1 })
+            int.TryParse(ctx.Args[0], out count);
+
+        for (var i = 0; i < count; i++) {
+            new Thread(async () => {
+                var bigNoise = GenerateHeightMap(5000, 2000);
+                await ctx.Room.SendMessageEventAsync(new RoomMessageEventContent("m.image", "src_noise.png") {
+                    Url = await ctx.Homeserver.UploadFile("data.png", await Float2DArrayToPng(bigNoise), "image/png"),
+                    FileInfo = new() {
+                        Width = bigNoise.GetWidth(),
+                        Height = bigNoise.GetHeight()
+                    }
+                });
+            }).Start();
+        }
+
+    }
+    
+    public async Task<byte[]> Float2DArrayToPng(float[,] data) {
+        //dump heightmap as PPM
+        Console.WriteLine($"{DateTime.Now} Converting to PNG");
+        var width = data.GetLength(1);
+        var height = data.GetLength(0);
+
+        //convert ppm to png with ffmpeg
+        var process = new Process {
+            StartInfo = new ProcessStartInfo {
+                // FileName = "/nix/store/4hz763c5w2hnzm55ll5vgfgmrr6i9kgg-imagemagick-7.1.1-28/bin/convert",
+                FileName = "convert",
+                Arguments = $"ppm:- png:-",
+                UseShellExecute = false,
+                RedirectStandardInput = true,
+                RedirectStandardOutput = true
+            }
+        };
+        process.Start();
+        await process.StandardInput.WriteLineAsync($"P2\n{width} {height}\n255");
+        for (var i = 0; i < height; i++) {
+            for (var j = 0; j < width; j++) {
+                await process.StandardInput.WriteAsync($"{(int)(data[i, j] * 255)} ");
+            }
+
+            // ppm.AppendLine();
+        }
+        await process.StandardInput.FlushAsync();
+        process.StandardInput.Close();
+        await using var ms = new MemoryStream();
+        await process.StandardOutput.BaseStream.CopyToAsync(ms);
+        ms.Position = 0;
+        Console.WriteLine($"{DateTime.Now} Converted to PNG");
+        return ms.ToArray();
+    }
+
+    public float[,] GenerateHeightMap(int width, int height) {
+        var rnd = new Random();
+
+        var bigNoiseVector3 = new Vector3[height, width];
+        for (var y = 0; y < bigNoiseVector3.GetLength(0); y++) {
+            for (var x = 0; x < bigNoiseVector3.GetLength(1); x++) {
+                bigNoiseVector3[y, x] = new Vector3(0, 0, 0);
+            }
+        }
+
+        bigNoiseVector3[0, 0] = new Vector3(rnd.NextSingle(), rnd.NextSingle(), rnd.NextSingle());
+        var last = bigNoiseVector3[0, 0];
+        for (var y = 0; y < bigNoiseVector3.GetLength(0); y++) {
+            if (y > 0) break;
+            for (var x = 0; x < bigNoiseVector3.GetLength(1); x++) {
+                float currentX = x;
+                float currentY = y;
+                int steps = 0;
+                int maxSteps = 1000;
+                while (steps++ < maxSteps) {
+                    if (currentX < 0) break;
+                    if (currentY < 0) break;
+                    if (currentX > bigNoiseVector3.GetWidth() - 1) break;
+                    if (currentY > bigNoiseVector3.GetHeight() - 1) break;
+
+                    var current = bigNoiseVector3[(int)currentY, (int)currentX];
+                    // if (current is {X: 0f, Y: 0f, Z: 0f}) {
+                    // bigNoiseVector3[currentY, currentX] = current = new Vector3(rnd.NextSingle(), rnd.NextSingle(), rnd.NextSingle());
+                    // }
+
+                    current = new(last.X, last.Y, last.Z);
+                    var diff = new Vector3(
+                        MathUtil.Map(rnd.NextSingle(), 0f, 1f, -0.2f, 0.2f),
+                        MathUtil.Map(rnd.NextSingle(), 0f, 1f, -0.2f, 0.2f),
+                        -0.1f
+                    );
+                    current += diff;
+                    bigNoiseVector3[(int)currentY, (int)currentX] = current;
+
+                    // Console.WriteLine("{0}/{1}={2} (+{3})", currentX, currentY, current, diff);
+                    currentX += current.X;
+                    currentY += current.Y;
+                    
+                    // if (current.X > 0.666f) currentX++;
+                    // else if (current.X < 0.333f) currentX--;
+                    // if (current.Y > 0.666f) currentY++;
+                    // else if (current.Y < 0.333f) currentY--;
+
+                    last = current;
+                }
+            }
+        }
+
+        var bigNoise = new float[height, width];
+        for (var i = 0; i < bigNoise.GetLength(0); i++) {
+            for (var j = 0; j < bigNoise.GetLength(1); j++) {
+                // bigNoise[i, j] = (float) (bigNoiseVector[i, j].Length() / Math.Sqrt(2));
+                bigNoise[i, j] = (float)(bigNoiseVector3[i, j].Z);
+            }
+        }
+
+        return bigNoise;
+    }
+}
\ No newline at end of file