Skip to content

Instantly share code, notes, and snippets.

@xshazwar
Last active August 12, 2021 16:17
Show Gist options
  • Save xshazwar/91a6b0478d75964aabcae9ecfdd11919 to your computer and use it in GitHub Desktop.
Save xshazwar/91a6b0478d75964aabcae9ecfdd11919 to your computer and use it in GitHub Desktop.
MapMagic2 Custom Generator Node
using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using Den.Tools;
using Den.Tools.GUI;
using Den.Tools.Matrices;
using MapMagic.Products;
using MapMagic.Nodes;
using UnityEngine;
[Serializable]
[GeneratorMenu(
menu = "Geometric Generators",
name = "Sine",
colorType = typeof(MatrixWorld))]
public class MyGenerator : Generator, IOutlet<MatrixWorld>
{
[Val("Offset")] public Vector2D offset;
[Val("Skew")] public Vector2D skew;
[Val("Radius")] public int period = 2000;
#if UNITY_EDITOR
[UnityEditor.InitializeOnLoadMethod]
static void EnlistInMenu () => MapMagic.Nodes.GUI.CreateRightClick.generatorTypes.Add(typeof(MyGenerator));
#endif
private float Sine(float x, float z, float skew_x, float skew_z, float period)
{
// rectify the wave between 0 -> 1 (halve and offset)
return 0.5f * Mathf.Sin(
Mathf.Sqrt(
(x * x * skew_x) + (z * z * skew_z)
) * 2 * Mathf.PI / period
) + 0.5f;
}
private float[] ValuesParallel(int res, float x_off, float z_off, float stepRatio, float period, float skew_x, float skew_z)
{
float[] output = new float[res * res];
Parallel.ForEach(Partitioner.Create(0, (res * res)),
(range) => {
int x = 0;
int z = 0;
for (int i = range.Item1; i < range.Item2; i++)
{
x = i % res;
z = (i - x) / res;
output[i] = Sine(
(x * stepRatio) + x_off,
(z * stepRatio) + z_off,
skew_x,
skew_z,
period
);
}
}
);
return output;
}
public override void Generate(TileData data, StopToken stop)
{
if (stop != null && stop.stop) return;
MatrixWorld dst = new MatrixWorld(data.area.full.rect, data.area.full.worldPos, data.area.full.worldSize, data.globals.height);
if (stop != null && stop.stop) return;
// The draft tiles have a different resolution. To make them continuous with the non-draft,
// we have to scale the step size so that the output Y value is consistently based on the higher
// resolution
float stepRatio = dst.worldSize.x / dst.rect.size.x;
dst.arr = ValuesParallel(
(int)dst.rect.size.x,
dst.worldPos.x + offset.x,
dst.worldPos.z + offset.z,
stepRatio,
period,
skew.x,
skew.z
);
if (stop != null && stop.stop) return;
data.StoreProduct(this, dst);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment