Adjusting texture generation inside a quadtree
Well, I'm trying to adjust the position of generated textures using this approach.
I replicated this in Unity3D for a complete texture of 4096x4096:
The point is that I need to generate the same texture on a quadtree using different level of details / zoom per each node.
I have almost the code finished, but I cannot calibrate textures inside the grid/nodes:
With grid:
The point is that I'm unsure at which point of the code execution, I have two main parts that I doubt about.
The first one is on the OnGUI()
call, read comments FMI.
private void OnGUI()
{
// Skipped logic
var totalTimeExecution = DrawBiomeTextureLogic();
// Skipped logic
}
private long DrawBiomeTextureLogic()
{
var octreeKey = world.worldSettings.TargetOctreeKey;
var regions = world.worldState.ChunkData.Get_Regions();
if (!regions.ContainsKey(octreeKey))
return -1;
var region = regions[octreeKey];
// will draw the smaller ones first (Depth = 0, 2^0=1 * textureSize)
// but we draw everything as 16x16 because we are doing a level of detail with textures
var map = region.NodeMap.AsEnumerable().OrderByDescending(x => x.Value.Depth);
foreach (var (key, octree) in map)
{
// fields from the octree node
var position = octree.Position;
var depth = octree.Depth;
var mult = 1 << depth;
// first intPosition, needs to refactgor
var size = world.worldSettings.ChunkSize * mult;
var intPosition = new Vector2Int(position.x - size / 2, position.y - size / 2);
DrawTexture(octree);
}
return totalTimeExecution;
}
private void DrawTexture(OctreeNode octree)
{
// fields from the octree node
// note: I say quadtree on the question, but because I'm skipping z axis values with a HashSet,
// I will create another question to create another algorithm for it
var position = octree.Position;
var key = octree.LocCode;
var depth = octree.Depth;
var mult = 1 << depth;
var size = world.worldSettings.ChunkSize * mult;
// use Y position because we need a bird view of the map (edit: but i need)
// the problem could be here
var intPosition = new Vector2Int(position.x - size / 2, position.y - size / 2);
var targetPosition = new long2(intPosition.x, intPosition.y);
// or maybe, but this is for adjusting inside scroll view
var texRect = new Rect(intPosition.x, -intPosition.y - MAP_SIZE_HEIGHT, size, size);
// pass targetPosition into second stage
TextureSettings.InitializeTextureParams(targetPosition, depth, key);
// Get the texture from the biomeTextureController
var texture = biomeTextureController.GetTexture(TextureSettings, out var textureTask);
if (texture != null)
{
Textures.TryAdd(new Vector2Int(intPosition.x, -intPosition.y), (texture, size));
}
var color = texture != null ? Color.green : Color.red;
if (texture != null)
{
GUI.DrawTexture(texRect, texture);
// not relevant
UIUtils.DrawOutlinedRect(texRect, color, 1);
}
}
The second stage mentioned in code (line 59), is the Job (Unity Jobs) that I use, I did it parallel with bounds checking for index
and the mentioned document from Cuberite above, the call is explained here:
[BurstCompile(OptimizeFor = OptimizeFor.Performance)]
public struct BiomeTextureParallelJob : IJobParallelFor, IDisposable
{
// colors of the texture
public NativeArray<Color32> data;
// used to get Biome color depending on its index (enumeration)
[ReadOnly]
public NativeParallelHashMap<short, Color> colorsCollection;
public BiomeGenenerationSettings settings;
public BiomeTextureJobSettings jobSettings;
public long2 TargetPosition => jobSettings.TargetPosition;
public int Depth => jobSettings.Depth;
public int TextureSize => jobSettings.textureSize;
public void Execute(int index)
{
OnStart();
To2D(index, TextureSize, out var x, out var y);
if (showPercentage)
counter[threadIndex]++;
// same octree fields calculated again
var d = 1 << (Depth + 4);
var p = d / TextureSize; // example: 64 / 16 = 4
var s = TextureSize * (1 << Depth); // textureSize multiplied by its 2^n node size
// maybe the problem start here
// this is from the first stage
var tx = TargetPosition.x;
var ty = TargetPosition.y;
// I tried some operations, but I'm unable to adjust it
var xx = x * p; // - p / 2; // * (tx < 0 ? -1 : 1); // + p / 2;
var yy = y * p; // - p / 2; // * (ty < 0 ? -1 : 1); // + p / 2;
long wx = tx + xx - s / 2; // * (tx < 0 ? -1 : 1);
long wy = ty + yy - s / 2; // * (ty < 0 ? -1 : 1);
if (!IsInBounds(index, data.Length))
return;
data[index] =
BiomeTextureUtils.CalcPixelColor(settings, colorsCollection, wx, wy, 1,
false, AlphaChannel);
}
[BurstDiscard]
public void Dispose()
{
try
{
if (data.IsCreated)
data.Dispose();
}
catch { }
}
}
As you can see the problem could be found in two places. It could be some simple, as you can see on UI, more zoomed:
I'd like to share a demo with the minimum code, I'll prepare one if needed.
Note: I'd like to add a spoiler to hide such big images. I'm sorry.