void cBlockArea::DumpToRawFile(const AString & a_FileName) { cFile f; if (!f.Open(a_FileName, cFile::fmWrite)) { LOGWARNING("cBlockArea: Cannot open file \"%s\" for raw dump", a_FileName.c_str()); return; } UInt32 SizeX = ntohl(m_SizeX); UInt32 SizeY = ntohl(m_SizeY); UInt32 SizeZ = ntohl(m_SizeZ); f.Write(&SizeX, 4); f.Write(&SizeY, 4); f.Write(&SizeZ, 4); unsigned char DataTypes = GetDataTypes(); f.Write(&DataTypes, 1); int NumBlocks = GetBlockCount(); if (HasBlockTypes()) { f.Write(m_BlockTypes, NumBlocks * sizeof(BLOCKTYPE)); } if (HasBlockMetas()) { f.Write(m_BlockMetas, NumBlocks); } if (HasBlockLights()) { f.Write(m_BlockLight, NumBlocks); } if (HasBlockSkyLights()) { f.Write(m_BlockSkyLight, NumBlocks); } }
void cBlockArea::Expand(int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMaxY, int a_SubMinZ, int a_AddMaxZ) { if (HasBlockTypes()) { ExpandBlockTypes(a_SubMinX, a_AddMaxX, a_SubMinY, a_AddMaxY, a_SubMinZ, a_AddMaxZ); } if (HasBlockMetas()) { ExpandNibbles(m_BlockMetas, a_SubMinX, a_AddMaxX, a_SubMinY, a_AddMaxY, a_SubMinZ, a_AddMaxZ); } if (HasBlockLights()) { ExpandNibbles(m_BlockLight, a_SubMinX, a_AddMaxX, a_SubMinY, a_AddMaxY, a_SubMinZ, a_AddMaxZ); } if (HasBlockSkyLights()) { ExpandNibbles(m_BlockSkyLight, a_SubMinX, a_AddMaxX, a_SubMinY, a_AddMaxY, a_SubMinZ, a_AddMaxZ); } m_OriginX -= a_SubMinX; m_OriginY -= a_SubMinY; m_OriginZ -= a_SubMinZ; m_SizeX += a_SubMinX + a_AddMaxX; m_SizeY += a_SubMinY + a_AddMaxY; m_SizeZ += a_SubMinZ + a_AddMaxZ; }
void cBlockArea::MirrorYZNoMeta(void) { int HalfX = m_SizeX / 2; int MaxX = m_SizeX - 1; if (HasBlockTypes()) { for (int y = 0; y < m_SizeY; y++) { for (int z = 0; z < m_SizeZ; z++) { for (int x = 0; x < HalfX; x++) { std::swap(m_BlockTypes[MakeIndex(x, y, z)], m_BlockTypes[MakeIndex(MaxX - x, y, z)]); } // for x } // for z } // for y } // if (HasBlockTypes) if (HasBlockMetas()) { for (int y = 0; y < m_SizeY; y++) { for (int z = 0; z < m_SizeZ; z++) { for (int x = 0; x < HalfX; x++) { std::swap(m_BlockMetas[MakeIndex(x, y, z)], m_BlockMetas[MakeIndex(MaxX - x, y, z)]); } // for x } // for z } // for y } // if (HasBlockMetas) }
void cBlockArea::CopyTo(cBlockArea & a_Into) const { if (&a_Into == this) { LOGWARNING("Trying to copy a cBlockArea into self, ignoring."); return; } a_Into.Clear(); a_Into.SetSize(m_SizeX, m_SizeY, m_SizeZ, GetDataTypes()); a_Into.m_OriginX = m_OriginX; a_Into.m_OriginY = m_OriginY; a_Into.m_OriginZ = m_OriginZ; int BlockCount = GetBlockCount(); if (HasBlockTypes()) { memcpy(a_Into.m_BlockTypes, m_BlockTypes, BlockCount * sizeof(BLOCKTYPE)); } if (HasBlockMetas()) { memcpy(a_Into.m_BlockMetas, m_BlockMetas, BlockCount * sizeof(NIBBLETYPE)); } if (HasBlockLights()) { memcpy(a_Into.m_BlockLight, m_BlockLight, BlockCount * sizeof(NIBBLETYPE)); } if (HasBlockSkyLights()) { memcpy(a_Into.m_BlockSkyLight, m_BlockSkyLight, BlockCount * sizeof(NIBBLETYPE)); } }
void cBlockArea::MirrorYZ(void) { if (!HasBlockTypes()) { LOGWARNING("cBlockArea: Cannot mirror meta without blocktypes!"); return; } if (!HasBlockMetas()) { // There are no blockmetas to mirror, just use the NoMeta function MirrorYZNoMeta(); return; } // We are guaranteed that both blocktypes and blockmetas exist; mirror both at the same time: int HalfX = m_SizeX / 2; int MaxX = m_SizeX - 1; for (int y = 0; y < m_SizeY; y++) { for (int z = 0; z < m_SizeZ; z++) { for (int x = 0; x < HalfX; x++) { int Idx1 = MakeIndex(x, y, z); int Idx2 = MakeIndex(MaxX - x, y, z); std::swap(m_BlockTypes[Idx1], m_BlockTypes[Idx2]); NIBBLETYPE Meta1 = BlockHandler(m_BlockTypes[Idx2])->MetaMirrorYZ(m_BlockMetas[Idx1]); NIBBLETYPE Meta2 = BlockHandler(m_BlockTypes[Idx1])->MetaMirrorYZ(m_BlockMetas[Idx2]); m_BlockMetas[Idx1] = Meta2; m_BlockMetas[Idx2] = Meta1; } // for x } // for z } // for y }
void cBlockArea::MirrorXYNoMeta(void) { int HalfZ = m_SizeZ / 2; int MaxZ = m_SizeZ - 1; if (HasBlockTypes()) { for (int y = 0; y < m_SizeY; y++) { for (int z = 0; z < HalfZ; z++) { for (int x = 0; x < m_SizeX; x++) { std::swap(m_BlockTypes[MakeIndex(x, y, z)], m_BlockTypes[MakeIndex(x, y, MaxZ - z)]); } // for x } // for z } // for y } // if (HasBlockTypes) if (HasBlockMetas()) { for (int y = 0; y < m_SizeY; y++) { for (int z = 0; z < HalfZ; z++) { for (int x = 0; x < m_SizeX; x++) { std::swap(m_BlockMetas[MakeIndex(x, y, z)], m_BlockMetas[MakeIndex(x, y, MaxZ - z)]); } // for x } // for z } // for y } // if (HasBlockMetas) }
void cBlockArea::MirrorXZNoMeta(void) { int HalfY = m_Size.y / 2; int MaxY = m_Size.y - 1; if (HasBlockTypes()) { for (int y = 0; y < HalfY; y++) { for (int z = 0; z < m_Size.z; z++) { for (int x = 0; x < m_Size.x; x++) { std::swap(m_BlockTypes[MakeIndex(x, y, z)], m_BlockTypes[MakeIndex(x, MaxY - y, z)]); } // for x } // for z } // for y } // if (HasBlockTypes) if (HasBlockMetas()) { for (int y = 0; y < HalfY; y++) { for (int z = 0; z < m_Size.z; z++) { for (int x = 0; x < m_Size.x; x++) { std::swap(m_BlockMetas[MakeIndex(x, y, z)], m_BlockMetas[MakeIndex(x, MaxY - y, z)]); } // for x } // for z } // for y } // if (HasBlockMetas) }
bool cBlockArea::SaveToSchematicFile(const AString & a_FileName) { cFastNBTWriter Writer("Schematic"); Writer.AddShort("Width", m_SizeX); Writer.AddShort("Height", m_SizeY); Writer.AddShort("Length", m_SizeZ); Writer.AddString("Materials", "Alpha"); if (HasBlockTypes()) { Writer.AddByteArray("Blocks", (const char *)m_BlockTypes, GetBlockCount()); } else { AString Dummy(GetBlockCount(), 0); Writer.AddByteArray("Blocks", Dummy.data(), Dummy.size()); } if (HasBlockMetas()) { Writer.AddByteArray("Data", (const char *)m_BlockMetas, GetBlockCount()); } else { AString Dummy(GetBlockCount(), 0); Writer.AddByteArray("Data", Dummy.data(), Dummy.size()); } // TODO: Save entities and block entities Writer.BeginList("Entities", TAG_Compound); Writer.EndList(); Writer.BeginList("TileEntities", TAG_Compound); Writer.EndList(); Writer.Finish(); // Save to file cGZipFile File; if (!File.Open(a_FileName, cGZipFile::fmWrite)) { LOG("Cannot open file \"%s\" for writing.", a_FileName.c_str()); return false; } if (!File.Write(Writer.GetResult())) { LOG("Cannot write data to file \"%s\".", a_FileName.c_str()); return false; } return true; }
void cBlockArea::RotateCW(void) { if (!HasBlockTypes()) { LOGWARNING("cBlockArea: Cannot rotate blockmeta without blocktypes!"); return; } if (!HasBlockMetas()) { // There are no blockmetas to rotate, just use the NoMeta function RotateCWNoMeta(); return; } // We are guaranteed that both blocktypes and blockmetas exist; rotate both at the same time: BLOCKTYPE * NewTypes = new BLOCKTYPE[m_SizeX * m_SizeY * m_SizeZ]; NIBBLETYPE * NewMetas = new NIBBLETYPE[m_SizeX * m_SizeY * m_SizeZ]; for (int x = 0; x < m_SizeX; x++) { int NewZ = x; for (int z = 0; z < m_SizeZ; z++) { int NewX = m_SizeZ - z - 1; for (int y = 0; y < m_SizeY; y++) { int NewIdx = NewX + NewZ * m_SizeX + y * m_SizeX * m_SizeZ; int OldIdx = MakeIndex(x, y, z); NewTypes[NewIdx] = m_BlockTypes[OldIdx]; NewMetas[NewIdx] = BlockHandler(m_BlockTypes[OldIdx])->MetaRotateCW(m_BlockMetas[OldIdx]); } // for y } // for z } // for x std::swap(m_BlockTypes, NewTypes); std::swap(m_BlockMetas, NewMetas); delete[] NewTypes; delete[] NewMetas; std::swap(m_SizeX, m_SizeZ); }
void cBlockArea::RotateCWNoMeta(void) { if (HasBlockTypes()) { BLOCKTYPE * NewTypes = new BLOCKTYPE[m_SizeX * m_SizeY * m_SizeZ]; for (int z = 0; z < m_SizeZ; z++) { int NewX = m_SizeZ - z - 1; for (int x = 0; x < m_SizeX; x++) { int NewZ = x; for (int y = 0; y < m_SizeY; y++) { NewTypes[NewX + NewZ * m_SizeX + y * m_SizeX * m_SizeZ] = m_BlockTypes[MakeIndex(x, y, z)]; } // for y } // for x } // for z std::swap(m_BlockTypes, NewTypes); delete[] NewTypes; } if (HasBlockMetas()) { NIBBLETYPE * NewMetas = new NIBBLETYPE[m_SizeX * m_SizeY * m_SizeZ]; for (int z = 0; z < m_SizeZ; z++) { int NewX = m_SizeZ - z - 1; for (int x = 0; x < m_SizeX; x++) { int NewZ = x; for (int y = 0; y < m_SizeY; y++) { NewMetas[NewX + NewZ * m_SizeX + y * m_SizeX * m_SizeZ] = m_BlockMetas[MakeIndex(x, y, z)]; } // for y } // for x } // for z std::swap(m_BlockMetas, NewMetas); delete[] NewMetas; } std::swap(m_SizeX, m_SizeZ); }
void cBlockArea::RotateCWNoMeta(void) { if (HasBlockTypes()) { BLOCKTYPE * NewTypes = new BLOCKTYPE[GetBlockCount()]; for (int z = 0; z < m_Size.z; z++) { int NewX = m_Size.z - z - 1; for (int x = 0; x < m_Size.x; x++) { int NewZ = x; for (int y = 0; y < m_Size.y; y++) { NewTypes[NewX + NewZ * m_Size.z + y * m_Size.x * m_Size.z] = m_BlockTypes[MakeIndex(x, y, z)]; } // for y } // for x } // for z std::swap(m_BlockTypes, NewTypes); delete[] NewTypes; } if (HasBlockMetas()) { NIBBLETYPE * NewMetas = new NIBBLETYPE[GetBlockCount()]; for (int z = 0; z < m_Size.z; z++) { int NewX = m_Size.z - z - 1; for (int x = 0; x < m_Size.x; x++) { int NewZ = x; for (int y = 0; y < m_Size.y; y++) { NewMetas[NewX + NewZ * m_Size.z + y * m_Size.x * m_Size.z] = m_BlockMetas[MakeIndex(x, y, z)]; } // for y } // for x } // for z std::swap(m_BlockMetas, NewMetas); delete[] NewMetas; } std::swap(m_Size.x, m_Size.z); }
void cBlockArea::Crop(int a_AddMinX, int a_SubMaxX, int a_AddMinY, int a_SubMaxY, int a_AddMinZ, int a_SubMaxZ) { if ( (a_AddMinX + a_SubMaxX >= m_SizeX) || (a_AddMinY + a_SubMaxY >= m_SizeY) || (a_AddMinZ + a_SubMaxZ >= m_SizeZ) ) { LOGWARNING("cBlockArea:Crop called with more croping than the dimensions: %d x %d x %d with cropping %d, %d and %d", m_SizeX, m_SizeY, m_SizeZ, a_AddMinX + a_SubMaxX, a_AddMinY + a_SubMaxY, a_AddMinZ + a_SubMaxZ ); return; } if (HasBlockTypes()) { CropBlockTypes(a_AddMinX, a_SubMaxX, a_AddMinY, a_SubMaxY, a_AddMinZ, a_SubMaxZ); } if (HasBlockMetas()) { CropNibbles(m_BlockMetas, a_AddMinX, a_SubMaxX, a_AddMinY, a_SubMaxY, a_AddMinZ, a_SubMaxZ); } if (HasBlockLights()) { CropNibbles(m_BlockLight, a_AddMinX, a_SubMaxX, a_AddMinY, a_SubMaxY, a_AddMinZ, a_SubMaxZ); } if (HasBlockSkyLights()) { CropNibbles(m_BlockSkyLight, a_AddMinX, a_SubMaxX, a_AddMinY, a_SubMaxY, a_AddMinZ, a_SubMaxZ); } m_OriginX += a_AddMinX; m_OriginY += a_AddMinY; m_OriginZ += a_AddMinZ; m_SizeX -= a_AddMinX + a_SubMaxX; m_SizeY -= a_AddMinY + a_SubMaxY; m_SizeZ -= a_AddMinZ + a_SubMaxZ; }
void cBlockArea::Expand(int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMaxY, int a_SubMinZ, int a_AddMaxZ) { if (HasBlockTypes()) { ExpandBlockTypes(a_SubMinX, a_AddMaxX, a_SubMinY, a_AddMaxY, a_SubMinZ, a_AddMaxZ); } if (HasBlockMetas()) { ExpandNibbles(m_BlockMetas, a_SubMinX, a_AddMaxX, a_SubMinY, a_AddMaxY, a_SubMinZ, a_AddMaxZ); } if (HasBlockLights()) { ExpandNibbles(m_BlockLight, a_SubMinX, a_AddMaxX, a_SubMinY, a_AddMaxY, a_SubMinZ, a_AddMaxZ); } if (HasBlockSkyLights()) { ExpandNibbles(m_BlockSkyLight, a_SubMinX, a_AddMaxX, a_SubMinY, a_AddMaxY, a_SubMinZ, a_AddMaxZ); } m_Origin.Move(-a_SubMinX, -a_SubMinY, -a_SubMinZ); m_Size.x += a_SubMinX + a_AddMaxX; m_Size.y += a_SubMinY + a_AddMaxY; m_Size.z += a_SubMinZ + a_AddMaxZ; }
void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy) { // Block types are compulsory, block metas are voluntary if (!HasBlockTypes() || !a_Src.HasBlockTypes()) { LOGWARNING("%s: cannot merge because one of the areas doesn't have blocktypes.", __FUNCTION__); return; } // Dst is *this, Src is a_Src int SrcOffX = std::max(0, -a_RelX); // Offset in Src where to start reading int DstOffX = std::max(0, a_RelX); // Offset in Dst where to start writing int SizeX = std::min(a_Src.GetSizeX() - SrcOffX, GetSizeX() - DstOffX); // How many blocks to copy int SrcOffY = std::max(0, -a_RelY); // Offset in Src where to start reading int DstOffY = std::max(0, a_RelY); // Offset in Dst where to start writing int SizeY = std::min(a_Src.GetSizeY() - SrcOffY, GetSizeY() - DstOffY); // How many blocks to copy int SrcOffZ = std::max(0, -a_RelZ); // Offset in Src where to start reading int DstOffZ = std::max(0, a_RelZ); // Offset in Dst where to start writing int SizeZ = std::min(a_Src.GetSizeZ() - SrcOffZ, GetSizeZ() - DstOffZ); // How many blocks to copy const NIBBLETYPE * SrcMetas = a_Src.GetBlockMetas(); NIBBLETYPE * DstMetas = m_BlockMetas; bool IsDummyMetas = ((SrcMetas == NULL) || (DstMetas == NULL)); if (IsDummyMetas) { SrcMetas = new NIBBLETYPE[a_Src.GetBlockCount()]; DstMetas = new NIBBLETYPE[GetBlockCount()]; } switch (a_Strategy) { case msOverwrite: { InternalMergeBlocks( m_BlockTypes, a_Src.GetBlockTypes(), DstMetas, SrcMetas, SizeX, SizeY, SizeZ, SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), m_SizeX, m_SizeY, m_SizeZ, MergeCombinatorOverwrite ); break; } // case msOverwrite case msFillAir: { InternalMergeBlocks( m_BlockTypes, a_Src.GetBlockTypes(), DstMetas, SrcMetas, SizeX, SizeY, SizeZ, SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), m_SizeX, m_SizeY, m_SizeZ, MergeCombinatorFillAir ); break; } // case msFillAir case msImprint: { InternalMergeBlocks( m_BlockTypes, a_Src.GetBlockTypes(), DstMetas, SrcMetas, SizeX, SizeY, SizeZ, SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), m_SizeX, m_SizeY, m_SizeZ, MergeCombinatorImprint ); break; } // case msImprint case msLake: { InternalMergeBlocks( m_BlockTypes, a_Src.GetBlockTypes(), DstMetas, SrcMetas, SizeX, SizeY, SizeZ, SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), m_SizeX, m_SizeY, m_SizeZ, MergeCombinatorLake ); break; } // case msLake default: { LOGWARNING("Unknown block area merge strategy: %d", a_Strategy); ASSERT(!"Unknown block area merge strategy"); break; } } // switch (a_Strategy) if (IsDummyMetas) { delete[] SrcMetas; delete[] DstMetas; } }
void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy, const NIBBLETYPE * SrcMetas, NIBBLETYPE * DstMetas) { // Block types are compulsory, block metas are voluntary if (!HasBlockTypes() || !a_Src.HasBlockTypes()) { LOGWARNING("%s: cannot merge because one of the areas doesn't have blocktypes.", __FUNCTION__); return; } // Dst is *this, Src is a_Src int SrcOffX = std::max(0, -a_RelX); // Offset in Src where to start reading int DstOffX = std::max(0, a_RelX); // Offset in Dst where to start writing int SizeX = std::min(a_Src.GetSizeX() - SrcOffX, GetSizeX() - DstOffX); // How many blocks to copy int SrcOffY = std::max(0, -a_RelY); // Offset in Src where to start reading int DstOffY = std::max(0, a_RelY); // Offset in Dst where to start writing int SizeY = std::min(a_Src.GetSizeY() - SrcOffY, GetSizeY() - DstOffY); // How many blocks to copy int SrcOffZ = std::max(0, -a_RelZ); // Offset in Src where to start reading int DstOffZ = std::max(0, a_RelZ); // Offset in Dst where to start writing int SizeZ = std::min(a_Src.GetSizeZ() - SrcOffZ, GetSizeZ() - DstOffZ); // How many blocks to copy switch (a_Strategy) { case cBlockArea::msOverwrite: { InternalMergeBlocks<MetasValid, MergeCombinatorOverwrite<MetasValid> >( m_BlockTypes, a_Src.GetBlockTypes(), DstMetas, SrcMetas, SizeX, SizeY, SizeZ, SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), m_Size.x, m_Size.y, m_Size.z ); return; } // case msOverwrite case cBlockArea::msFillAir: { InternalMergeBlocks<MetasValid, MergeCombinatorFillAir<MetasValid> >( m_BlockTypes, a_Src.GetBlockTypes(), DstMetas, SrcMetas, SizeX, SizeY, SizeZ, SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), m_Size.x, m_Size.y, m_Size.z ); return; } // case msFillAir case cBlockArea::msImprint: { InternalMergeBlocks<MetasValid, MergeCombinatorImprint<MetasValid> >( m_BlockTypes, a_Src.GetBlockTypes(), DstMetas, SrcMetas, SizeX, SizeY, SizeZ, SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), m_Size.x, m_Size.y, m_Size.z ); return; } // case msImprint case cBlockArea::msLake: { InternalMergeBlocks<MetasValid, MergeCombinatorLake<MetasValid> >( m_BlockTypes, a_Src.GetBlockTypes(), DstMetas, SrcMetas, SizeX, SizeY, SizeZ, SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), m_Size.x, m_Size.y, m_Size.z ); return; } // case msLake case cBlockArea::msSpongePrint: { InternalMergeBlocks<MetasValid, MergeCombinatorSpongePrint<MetasValid> >( m_BlockTypes, a_Src.GetBlockTypes(), DstMetas, SrcMetas, SizeX, SizeY, SizeZ, SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), m_Size.x, m_Size.y, m_Size.z ); return; } // case msSpongePrint case cBlockArea::msDifference: { InternalMergeBlocks<MetasValid, MergeCombinatorDifference<MetasValid> >( m_BlockTypes, a_Src.GetBlockTypes(), DstMetas, SrcMetas, SizeX, SizeY, SizeZ, SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), m_Size.x, m_Size.y, m_Size.z ); return; } // case msDifference case cBlockArea::msMask: { InternalMergeBlocks<MetasValid, MergeCombinatorMask<MetasValid> >( m_BlockTypes, a_Src.GetBlockTypes(), DstMetas, SrcMetas, SizeX, SizeY, SizeZ, SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), m_Size.x, m_Size.y, m_Size.z ); return; } // case msMask } // switch (a_Strategy) LOGWARNING("Unknown block area merge strategy: %d", a_Strategy); ASSERT(!"Unknown block area merge strategy"); return; }