// System.out.println("LayerMap:");
// printfloatarray(layermap);
// //endregion Layer Map
//region Texture Compositing
IBitmap output = BitmapFactory.getIntance().getNewIntance(outputSize, outputSize, PixelFormat.Format32bppArgb);
// int[] comps = new int[]
// {
// (detailTexture[0].getPixelFormat() == PixelFormat.Format32bppArgb) ? 4 : 3,
// (detailTexture[1].getPixelFormat() == PixelFormat.Format32bppArgb) ? 4 : 3,
// (detailTexture[2].getPixelFormat() == PixelFormat.Format32bppArgb) ? 4 : 3,
// (detailTexture[3].getPixelFormat() == PixelFormat.Format32bppArgb) ? 4 : 3
// };
//
// int[] strides = new int[]
// {
// detailTexture[0].getWidth(),
// detailTexture[1].getWidth(),
// detailTexture[2].getWidth(),
// detailTexture[3].getWidth()
// };
//
// int[] scans = new int[]
// {
// 0,
// 0,
// 0,
// 0
// };
int ratio = outputSize / RegionSize;
for (int y = 0; y < outputSize; y++)
{
for (int x = 0; x < outputSize; x++)
{
float layer = layermap[(y / ratio) * RegionSize + x / ratio];
float layerx = layermap[(y / ratio) * RegionSize + Math.min(outputSize - 1, (x + 1)) / ratio];
float layerxx = layermap[(y / ratio) * RegionSize + Math.max(0, (x - 1)) / ratio];
float layery = layermap[Math.min(outputSize - 1, (y + 1)) / ratio * RegionSize + x / ratio];
float layeryy = layermap[(Math.max(0, (y - 1)) / ratio) * RegionSize + x / ratio];
// Select two textures
int l0 = (int)Math.floor(layer);
int l1 = Math.min(l0 + 1, 3);
int pixelA = detailTexture[l0].getRGB((x % 256), (y % 256));
int pixelB = detailTexture[l1].getRGB((x % 256), (y % 256));
// int pixel0 = output.getRGB(x, y);
float aB = pixelA & 0xff;
float aG = (pixelA >> 8) & 0xff;
float aR = (pixelA >> 16) & 0xff;
// byte* ptrA = (byte*)scans[l0] + (y % 256) * strides[l0] + (x % 256) * comps[l0];
// byte* ptrB = (byte*)scans[l1] + (y % 256) * strides[l1] + (x % 256) * comps[l1];
// byte* ptrO = (byte*)outputData.Scan0 + y * outputData.Stride + x * 3;
// float aB = *(ptrA + 0);
// float aG = *(ptrA + 1);
// float aR = *(ptrA + 2);
int lX = (int)Math.floor(layerx);
int pixelX = detailTexture[lX].getRGB((x % 256), (y % 256));
int lXX = (int)Math.floor(layerxx);
int pixelXX = detailTexture[lXX].getRGB((x % 256), (y % 256));
int lY = (int)Math.floor(layery);
int pixelY = detailTexture[lY].getRGB((x % 256), (y % 256));
int lYY = (int)Math.floor(layeryy);
int pixelYY = detailTexture[lYY].getRGB((x % 256), (y % 256));
float bB = pixelB & 0xff;
float bG = (pixelB >> 8) & 0xff;
float bR = (pixelB >> 16) & 0xff;
float XB = pixelX & 0xff;
float XG = (pixelX >> 8) & 0xff;
float XR = (pixelX >> 16) & 0xff;
float XXB = pixelXX & 0xff;
float XXG = (pixelXX >> 8) & 0xff;
float XXR = (pixelXX >> 16) & 0xff;
float YB = pixelY & 0xff;
float YG = (pixelY >> 8) & 0xff;
float YR = (pixelY >> 16) & 0xff;
float YYB = pixelYY & 0xff;
float YYG = (pixelYY >> 8) & 0xff;
float YYR = (pixelYY >> 16) & 0xff;
// int lX = (int)Math.floor(layerx);
// byte* ptrX = (byte*)scans[lX] + (y % 256) * strides[lX] + (x % 256) * comps[lX];
// int lXX = (int)Math.floor(layerxx);
// byte* ptrXX = (byte*)scans[lXX] + (y % 256) * strides[lXX] + (x % 256) * comps[lXX];
// int lY = (int)Math.floor(layery);
// byte* ptrY = (byte*)scans[lY] + (y % 256) * strides[lY] + (x % 256) * comps[lY];
// int lYY = (int)Math.floor(layeryy);
// byte* ptrYY = (byte*)scans[lYY] + (y % 256) * strides[lYY] + (x % 256) * comps[lYY];
//
// float bB = *(ptrB + 0);
// float bG = *(ptrB + 1);
// float bR = *(ptrB + 2);
float layerDiff = layer - l0;
float xlayerDiff = layerx - layer;
float xxlayerDiff = layerxx - layer;
float ylayerDiff = layery - layer;
float yylayerDiff = layeryy - layer;
// Interpolate between the two selected textures
int oB = ((int)Math.floor(aB + layerDiff * (bB - aB) +
xlayerDiff * (XB - aB) +
xxlayerDiff * (XXB - aB) +
ylayerDiff * (YB - aB) +
yylayerDiff * (YYB - aB)) ) & 0xff;
int oG = ((int)Math.floor(aG + layerDiff * (bG - aG) +
xlayerDiff * (XG - aG) +
xxlayerDiff * (XXG - aG) +
ylayerDiff * (YG - aG) +
yylayerDiff * (YYG - aG)) ) & 0xff;
int oR = ((int)Math.floor(aR + layerDiff * (bR - aR) +
xlayerDiff * (XR - aR) +
xxlayerDiff * (XXR - aR) +
ylayerDiff * (YR - aR) +
yylayerDiff * (YYR - aR)) ) & 0xff;
output.setRGB(x, y, (0xff << 24) | (oR << 16) | (oG << 8) | oB);
// *(ptrO + 0) = (byte)Math.Floor(aB + layerDiff * (bB - aB) +
// xlayerDiff * (*ptrX - aB) +
// xxlayerDiff * (*(ptrXX) - aB) +
// ylayerDiff * (*ptrY - aB) +
// yylayerDiff * (*(ptrYY) - aB));
// *(ptrO + 1) = (byte)Math.Floor(aG + layerDiff * (bG - aG) +
// xlayerDiff * (*(ptrX + 1) - aG) +
// xxlayerDiff * (*(ptrXX + 1) - aG) +
// ylayerDiff * (*(ptrY + 1) - aG) +
// yylayerDiff * (*(ptrYY + 1) - aG));
// *(ptrO + 2) = (byte)Math.Floor(aR + layerDiff * (bR - aR) +
// xlayerDiff * (*(ptrX + 2) - aR) +
// xxlayerDiff * (*(ptrXX + 2) - aR) +
// ylayerDiff * (*(ptrY + 2) - aR) +
// yylayerDiff * (*(ptrYY + 2) - aR));
}
}
for (int i = 0; i < detailTexture.length; i++)
{
// detailTexture[i].UnlockBits(datas[i]);
detailTexture[i].dispose();
}
layermap = null;
// output.UnlockBits(outputData);
// output.RotateFlip(RotateFlipType.Rotate270FlipNone);
output.rotateAndFlip(Math.toRadians(270), false, false);
//endregion Texture Compositing
return output;
}