private uint PackTileInAtlas(uint layerIdx, uint tx, uint ty) { var tileIndex = tx + (ty * _mlmask.Layers[layerIdx].WidthInTiles0); if (_mlmask.Layers[layerIdx].Tiles[Convert.ToInt32(tileIndex)].AtlasInPosition == uint.MaxValue) { BlockCompressLocalTile(ref _mlmask.Layers[layerIdx], tileIndex); var recursiveHash = FNV1A.FnvHashInitial; for (uint y = 0; y < _mlmask.AtlasTileSize / 4; y++) { for (uint x = 0; x < _mlmask.AtlasTileSize / 4; x++) { var compressedBlock = _mlmask.Layers[layerIdx].Tiles[Convert.ToInt32(tileIndex)].AtlasBlockCompressed[x + (y * _mlmask.AtlasTileSize / 4)]; var color32 = new float[16]; D3DX.D3DXDecodeBC4U(ref color32, compressedBlock); var color8 = new byte[16]; for (uint i = 0; i < 16; ++i) { color8[i] = Convert.ToByte(color32[i] * 255.0f); } recursiveHash = FNV1A.HashReadOnlySpan(color8, recursiveHash); } } var atlasView = new TileView(); if (!_mlmask.AtlasTiles.TryGetValue(recursiveHash, out atlasView)) { var atlasTile = new TileView { AtlasInPosition = _mlmask.AtlasTilesCount++, LayerIndex = layerIdx, LayerTileIndex = tileIndex }; atlasView = atlasTile; _mlmask.AtlasTiles.Add(recursiveHash, atlasTile); } var z = _mlmask.Layers[layerIdx].Tiles[Convert.ToInt32(tileIndex)]; z.AtlasInPosition = atlasView.AtlasInPosition; _mlmask.Layers[layerIdx].Tiles[Convert.ToInt32(tileIndex)] = z; } return(_mlmask.Layers[layerIdx].Tiles[Convert.ToInt32(tileIndex)].AtlasInPosition); }
uint PackTileInAtlas(uint layerIdx, uint tx, uint ty) { uint tileIndex = (tx + ty * mlmask.layers[layerIdx]._widthInTiles0); if (mlmask.layers[layerIdx].tiles[Convert.ToInt32(tileIndex)]._atlasInPosition == uint.MaxValue) { BlockCompressLocalTile(ref mlmask.layers[layerIdx], tileIndex); UInt64 recursiveHash = FNV1A.FnvHashInitial; for (uint y = 0; y < mlmask._atlasTileSize / 4; y++) { for (uint x = 0; x < mlmask._atlasTileSize / 4; x++) { UInt64 compressedBlock = mlmask.layers[layerIdx].tiles[Convert.ToInt32(tileIndex)]._atlasBlockCompressed[x + y * mlmask._atlasTileSize / 4]; float[] color32 = new float[16]; D3DX.D3DXDecodeBC4U(ref color32, compressedBlock); Byte[] color8 = new Byte[16]; for (uint i = 0; i < 16; ++i) { color8[i] = Convert.ToByte(color32[i] * 255.0f); } recursiveHash = FNV1A.HashReadOnlySpan(color8, recursiveHash); } } TileView atlasView = new TileView(); if (!mlmask._atlasTiles.TryGetValue(recursiveHash, out atlasView)) { TileView atlasTile = new TileView(); atlasTile._atlasInPosition = mlmask._atlasTilesCount++; atlasTile._layerIndex = layerIdx; atlasTile._layerTileIndex = tileIndex; atlasView = atlasTile; mlmask._atlasTiles.Add(recursiveHash, atlasTile); } var z = mlmask.layers[layerIdx].tiles[Convert.ToInt32(tileIndex)]; z._atlasInPosition = atlasView._atlasInPosition; mlmask.layers[layerIdx].tiles[Convert.ToInt32(tileIndex)] = z; } return(mlmask.layers[layerIdx].tiles[Convert.ToInt32(tileIndex)]._atlasInPosition); }
void BlockCompressLocalTile(ref RawTexContainer layer, uint tileIdx) { uint tileSizeInBlocks0 = mlmask._atlasTileSize / 4; uint tx = (tileIdx % layer._widthInTiles0); uint ty = (tileIdx / layer._widthInTiles0); var layerTile = layer.tiles[Convert.ToInt32(tileIdx)]; layerTile._atlasBlockCompressed = new UInt64[(tileSizeInBlocks0 * tileSizeInBlocks0)]; for (uint yBlock = 0; yBlock < tileSizeInBlocks0; yBlock++) { for (uint xBlock = 0; xBlock < tileSizeInBlocks0; xBlock++) { List <float> referenceData = new List <float>(); float[] toBBCValues = new float[16]; for (uint j = 0; j < 4; j++) { for (uint i = 0; i < 4; i++) { uint px = xBlock * 4 + i; uint py = yBlock * 4 + j; float v = Convert.ToSingle(layerTile._atlasUnCompressed[px + py * mlmask._atlasTileSize]) / 255.0f; toBBCValues[i + j * 4] = v; referenceData.Add(v); } } if ((tx > 0) && (xBlock == 0)) { PushBlockReferenceData(ref referenceData, layer, tx - 1, ty, tileSizeInBlocks0 - 1, yBlock); } else if ((tx < layer._widthInTiles0 - 1) && (xBlock == tileSizeInBlocks0 - 1)) { PushBlockReferenceData(ref referenceData, layer, tx + 1, ty, 0, yBlock); } if ((ty > 0) && (yBlock == 0)) { PushBlockReferenceData(ref referenceData, layer, tx, ty - 1, xBlock, tileSizeInBlocks0 - 1); } else if ((ty < layer._heightInTiles0 - 1) && (yBlock == tileSizeInBlocks0 - 1)) { PushBlockReferenceData(ref referenceData, layer, tx, ty + 1, xBlock, 0); } if (((tx > 0) && (xBlock == 0)) && ((ty > 0) && (yBlock == 0))) { PushBlockReferenceData(ref referenceData, layer, tx - 1, ty - 1, tileSizeInBlocks0 - 1, tileSizeInBlocks0 - 1); } else if (((tx < layer._widthInTiles0 - 1) && (xBlock == tileSizeInBlocks0 - 1)) && ((ty > 0) && (yBlock == 0))) { PushBlockReferenceData(ref referenceData, layer, tx + 1, ty - 1, 0, tileSizeInBlocks0 - 1); } else if (((tx > 0) && (xBlock == 0)) && ((ty < layer._heightInTiles0 - 1) && (yBlock == tileSizeInBlocks0 - 1))) { PushBlockReferenceData(ref referenceData, layer, tx - 1, ty + 1, tileSizeInBlocks0 - 1, 0); } else if (((tx < layer._widthInTiles0 - 1) && (xBlock == tileSizeInBlocks0 - 1)) && ((ty < layer._heightInTiles0 - 1) && (yBlock == tileSizeInBlocks0 - 1))) { PushBlockReferenceData(ref referenceData, layer, tx + 1, ty + 1, 0, 0); } UInt64 blockCompressed = 0; D3DX.D3DXEncodeBC4U(ref blockCompressed, toBBCValues, referenceData); layerTile._atlasBlockCompressed[xBlock + yBlock * tileSizeInBlocks0] = blockCompressed; } } layer.tiles[Convert.ToInt32(tileIdx)] = layerTile; }
private void BlockCompressLocalTile(ref RawTexContainer layer, uint tileIdx) { var tileSizeInBlocks0 = _mlmask.AtlasTileSize / 4; var tx = tileIdx % layer.WidthInTiles0; var ty = tileIdx / layer.WidthInTiles0; var layerTile = layer.Tiles[Convert.ToInt32(tileIdx)]; layerTile.AtlasBlockCompressed = new ulong[tileSizeInBlocks0 * tileSizeInBlocks0]; for (uint yBlock = 0; yBlock < tileSizeInBlocks0; yBlock++) { for (uint xBlock = 0; xBlock < tileSizeInBlocks0; xBlock++) { var referenceData = new List <float>(); var toBBCValues = new float[16]; for (uint j = 0; j < 4; j++) { for (uint i = 0; i < 4; i++) { var px = (xBlock * 4) + i; var py = (yBlock * 4) + j; var v = Convert.ToSingle(layerTile.AtlasUnCompressed[px + (py * _mlmask.AtlasTileSize)]) / 255.0f; toBBCValues[i + (j * 4)] = v; referenceData.Add(v); } } if (tx > 0 && xBlock == 0) { PushBlockReferenceData(ref referenceData, layer, tx - 1, ty, tileSizeInBlocks0 - 1, yBlock); } else if (tx < layer.WidthInTiles0 - 1 && xBlock == tileSizeInBlocks0 - 1) { PushBlockReferenceData(ref referenceData, layer, tx + 1, ty, 0, yBlock); } if (ty > 0 && yBlock == 0) { PushBlockReferenceData(ref referenceData, layer, tx, ty - 1, xBlock, tileSizeInBlocks0 - 1); } else if (ty < layer.HeightInTiles0 - 1 && yBlock == tileSizeInBlocks0 - 1) { PushBlockReferenceData(ref referenceData, layer, tx, ty + 1, xBlock, 0); } if (tx > 0 && xBlock == 0 && ty > 0 && yBlock == 0) { PushBlockReferenceData(ref referenceData, layer, tx - 1, ty - 1, tileSizeInBlocks0 - 1, tileSizeInBlocks0 - 1); } else if (tx < layer.WidthInTiles0 - 1 && xBlock == tileSizeInBlocks0 - 1 && ty > 0 && yBlock == 0) { PushBlockReferenceData(ref referenceData, layer, tx + 1, ty - 1, 0, tileSizeInBlocks0 - 1); } else if (tx > 0 && xBlock == 0 && ty < layer.HeightInTiles0 - 1 && yBlock == tileSizeInBlocks0 - 1) { PushBlockReferenceData(ref referenceData, layer, tx - 1, ty + 1, tileSizeInBlocks0 - 1, 0); } else if (tx < layer.WidthInTiles0 - 1 && xBlock == tileSizeInBlocks0 - 1 && ty < layer.HeightInTiles0 - 1 && yBlock == tileSizeInBlocks0 - 1) { PushBlockReferenceData(ref referenceData, layer, tx + 1, ty + 1, 0, 0); } ulong blockCompressed = 0; D3DX.D3DXEncodeBC4U(ref blockCompressed, toBBCValues, referenceData); layerTile.AtlasBlockCompressed[xBlock + (yBlock * tileSizeInBlocks0)] = blockCompressed; } } layer.Tiles[Convert.ToInt32(tileIdx)] = layerTile; }