test
This commit is contained in:
111
src/voxelgame/Voxels/UVWrapVisualizer.cs
Normal file
111
src/voxelgame/Voxels/UVWrapVisualizer.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
using Godot;
|
||||
using SJK.Voxels;
|
||||
using System;
|
||||
|
||||
public partial class UVWrapVisualizer : Control
|
||||
{
|
||||
public enum WrapperType
|
||||
{
|
||||
Normal,
|
||||
Twisted
|
||||
}
|
||||
|
||||
[Export] public int WorldSize = 8;
|
||||
[Export] public int ChunkSize = 16;
|
||||
[Export] public int RenderChunks = 4;
|
||||
[Export] public WrapperType WrapMode = WrapperType.Twisted;
|
||||
|
||||
private ImageTexture texture;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
GenerateTexture();
|
||||
}
|
||||
private IWorldWrapper wrapper = new EndlessSizeXZWorld(10);
|
||||
private void GenerateTexture()
|
||||
{
|
||||
int texSize = WorldSize * ChunkSize * RenderChunks;
|
||||
var image = Godot.Image.CreateEmpty(texSize, texSize, false, Image.Format.Rgb8);
|
||||
wrapper = WrapMode switch
|
||||
{
|
||||
WrapperType.Normal => new ToroidalWrapping(Vector3I.One * WorldSize),
|
||||
WrapperType.Twisted => new MirroredZWrappingXOffset(Vector3I.One * WorldSize),
|
||||
_ => throw new Exception(),
|
||||
};
|
||||
GD.Print(wrapper.GetType());
|
||||
for (int gz = 0; gz < texSize; gz++)
|
||||
{
|
||||
for (int gx = 0; gx < texSize; gx++)
|
||||
{
|
||||
Vector2I global = new Vector2I(gx - texSize / 2, gz - texSize / 2); // center origin
|
||||
var v3 = wrapper.Wrap(new Vector3I(global.X, 1, global.Y));
|
||||
Vector2I local = new(v3.X, v3.Z);
|
||||
bool flip = false;
|
||||
|
||||
// switch (WrapMode)
|
||||
// {
|
||||
// case WrapperType.Twisted:
|
||||
// (local, flip) = TwistedWrapInt(global, WorldSize, WorldSize);
|
||||
// break;
|
||||
// default:
|
||||
// local = new Vector2I(Mod(global.X, WorldSize), Mod(global.Y, WorldSize));
|
||||
// flip = false;
|
||||
// break;
|
||||
// }
|
||||
|
||||
// Encode local position into RGB (U and V channels)
|
||||
float u = local.X / (float)WorldSize;
|
||||
float v = local.Y / (float)WorldSize;
|
||||
Color color = new Color(u, v, flip ? 1.0f : 0.0f);
|
||||
image.SetPixel(gx, gz, color);
|
||||
}
|
||||
}
|
||||
|
||||
texture = ImageTexture.CreateFromImage(image);
|
||||
|
||||
QueueRedraw();
|
||||
}
|
||||
|
||||
public override void _Draw()
|
||||
{
|
||||
if (texture != null)
|
||||
{
|
||||
DrawTexture(texture, Vector2.Zero);
|
||||
}
|
||||
}
|
||||
|
||||
// ========== Wrapping Logic ==========
|
||||
|
||||
private (Vector2I local, bool flipped) TwistedWrapInt(Vector2I global, int W, int H)
|
||||
{
|
||||
int gx = global.X;
|
||||
int gy = global.Y;
|
||||
|
||||
int yWrap = FloorDiv(gy, H);
|
||||
bool flip = (yWrap & 1) != 0;
|
||||
|
||||
int tileY = gy % H;
|
||||
if (tileY < 0) tileY += H;
|
||||
int ly = flip ? (H - 1 - tileY) : tileY;
|
||||
|
||||
int xOffset = flip ? W / 2 : 0;
|
||||
int wrappedX = gx + xOffset;
|
||||
|
||||
int tileX = wrappedX % W;
|
||||
if (tileX < 0) tileX += W;
|
||||
int lx = flip ? (W - 1 - tileX) : tileX;
|
||||
|
||||
return (new Vector2I(lx, ly), flip);
|
||||
}
|
||||
|
||||
private int FloorDiv(int a, int b)
|
||||
{
|
||||
return (a >= 0) ? a / b : ((a + 1) / b) - 1;
|
||||
}
|
||||
|
||||
private int Mod(int a, int b)
|
||||
{
|
||||
int r = a % b;
|
||||
return r < 0 ? r + b : r;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user