//Generate one banding of a palette public void PalGen1DBand(int numBands, Grid pal, ulong color1, ulong color2, int band) { if (pal == null) { return; } double sectionSize = 256.0 / numBands / 2; ulong a = color1; ulong b = color2; var offset = (int)(band * sectionSize * 2); for (int i = 0; i <= sectionSize; i++) { double mux = i / sectionSize; ulong color = MathLerper.LerpRgba(mux, a, b); pal.Plot((i + offset), 0, 0, color); } for (int i = 0; i <= sectionSize; i++) { double mux = i / sectionSize; ulong color = MathLerper.LerpRgba(mux, b, a); pal.Plot((int)(i + sectionSize + offset), 0, 0, color); } }
//Blit a Grid into a Grid, blended public void BlendBlit(GridContext bgc, Grid pal, int x1, int y1, int z1, int x2, int y2, int z2, int blend) { if (bgc == null || pal == null) { return; } MinMax(ref x1, ref x2); MinMax(ref y1, ref y2); MinMax(ref z1, ref z2); if (x2 - x1 == 0) { x2++; } if (y2 - y1 == 0) { y2++; } if (z2 - z1 == 0) { z2++; } double scaleX = (double)pal.SizeX / (x2 - x1); double scaleY = (double)pal.SizeY / (y2 - y1); double scaleZ = (double)pal.SizeZ / (z2 - z1); for (int z = z1; z < z2; z++) { for (int y = y1; y < y2; y++) { for (int x = x1; x < x2; x++) { double scaledx = (x - x1) * scaleX; double scaledy = (y - y1) * scaleY; double scaledz = (z - z1) * scaleZ; ulong v1 = pal.GetRgba((int)scaledx, (int)scaledy, (int)scaledz); ulong v2 = bgc.Grid.GetRgba((int)scaledx, (int)scaledy, (int)scaledz); byte r1, g1, b1, a1; Converter.Ulong2Rgba(v1, out r1, out g1, out b1, out a1); byte r2, g2, b2, a2; Converter.Ulong2Rgba(v2, out r2, out g2, out b2, out a2); ulong v = Converter.Rgba2Ulong( MathLerper.Lerp1D((double)blend / 100, r1, r2), MathLerper.Lerp1D((double)blend / 100, g1, g2), MathLerper.Lerp1D((double)blend / 100, b1, b2), MathLerper.Lerp1D((double)blend / 100, a1, a2)); bgc.Grid.Plot(x, y, z, v); } } } }
//Extrude shape along Z-axis public void ExtrudeZ(GridContext bgc, int startX, int startY, int startZ, int stopZ, int shape, int startScale, int stopScale, int skips) { for (int z = startZ; z < stopZ; z++) { double mux = (double)(z - startZ) / (stopZ - startZ); int scale = MathLerper.Lerp1D(mux, startScale, stopScale); if (startScale == stopScale) { scale = startScale; } DrawShape(bgc, PenTwist.XYaxis, shape, startX, startY, z, scale); } }
//Extrude shape along Y-axis public void ExtrudeY(GridContext bgc, int startX, int startY, int startZ, int stopY, int shape, int startScale, int stopScale, int skips) { for (int y = startY; y < stopY; y++) { double mux = (double)(y - startY) / (stopY - startY); int scale = MathLerper.Lerp1D(mux, startScale, stopScale); if (startScale == stopScale) { scale = startScale; } DrawShape(bgc, PenTwist.XZaxis, shape, startX, startZ, y, scale); } }
//Extrude shape along X-axis public void ExtrudeX(GridContext bgc, int startX, int startY, int startZ, int stopX, int shape, int startScale, int stopScale, int skips) { for (int x = startX; x < stopX; x++) { double mux = (double)(x - startX) / (stopX - startX); int scale = MathLerper.Lerp1D(mux, startScale, stopScale); if (startScale == stopScale) { scale = startScale; } DrawShape(bgc, PenTwist.YZaxis, shape, startY, startZ, x, scale); } }
//Linearly interpolate between properties A and B, modulated by mux (0 to 1) public void Lerp(double mux, CellProperties propsA, CellProperties propsB) { if (propsA == null || propsB == null) { return; } Rgba = MathLerper.LerpRgba(mux, propsA.Rgba, propsB.Rgba); TextureId = (byte)MathLerper.ThresholdAb(mux, propsA.TextureId, propsB.TextureId); ShapeId = (byte)MathLerper.ThresholdAb(mux, propsA.ShapeId, propsB.ShapeId); PhysicsId = (byte)MathLerper.ThresholdAb(mux, propsA.PhysicsId, propsB.PhysicsId); GroupId = (byte)MathLerper.ThresholdAb(mux, propsA.GroupId, propsB.GroupId); WorldId = (ulong)MathLerper.ThresholdAb(mux, propsA.WorldId, propsB.WorldId); CalcUnified(); }
//Shade all pixels in Grid public void Shade(GridContext bgc, int axis, byte r1, byte g1, byte b1, byte r2, byte g2, byte b2) { if (bgc == null) { return; } Grid grid = bgc.Grid; for (int z = 0; z < grid.SizeZ; z++) { for (int y = 0; y < grid.SizeY; y++) { for (int x = 0; x < grid.SizeX; x++) { double factor = 0.0f; if (axis == 0) { factor = (double)x / grid.SizeX; } else if (axis == 1) { factor = (double)y / grid.SizeY; } else if (axis == 2) { factor = (double)z / grid.SizeZ; } ulong u = grid.GetRgba(x, y, z); if (u > 0) { byte r, g, b, a; Converter.Ulong2Rgba(u, out r, out g, out b, out a); r = (byte)((MathLerper.Lerp1D(factor, r1, r2)) / 1); g = (byte)((MathLerper.Lerp1D(factor, g1, g2)) / 1); b = (byte)((MathLerper.Lerp1D(factor, b1, b2)) / 1); u = Converter.Rgba2Ulong(r, g, b, a); } grid.Plot(x, y, z, u, 0, grid.GetProperty(x, y, z).ShapeId, grid.GetProperty(x, y, z).TextureId, 0, 0); } } } }
//Generate a palette from a List of banding rgba public void PalGen1DBanded(Grid pal, List <ulong> bandColors) { if (pal == null || bandColors == null) { return; } double sectionSize = 256.0 / (bandColors.Count - 1); for (int band = 0; band < bandColors.Count - 1; band++) { ulong a = bandColors[band]; ulong b = bandColors[band + 1]; for (int i = 0; i < sectionSize; i++) { double mux = i / sectionSize; ulong color = MathLerper.LerpRgba(mux, a, b); pal.Plot((int)(band * sectionSize + i), 0, 0, color); } } }