Files
MinecraftConsoles/Minecraft.Client/PS3/SPU_Tasks/ChunkUpdate/ChunkRebuildData.cpp
2026-03-01 12:16:08 +08:00

895 lines
35 KiB
C++

#include "stdafx.h"
#ifdef __PS3__
#ifndef SN_TARGET_PS3_SPU
// #include "..\..\..\stdafx.h"
#endif
#endif
#include "ChunkRebuildData.h"
#include "Tesselator_SPU.h"
#ifndef SN_TARGET_PS3_SPU
#include "..\..\..\..\Minecraft.World\Tile.h"
#include "..\..\..\..\Minecraft.World\Level.h"
#include "..\..\..\..\Minecraft.World\Dimension.h"
//
// #include "..\..\..\Chunk.h"
// #include "..\..\..\TileRenderer.h"
// #include "..\..\..\TileEntityRenderDispatcher.h"
// #include "..\..\..\LevelRenderer.h"
#include "..\..\..\..\Minecraft.World\net.minecraft.world.level.h"
#include "..\..\..\..\Minecraft.World\net.minecraft.world.level.chunk.h"
#include "..\..\..\..\Minecraft.World\net.minecraft.world.level.tile.h"
#include "..\..\..\..\Minecraft.World\net.minecraft.world.level.tile.entity.h"
#include "..\..\..\..\Minecraft.World\Icon.h"
#include "..\..\..\..\Minecraft.World\BiomeSource.h"
#else
#include "..\Common\spu_assert.h"
#endif //SN_TARGET_PS3_SPU
static const int Level_maxBuildHeight = 256;
static const int Level_MAX_LEVEL_SIZE = 30000000;
static const int Level_MAX_BRIGHTNESS = 15;
#include "TileRenderer_SPU.h"
#include "Tile_SPU.h"
#include "ChunkRebuildData.h"
TileData_SPU g_tileSPUData;
static const int MAX_LEVEL_SIZE = 30000000;
static const int MAX_BRIGHTNESS = 15;
#if 0 //def SN_TARGET_PS3_SPU
int ChunkRebuildData::getTile( int x, int y, int z ) { return m_tileIds[getTileIdx(x,y,z)]; }
int ChunkRebuildData::getBrightnessSky(int x, int y, int z) { return m_brightness[getTileIdx(x,y,z)] & 0x0f; }
int ChunkRebuildData::getBrightnessBlock(int x, int y, int z) { return m_brightness[getTileIdx(x,y,z)] >> 4; }
int ChunkRebuildData::getData(int x, int y, int z) { return m_data_flags[getTileIdx(x,y,z)] & 0x0f; }
int ChunkRebuildData::getGrassColor( int x, int z ) { return m_grassColor[getTileIdx(x,z)]; }
int ChunkRebuildData::getFoliageColor( int x, int z ) { return m_foliageColor[getTileIdx(x,z)]; }
int ChunkRebuildData::getFlags(int x, int y, int z) { return m_data_flags[getTileIdx(x,y,z)] >> 4; }
void ChunkRebuildData::setFlag(int x, int y, int z, int flag) { m_data_flags[getTileIdx(x,y,z)] |= (flag<<4);}
#endif
void ChunkRebuildData::disableUnseenTiles()
{
// We now go through the vertical section of this level chunk that we are interested in and try and establish
// (1) if it is completely empty
// (2) if any of the tiles can be quickly determined to not need rendering because they are in the middle of other tiles and
// so can't be seen. A large amount (> 60% in tests) of tiles that call tesselateInWorld in the unoptimised version
// of this function fall into this category. By far the largest category of these are tiles in solid regions of rock.
int startX = m_x0+2; // beginning of the chunk
int startY = m_y0+2; // beginning of the chunk
int startZ = m_z0+2; // beginning of the chunk
for(int iX=startX; iX<(startX+16); iX++)
{
for(int iY=startY; iY<(startY+16); iY++)
{
for(int iZ=startZ; iZ<(startZ+16); iZ++)
{
int tileID = getTile(iX,iY,iZ);
if( tileID == 0 ) continue;
m_flags &= ~e_flag_EmptyChunk;
// Don't bother trying to work out neighbours for this tile if we are at the edge of the chunk - apart from the very
// bottom of the world where we shouldn't ever be able to see
if( iY == 127 ) continue;
if(( iX-startX == 0 ) || ( iX-startX == 15 )) continue;
if(( iZ-startZ == 0 ) || ( iZ-startZ == 15 )) continue;
int flags = getFlags(iX, iY, iZ);
// Establish whether this tile and its neighbours are all made of rock, dirt, unbreakable tiles, or have already
// been determined to meet this criteria themselves and have a tile of 255 set.
if( !( ( tileID == Tile_SPU::rock_Id ) || ( tileID == Tile_SPU::dirt_Id ) || ( tileID == Tile_SPU::unbreakable_Id ) || ( flags & e_flag_NoRender) ) ) continue;
tileID = getTile(iX-1, iY, iZ);
flags = getFlags(iX-1, iY, iZ);
if( !( ( tileID == Tile_SPU::rock_Id ) || ( tileID == Tile_SPU::dirt_Id ) || ( tileID == Tile_SPU::unbreakable_Id ) || ( flags & e_flag_NoRender) ) ) continue;
tileID = getTile(iX+1, iY, iZ);
flags = getFlags(iX+1, iY, iZ);
if( !( ( tileID == Tile_SPU::rock_Id ) || ( tileID == Tile_SPU::dirt_Id ) || ( tileID == Tile_SPU::unbreakable_Id ) || ( flags & e_flag_NoRender) ) ) continue;
tileID = getTile(iX, iY, iZ-1);
flags = getFlags(iX, iY, iZ-1);
if( !( ( tileID == Tile_SPU::rock_Id ) || ( tileID == Tile_SPU::dirt_Id ) || ( tileID == Tile_SPU::unbreakable_Id ) || ( flags & e_flag_NoRender) ) ) continue;
tileID = getTile(iX, iY, iZ+1);
flags = getFlags(iX, iY, iZ+1);
if( !( ( tileID == Tile_SPU::rock_Id ) || ( tileID == Tile_SPU::dirt_Id ) || ( tileID == Tile_SPU::unbreakable_Id ) || ( flags & e_flag_NoRender) ) ) continue;
// Treat the bottom of the world differently - we shouldn't ever be able to look up at this, so consider tiles as invisible
// if they are surrounded on sides other than the bottom
if( iY > 0 )
{
tileID = getTile(iX, iY-1, iZ);
flags = getFlags(iX, iY-1, iZ);
if( !( ( tileID == Tile_SPU::rock_Id ) || ( tileID == Tile_SPU::dirt_Id ) || ( tileID == Tile_SPU::unbreakable_Id ) || ( flags & e_flag_NoRender) ) ) continue;
}
tileID = getTile(iX, iY+1, iZ);
flags = getFlags(iX, iY+1, iZ);
if( !( ( tileID == Tile_SPU::rock_Id ) || ( tileID == Tile_SPU::dirt_Id ) || ( tileID == Tile_SPU::unbreakable_Id ) || ( flags & e_flag_NoRender) ) ) continue;
// This tile is surrounded. Flag it as not requiring to be rendered by setting its id to 255.
setFlag(iX, iY, iZ, e_flag_NoRender);
}
}
}
}
#ifndef SN_TARGET_PS3_SPU
void setIconSPUFromIcon(Icon_SPU* iconSpu, Icon* icon)
{
iconSpu->set(icon->getX(), icon->getY(), icon->getWidth(), icon->getHeight(), icon->getSourceWidth(), icon->getSourceHeight());
}
void ChunkRebuildData::buildMaterial(int matSPUIndex, Material* mat)
{
Material_SPU* matSPU = &m_tileData.materials[matSPUIndex];
matSPU->id = matSPUIndex;
matSPU->color = mat->color->col;
matSPU->flags =0;
matSPU->flags |= mat->isFlammable() ? Material_SPU::e_flammable : 0;
matSPU->flags |= mat->isReplaceable() ? Material_SPU::e_replaceable : 0;
matSPU->flags |= mat->_neverBuildable ? Material_SPU::e_neverBuildable : 0;
matSPU->flags |= mat->isSolid() ? Material_SPU::e_isSolid : 0;
matSPU->flags |= mat->isLiquid() ? Material_SPU::e_isLiquid : 0;
matSPU->flags |= mat->blocksLight() ? Material_SPU::e_blocksLight : 0;
matSPU->flags |= mat->blocksMotion() ? Material_SPU::e_blocksMotion : 0;
}
void ChunkRebuildData::buildMaterials()
{
buildMaterial(Material_SPU::air_Id, Material::air);
buildMaterial(Material_SPU::grass_Id, Material::grass);
buildMaterial(Material_SPU::dirt_Id, Material::dirt);
buildMaterial(Material_SPU::wood_Id, Material::wood);
buildMaterial(Material_SPU::stone_Id, Material::stone);
buildMaterial(Material_SPU::metal_Id, Material::metal);
buildMaterial(Material_SPU::water_Id, Material::water);
buildMaterial(Material_SPU::lava_Id, Material::lava);
buildMaterial(Material_SPU::leaves_Id, Material::leaves);
buildMaterial(Material_SPU::plant_Id, Material::plant);
buildMaterial(Material_SPU::replaceable_plant_Id, Material::replaceable_plant);
buildMaterial(Material_SPU::sponge_Id, Material::sponge);
buildMaterial(Material_SPU::cloth_Id, Material::cloth);
buildMaterial(Material_SPU::fire_Id, Material::fire);
buildMaterial(Material_SPU::sand_Id, Material::sand);
buildMaterial(Material_SPU::decoration_Id, Material::decoration);
buildMaterial(Material_SPU::clothDecoration_Id, Material::clothDecoration);
buildMaterial(Material_SPU::glass_Id, Material::glass);
buildMaterial(Material_SPU::explosive_Id, Material::explosive);
buildMaterial(Material_SPU::coral_Id, Material::coral);
buildMaterial(Material_SPU::ice_Id, Material::ice);
buildMaterial(Material_SPU::topSnow_Id, Material::topSnow);
buildMaterial(Material_SPU::snow_Id, Material::snow);
buildMaterial(Material_SPU::cactus_Id, Material::cactus);
buildMaterial(Material_SPU::clay_Id, Material::clay);
buildMaterial(Material_SPU::vegetable_Id, Material::vegetable);
buildMaterial(Material_SPU::egg_Id, Material::egg);
buildMaterial(Material_SPU::portal_Id, Material::portal);
buildMaterial(Material_SPU::cake_Id, Material::cake);
buildMaterial(Material_SPU::web_Id, Material::web);
buildMaterial(Material_SPU::piston_Id, Material::piston);
buildMaterial(Material_SPU::buildable_glass_Id, Material::buildable_glass);
buildMaterial(Material_SPU::heavyMetal_Id, Material::heavyMetal);
}
int ChunkRebuildData::getMaterialID(Tile* pTile)
{
Material* m = pTile->material;
if(m == Material::air) return Material_SPU::air_Id;
if(m == Material::grass) return Material_SPU::grass_Id;
if(m == Material::dirt) return Material_SPU::dirt_Id;
if(m == Material::wood) return Material_SPU::wood_Id;
if(m == Material::stone) return Material_SPU::stone_Id;
if(m == Material::metal) return Material_SPU::metal_Id;
if(m == Material::water) return Material_SPU::water_Id;
if(m == Material::lava) return Material_SPU::lava_Id;
if(m == Material::leaves) return Material_SPU::leaves_Id;
if(m == Material::plant) return Material_SPU::plant_Id;
if(m == Material::replaceable_plant)return Material_SPU::replaceable_plant_Id;
if(m == Material::sponge) return Material_SPU::sponge_Id;
if(m == Material::cloth) return Material_SPU::cloth_Id;
if(m == Material::fire) return Material_SPU::fire_Id;
if(m == Material::sand) return Material_SPU::sand_Id;
if(m == Material::decoration) return Material_SPU::decoration_Id;
if(m == Material::clothDecoration) return Material_SPU::clothDecoration_Id;
if(m == Material::glass) return Material_SPU::glass_Id;
if(m == Material::explosive) return Material_SPU::explosive_Id;
if(m == Material::coral) return Material_SPU::coral_Id;
if(m == Material::ice) return Material_SPU::ice_Id;
if(m == Material::topSnow) return Material_SPU::topSnow_Id;
if(m == Material::snow) return Material_SPU::snow_Id;
if(m == Material::cactus) return Material_SPU::cactus_Id;
if(m == Material::clay) return Material_SPU::clay_Id;
if(m == Material::vegetable) return Material_SPU::vegetable_Id;
if(m == Material::egg) return Material_SPU::egg_Id;
if(m == Material::portal) return Material_SPU::portal_Id;
if(m == Material::cake) return Material_SPU::cake_Id;
if(m == Material::web) return Material_SPU::web_Id;
if(m == Material::piston) return Material_SPU::piston_Id;
if(m == Material::buildable_glass) return Material_SPU::buildable_glass_Id;
if(m == Material::heavyMetal) return Material_SPU::heavyMetal_Id;
assert(0);
return Material_SPU::air_Id;
}
void ChunkRebuildData::createTileData()
{
// build the material data
buildMaterials();
// build the tile data
for(int i=0;i<256;i++)
{
m_tileData.mipmapEnable.set(i, Tile::mipmapEnable[i]);
m_tileData.solid.set(i, Tile::solid[i]);
m_tileData.transculent.set(i, Tile::transculent[i]);
// m_tileData._sendTileData.set(i, Tile::_sendTileData[i]);
m_tileData.propagate.set(i, Tile::propagate[i]);
m_tileData.lightBlock[i] = Tile::lightBlock[i];
m_tileData.lightEmission[i] = Tile::lightEmission[i];
if(Tile::tiles[i])
{
m_tileData.signalSource.set(i, Tile::tiles[i]->isSignalSource());
m_tileData.cubeShaped.set(i, Tile::tiles[i]->isCubeShaped());
m_tileData.xx0[i] = (float)Tile::tiles[i]->getShapeX0();
m_tileData.yy0[i] = (float)Tile::tiles[i]->getShapeY0();
m_tileData.zz0[i] = (float)Tile::tiles[i]->getShapeZ0();
m_tileData.xx1[i] = (float)Tile::tiles[i]->getShapeX1();
m_tileData.yy1[i] = (float)Tile::tiles[i]->getShapeY1();
m_tileData.zz1[i] = (float)Tile::tiles[i]->getShapeZ1();
Icon* pTex = Tile::tiles[i]->icon;
if(pTex)
{
setIconSPUFromIcon(&m_tileData.iconData[i], pTex);
}
m_tileData.materialIDs[i] = getMaterialID(Tile::tiles[i]);
}
}
m_tileData.leafTile_allowSame = Tile::leaves->allowSame;
m_tileData.leafTile_fancyTextureSet = Tile::leaves->fancyTextureSet;
// Custom tile textures
// get the width and height of any texture, since everything uses the same texture
m_tileData.iconTexWidth = Tile::grass->iconTop->getSourceWidth();
m_tileData.iconTexHeight = Tile::grass->iconTop->getSourceHeight();
// Grass tile
setIconSPUFromIcon(&m_tileData.grass_iconTop, Tile::grass->iconTop);
setIconSPUFromIcon(&m_tileData.grass_iconSnowSide, Tile::grass->iconSnowSide);
setIconSPUFromIcon(&m_tileData.grass_iconSideOverlay, Tile::grass->iconSideOverlay);
// ThinFence
setIconSPUFromIcon(&m_tileData.ironFence_EdgeTexture, ((ThinFenceTile*)Tile::ironFence)->getEdgeTexture());
setIconSPUFromIcon(&m_tileData.thinGlass_EdgeTexture, ((ThinFenceTile*)Tile::thinGlass)->getEdgeTexture());
//FarmTile
setIconSPUFromIcon(&m_tileData.farmTile_Dry, ((FarmTile*)Tile::farmland)->iconDry);
setIconSPUFromIcon(&m_tileData.farmTile_Wet, ((FarmTile*)Tile::farmland)->iconWet);
// DoorTile
for(int i=0;i<8; i++)
{
setIconSPUFromIcon(&m_tileData.doorTile_Icons[i], ((DoorTile*)Tile::door_wood)->icons[i]);
// we're not supporting flipped icons, so manually flip here
if(i>=4)
m_tileData.doorTile_Icons[i].flipHorizontal();
}
// TallGrass
for(int i=0;i<3; i++)
setIconSPUFromIcon(&m_tileData.tallGrass_Icons[i], Tile::tallgrass->icons[i]);
// SandStoneTile
for(int i=0;i<3; i++)
setIconSPUFromIcon(&m_tileData.sandStone_icons[i], ((SandStoneTile*)Tile::sandStone)->icons[i]);
setIconSPUFromIcon(&m_tileData.sandStone_iconTop, ((SandStoneTile*)Tile::sandStone)->iconTop);
setIconSPUFromIcon(&m_tileData.sandStone_iconBottom, ((SandStoneTile*)Tile::sandStone)->iconBottom);
// WoodTile
// assert(WoodTile_SPU::WOOD_NAMES_LENGTH == 4);
for(int i=0;i<4; i++)
setIconSPUFromIcon(&m_tileData.woodTile_icons[i], ((WoodTile*)Tile::wood)->icons[i]);
// TreeTile
// assert(TreeTile_SPU::TREE_NAMES_LENGTH == 4);
for(int i=0;i<4; i++)
setIconSPUFromIcon(&m_tileData.treeTile_icons[i], ((TreeTile*)Tile::treeTrunk)->icons[i]);
setIconSPUFromIcon(&m_tileData.treeTile_iconTop, ((TreeTile*)Tile::treeTrunk)->iconTop);
// LeafTile
for(int i=0;i<2; i++)
for(int j=0;j<4;j++)
setIconSPUFromIcon(&m_tileData.leafTile_icons[i][j], ((LeafTile*)Tile::leaves)->icons[i][j]);
// CropTile
for(int i=0;i<8; i++)
setIconSPUFromIcon(&m_tileData.cropTile_icons[i], ((CropTile*)Tile::crops)->icons[i]);
// FurnaceTile
setIconSPUFromIcon(&m_tileData.furnaceTile_iconTop, ((FurnaceTile*)Tile::furnace)->iconTop);
setIconSPUFromIcon(&m_tileData.furnaceTile_iconFront, ((FurnaceTile*)Tile::furnace)->iconFront);
setIconSPUFromIcon(&m_tileData.furnaceTile_iconFront_lit, ((FurnaceTile*)Tile::furnace_lit)->iconFront);
//LiquidTile
setIconSPUFromIcon(&m_tileData.liquidTile_iconWaterStill, (Tile::water)->icons[0]);
setIconSPUFromIcon(&m_tileData.liquidTile_iconWaterFlow, (Tile::water)->icons[1]);
setIconSPUFromIcon(&m_tileData.liquidTile_iconLavaStill, (Tile::lava)->icons[0]);
setIconSPUFromIcon(&m_tileData.liquidTile_iconLavaFlow, (Tile::lava)->icons[1]);
//FireTile
for(int i=0;i<2;i++)
setIconSPUFromIcon(&m_tileData.fireTile_icons[i], (Tile::fire)->icons[i]);
// Sapling
for(int i=0;i<4;i++)
setIconSPUFromIcon(&m_tileData.sapling_icons[i], ((Sapling*)Tile::sapling)->icons[i]);
m_tileData.glassTile_allowSame = ((GlassTile*)Tile::glass)->allowSame;
m_tileData.iceTile_allowSame = ((IceTile*)Tile::ice)->allowSame;
// DispenserTile
setIconSPUFromIcon(&m_tileData.dispenserTile_iconTop, ((DispenserTile*)Tile::dispenser)->iconTop);
setIconSPUFromIcon(&m_tileData.dispenserTile_iconFront, ((DispenserTile*)Tile::dispenser)->iconFront);
setIconSPUFromIcon(&m_tileData.dispenserTile_iconFrontVertical, ((DispenserTile*)Tile::dispenser)->iconFrontVertical);
// RailTile
setIconSPUFromIcon(&m_tileData.railTile_iconTurn, ((RailTile*)Tile::rail)->iconTurn);
setIconSPUFromIcon(&m_tileData.railTile_iconTurnGolden, ((RailTile*)Tile::goldenRail)->iconTurn);
for(int i=0;i<2;i++)
setIconSPUFromIcon(&m_tileData.detectorRailTile_icons[i], ((DetectorRailTile*)Tile::detectorRail)->icons[i]);
// tntTile
setIconSPUFromIcon(&m_tileData.tntTile_iconBottom, ((TntTile*)Tile::tnt)->iconBottom);
setIconSPUFromIcon(&m_tileData.tntTile_iconTop, ((TntTile*)Tile::tnt)->iconTop);
// workbenchTile
setIconSPUFromIcon(&m_tileData.workBench_iconFront, ((WorkbenchTile*)Tile::workBench)->iconFront);
setIconSPUFromIcon(&m_tileData.workBench_iconTop, ((WorkbenchTile*)Tile::workBench)->iconTop);
// cactusTile
setIconSPUFromIcon(&m_tileData.cactusTile_iconTop, ((CactusTile*)Tile::cactus)->iconTop);
setIconSPUFromIcon(&m_tileData.cactusTile_iconBottom, ((CactusTile*)Tile::cactus)->iconBottom);
// recordPlayer
setIconSPUFromIcon(&m_tileData.recordPlayer_iconTop, ((RecordPlayerTile*)Tile::recordPlayer)->iconTop);
// pumpkin
setIconSPUFromIcon(&m_tileData.pumpkinTile_iconTop, ((PumpkinTile*)Tile::pumpkin)->iconTop);
setIconSPUFromIcon(&m_tileData.pumpkinTile_iconFace, ((PumpkinTile*)Tile::pumpkin)->iconFace);
setIconSPUFromIcon(&m_tileData.pumpkinTile_iconFaceLit, ((PumpkinTile*)Tile::litPumpkin)->iconFace);
// cakeTile
setIconSPUFromIcon(&m_tileData.cakeTile_iconTop, ((CakeTile*)Tile::cake)->iconTop);
setIconSPUFromIcon(&m_tileData.cakeTile_iconBottom, ((CakeTile*)Tile::cake)->iconBottom);
setIconSPUFromIcon(&m_tileData.cakeTile_iconInner, ((CakeTile*)Tile::cake)->iconInner);
// SmoothStoneBrickTile
for(int i=0;i<4;i++)
setIconSPUFromIcon(&m_tileData.smoothStoneBrick_icons[i], ((SmoothStoneBrickTile*)Tile::stoneBrickSmooth)->icons[i]);
// HugeMushroomTile
for(int i=0;i<2;i++)
setIconSPUFromIcon(&m_tileData.hugeMushroom_icons[i], ((HugeMushroomTile*)Tile::hugeMushroom1)->icons[i]);
setIconSPUFromIcon(&m_tileData.hugeMushroom_iconStem, ((HugeMushroomTile*)Tile::hugeMushroom1)->iconStem);
setIconSPUFromIcon(&m_tileData.hugeMushroom_iconInside, ((HugeMushroomTile*)Tile::hugeMushroom1)->iconInside);
// MelonTile
setIconSPUFromIcon(&m_tileData.melonTile_iconTop, ((MelonTile*)Tile::melon)->iconTop);
// StemTile
setIconSPUFromIcon(&m_tileData.stemTile_iconAngled, ((StemTile*)Tile::melonStem)->iconAngled);
// MycelTile
setIconSPUFromIcon(&m_tileData.mycelTile_iconTop, (Tile::mycel)->iconTop);
setIconSPUFromIcon(&m_tileData.mycelTile_iconSnowSide, (Tile::mycel)->iconSnowSide);
// NetherStalkTile
for(int i=0;i<3;i++)
setIconSPUFromIcon(&m_tileData.netherStalk_icons[i], ((NetherStalkTile*)Tile::netherStalk)->icons[i]);
// EnchantmentTableTile
setIconSPUFromIcon(&m_tileData.enchantmentTable_iconTop, ((EnchantmentTableTile*)Tile::enchantTable)->iconTop);
setIconSPUFromIcon(&m_tileData.enchantmentTable_iconBottom, ((EnchantmentTableTile*)Tile::enchantTable)->iconBottom);
//BrewingStandTile
setIconSPUFromIcon(&m_tileData.brewingStand_iconBase, ((BrewingStandTile*)Tile::brewingStand)->iconBase);
//RedStoneDust
setIconSPUFromIcon(&m_tileData.redStoneDust_iconCross, (Tile::redStoneDust)->iconCross);
setIconSPUFromIcon(&m_tileData.redStoneDust_iconCross, (Tile::redStoneDust)->iconLine);
setIconSPUFromIcon(&m_tileData.redStoneDust_iconCrossOver, (Tile::redStoneDust)->iconCrossOver);
setIconSPUFromIcon(&m_tileData.redStoneDust_iconLineOver, (Tile::redStoneDust)->iconLineOver);
setIconSPUFromIcon(&m_tileData.stoneSlab_iconSide, ((StoneSlabTile*)(Tile::stoneSlab))->iconSide);
for(int i=0;i<16;i++)
setIconSPUFromIcon(&m_tileData.clothTile_icons[i], ((ClothTile*)Tile::cloth)->icons[i]);
// CarrotTile
for(int i=0;i<4;i++)
setIconSPUFromIcon(&m_tileData.carrot_icons[i], ((CarrotTile*)Tile::carrots)->icons[i]);
// PotatoTile
for(int i=0;i<4;i++)
setIconSPUFromIcon(&m_tileData.potato_icons[i], ((PotatoTile*)Tile::potatoes)->icons[i]);
// AnvilTile
for(int i=0;i<3;i++)
setIconSPUFromIcon(&m_tileData.anvil_icons[i], ((AnvilTile*)Tile::anvil)->icons[i]);
// QuartzBlockTile
for(int i=0;i<5;i++)
setIconSPUFromIcon(&m_tileData.quartzBlock_icons[i], ((QuartzBlockTile*)Tile::quartzBlock)->icons[i]);
setIconSPUFromIcon(&m_tileData.quartzBlock_iconChiseledTop, ((QuartzBlockTile*)Tile::quartzBlock)->iconChiseledTop);
setIconSPUFromIcon(&m_tileData.quartzBlock_iconLinesTop, ((QuartzBlockTile*)Tile::quartzBlock)->iconLinesTop);
setIconSPUFromIcon(&m_tileData.quartzBlock_iconTop, ((QuartzBlockTile*)Tile::quartzBlock)->iconTop);
setIconSPUFromIcon(&m_tileData.quartzBlock_iconBottom, ((QuartzBlockTile*)Tile::quartzBlock)->iconBottom);
}
// extern int g_lastHitBlockX;
// extern int g_lastHitBlockY;
// extern int g_lastHitBlockZ;
void ChunkRebuildData::buildForChunk( Region* region, Level* level, int x0, int y0, int z0 )
{
static bool bCreatedTileData = false;
if(!bCreatedTileData)
{
createTileData();
bCreatedTileData = true;
}
m_tileData.stemTile_minColour = Minecraft::GetInstance()->getColourTable()->getColor( eMinecraftColour_Tile_StemMin );
m_tileData.stemTile_maxColour = Minecraft::GetInstance()->getColourTable()->getColor( eMinecraftColour_Tile_StemMax );
m_tileData.waterLily_colour = Minecraft::GetInstance()->getColourTable()->getColor( eMinecraftColour_Tile_WaterLily );
m_tileData.foliageColor_evergreenColor = FoliageColor::getEvergreenColor();
m_tileData.foliageColor_birchColor = FoliageColor::getBirchColor();
// m_lastHitBlockX = g_lastHitBlockX;
// m_lastHitBlockY = g_lastHitBlockY;
// m_lastHitBlockZ = g_lastHitBlockZ;
m_x0 = x0-2;
m_y0 = y0-2;
m_z0 = z0-2;
m_pRegion = region;
m_flags = 0;//e_flag_EmptyChunk;
// for(int iX=m_x0; iX<(m_x0+sc_size); iX++)
// {
// for(int iY=m_y0; iY<(m_y0+sc_size); iY++)
// {
// for(int iZ=m_z0; iZ<(m_z0+sc_size); iZ++)
// {
// buildTile(iX, iY, iZ);
// }
// }
// }
BiomeCache::Block* cacheBlocks[9];
cacheBlocks[0] = region->getBiomeSource()->getBlockAt(m_x0, m_z0);
cacheBlocks[1] = region->getBiomeSource()->getBlockAt(m_x0+2, m_z0);
cacheBlocks[2] = region->getBiomeSource()->getBlockAt(m_x0+18, m_z0);
cacheBlocks[3] = region->getBiomeSource()->getBlockAt(m_x0, m_z0+2);
cacheBlocks[4] = region->getBiomeSource()->getBlockAt(m_x0+2, m_z0+2);
cacheBlocks[5] = region->getBiomeSource()->getBlockAt(m_x0+18, m_z0+2);
cacheBlocks[6] = region->getBiomeSource()->getBlockAt(m_x0, m_z0+18);
cacheBlocks[7] = region->getBiomeSource()->getBlockAt(m_x0+2, m_z0+18);
cacheBlocks[8] = region->getBiomeSource()->getBlockAt(m_x0+18, m_z0+18);
int cacheMap[20] = { 0,0, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 2,2};
ColourTable* pColourTable = Minecraft::GetInstance()->getColourTable();
for(int iX=m_x0; iX<(m_x0+sc_size); iX++)
{
for(int iZ=m_z0; iZ<(m_z0+sc_size); iZ++)
{
int newX = ( iX - m_x0 );
int newZ = ( iZ - m_z0 );
int index = (newX*sc_size) + newZ;
// assert(index < 400);
int cacheBlockIndex = (cacheMap[iZ-m_z0]*3) + cacheMap[iX-m_x0];
BiomeCache::Block* pCacheBlock = cacheBlocks[cacheBlockIndex];
// assert(region->getBiomeSource()->getBlockAt(iX, iZ) == pCacheBlock);
Biome* pBiome = pCacheBlock->getBiome(iX, iZ);
m_grassColor[index] = pColourTable->getColor(pBiome->m_grassColor);
m_foliageColor[index] = pColourTable->getColor(pBiome->m_foliageColor);
m_waterColor[index] = pColourTable->getColor(pBiome->m_waterColor);
}
}
if(isEmptyChunk())
return;
if(level->dimension->hasCeiling)
m_flags |= e_flag_HasCeiling;
for(int i=0;i<16;i++)
m_brightnessRamp[i] = level->dimension->brightnessRamp[i];
m_levelSkyDarken = level->skyDarken;
}
void ChunkRebuildData::copyFromTesselator()
{
Tesselator* t = Tesselator::getInstance(); // 4J - added - static initialiser being set at the wrong time
m_tesselator.m_PPUArray = t->_array->data;
assert(t->p == 0);
m_tesselator.m_PPUOffset = 0;
// copy tesselator vars over
m_tesselator.vertices = t->vertices;
m_tesselator.u = t->u;
m_tesselator.v = t->v;
m_tesselator._tex2 = t->_tex2;
m_tesselator.col = t->col;
m_tesselator.hasColor = t->hasColor;
m_tesselator.hasTexture = t->hasTexture;
m_tesselator.hasTexture2 = t->hasTexture2;
m_tesselator.hasNormal = t->hasNormal;
m_tesselator.p = t->p;
m_tesselator.useCompactFormat360 = t->useCompactFormat360;
m_tesselator.useProjectedTexturePixelShader = t->useProjectedTexturePixelShader;
m_tesselator.count = t->count;
m_tesselator._noColor = t->_noColor;
m_tesselator.mode = t->mode;
m_tesselator.xo = t->xo;
m_tesselator.yo = t->yo;
m_tesselator.zo = t->zo;
m_tesselator.count = t->count ;
m_tesselator._normal = t->_normal;
m_tesselator.tesselating = t->tesselating;
m_tesselator.mipmapEnable = t->mipmapEnable; // 4J added
m_tesselator.vboId = t->vboId;
m_tesselator.vboCounts = t->vboCounts;
m_tesselator.size = t->size;
for(int i=0;i<6;i++)
m_tesselator.bounds.boundingBox[i] = t->bounds.boundingBox[i];
}
void ChunkRebuildData::buildTile(int x, int y, int z)
{
int newX = ( x - m_x0 );
int newY = ( y - m_y0 );
int newZ = ( z - m_z0 );
int index = (newX*sc_size*sc_size) + (newY*sc_size) + newZ;
m_tileIds[index] = m_pRegion->getTile(x, y, z);
m_brightness[index] = m_pRegion->getBrightness(LightLayer::Sky, x, y, z);
m_brightness[index] |= (m_pRegion->getBrightness(LightLayer::Block, x, y, z)) << 4;
m_data_flags[index] = m_pRegion->getData(x,y,z);
}
void ChunkRebuildData::storeInTesselator()
{
Tesselator* t = Tesselator::getInstance(); // 4J - added - static initialiser being set at the wrong time
// copy tesselator vars over
t->vertices = m_tesselator.vertices;
t->u = m_tesselator.u;
t->v = m_tesselator.v;
t->_tex2 = m_tesselator._tex2;
t->col = m_tesselator.col;
t->hasColor = m_tesselator.hasColor;
t->hasTexture = m_tesselator.hasTexture;
t->hasTexture2 = m_tesselator.hasTexture2;
t->hasNormal = m_tesselator.hasNormal;
t->p = m_tesselator.m_PPUOffset/4;
t->useCompactFormat360 = m_tesselator.useCompactFormat360;
t->useProjectedTexturePixelShader = m_tesselator.useProjectedTexturePixelShader;
t->count = m_tesselator.count;
t->_noColor = m_tesselator._noColor;
t->mode = m_tesselator.mode;
t->xo = m_tesselator.xo;
t->yo = m_tesselator.yo;
t->zo = m_tesselator.zo;
t->count = m_tesselator.count;
t->_normal = m_tesselator._normal;
t->tesselating = m_tesselator.tesselating;
t->mipmapEnable = m_tesselator.mipmapEnable; // 4J added
t->vboId = m_tesselator.vboId;
t->vboCounts = m_tesselator.vboCounts;
t->size = m_tesselator.size;
for(int i=0;i<6;i++)
t->bounds.boundingBox[i] = m_tesselator.bounds.boundingBox[i];
}
#endif // SN_TARGET_PS3_SPU
void ChunkRebuildData::tesselateAllTiles(TileRenderer_SPU* pTileRenderer)
{
Tile_SPU::ms_pTileData = &m_tileData;
// 4J - changed loop order here to leave y as the innermost loop for better cache performance
bool renderNextLayer = false;
bool rendered = false;
int numRenderedLayer0 = 0;
int startX = m_x0+2; // beginning of the chunk
int startY = m_y0+2; // beginning of the chunk
int startZ = m_z0+2; // beginning of the chunk
m_tesselator.beginData();
for (int z = startZ; z < (startZ+16); z++)
{
for (int x = startX; x < (startX+16); x++)
{
for (int y = startY; y < (startY+16); y++)
{
// 4J - get tile from those copied into our local array in earlier optimisation
int flags = getFlags(x,y,z);
if(flags & ChunkRebuildData::e_flag_NoRender)
continue;
unsigned char tileId = getTile(x,y,z);
if (tileId > 0)
{
// if (m_currentLayer == 0 && m_tileData.isEntityTile[tileId])
// {
// shared_ptr<TileEntity> et = region->getTileEntity(x, y, z);
// if (TileEntityRenderDispatcher::instance->hasRenderer(et))
// {
// renderableTileEntities.push_back(et);
// }
// }
TileRef_SPU tile(tileId);
int renderLayer = tile->getRenderLayer();
if (renderLayer != m_currentLayer)
{
renderNextLayer = true;
}
else //if (renderLayer == m_currentLayer)
{
if(pTileRenderer->hasRenderer(tile.getPtr()))
{
numRenderedLayer0++;
rendered |= pTileRenderer->tesselateInWorld(tile.getPtr(), x, y, z);
}
else
{
setFlag(x, y, z, e_flag_SPURenderCodeMissing);
// #ifdef SN_TARGET_PS3_SPU
// spu_print("Render code missing for tile ID %d : render shape %d\n", tile->id, tile->getRenderShape());
// #endif
}
}
}
}
}
}
if(rendered)
m_flags |= e_flag_Rendered;
// spu_print("(%d,%d,%d) SPU num rendered : %d\n", m_x0+2, m_y0+2, m_z0+2, numRenderedLayer0);
m_tesselator.endData();
}
bool ChunkRebuildData::isEmptyTile(int x, int y, int z)
{
return getTile(x, y, z) == 0;
}
bool ChunkRebuildData::isSolidRenderTile(int x, int y, int z)
{
TileRef_SPU tile(getTile(x,y,z));
if (tile.getPtr() == NULL) return false;
// 4J - addition here to make rendering big blocks of leaves more efficient. Normally leaves never consider themselves as solid, so
// blocks of leaves will have all sides of each block completely visible. Changing to consider as solid if this block is surrounded by
// other leaves. This is paired with another change in Tile::getTexture which makes such solid tiles actually visibly solid (these
// textures exist already for non-fancy graphics). Note: this tile-specific code is here rather than making some new virtual method in the tiles,
// for the sake of efficiency - I don't imagine we'll be doing much more of this sort of thing
if( tile->id == Tile_SPU::leaves_Id )
{
int axo[6] = { 1,-1, 0, 0, 0, 0};
int ayo[6] = { 0, 0, 1,-1, 0, 0};
int azo[6] = { 0, 0, 0, 0, 1,-1};
for( int i = 0; i < 6; i++ )
{
int t = getTile(x + axo[i], y + ayo[i] , z + azo[i]);
if( ( t != Tile_SPU::leaves_Id ) && ( ( Tile_SPU::m_tiles[t].id == -1) || !Tile_SPU::m_tiles[t].isSolidRender() ) )
{
return false;
}
}
return true;
}
return tile->isSolidRender();
}
bool ChunkRebuildData::isSolidBlockingTile(int x, int y, int z)
{
TileRef_SPU tile(getTile(x, y, z));
if (tile.getPtr() == NULL) return false;
bool ret = tile->getMaterial()->blocksMotion() && tile->isCubeShaped();
return ret;
}
float ChunkRebuildData::getBrightness(int x, int y, int z, int emitt)
{
int n = getRawBrightness(x, y, z);
if (n < emitt) n = emitt;
return m_brightnessRamp[n];
}
float ChunkRebuildData::getBrightness(int x, int y, int z)
{
return m_brightnessRamp[getRawBrightness(x, y, z)];
}
// 4J - brought forward from 1.8.2
int ChunkRebuildData::getBrightness(LightLayer::variety layer, int x, int y, int z)
{
#ifndef SN_TARGET_PS3_SPU
assert(Level_MAX_LEVEL_SIZE == Level::MAX_LEVEL_SIZE);
assert(Level_maxBuildHeight == Level::maxBuildHeight);
assert(Level_MAX_BRIGHTNESS == Level::MAX_BRIGHTNESS);
#endif
if (y < 0) y = 0;
if (y >= Level_maxBuildHeight) y = Level_maxBuildHeight - 1;
if (y < 0 || y >= Level_maxBuildHeight || x < -Level_MAX_LEVEL_SIZE || z < -Level_MAX_LEVEL_SIZE || x >= Level_MAX_LEVEL_SIZE || z > Level_MAX_LEVEL_SIZE)
{
// 4J Stu - The java LightLayer was an enum class type with a member "surrounding" which is what we
// were returning here. Surrounding has the same value as the enum value in our C++ code, so just cast
// it to an int
return (int)layer;
}
if(layer == LightLayer::Sky)
return getBrightnessSky(x, y, z);
return getBrightnessBlock(x, y, z);
}
// 4J - brought forward from 1.8.2
int ChunkRebuildData::getBrightnessPropagate(LightLayer::variety layer, int x, int y, int z)
{
if (y < 0) y = 0;
if (y >= Level_maxBuildHeight) y = Level_maxBuildHeight - 1;
if (y < 0 || y >= Level_maxBuildHeight || x < -Level_MAX_LEVEL_SIZE || z < -Level_MAX_LEVEL_SIZE || x >= Level_MAX_LEVEL_SIZE || z > Level_MAX_LEVEL_SIZE)
{
// 4J Stu - The java LightLayer was an enum class type with a member "surrounding" which is what we
// were returning here. Surrounding has the same value as the enum value in our C++ code, so just cast
// it to an int
return (int)layer;
}
{
int id = getTile(x, y, z);
if (m_tileData.propagate[getTile(x, y, z)])
{
int br = getBrightness(layer, x, y + 1, z);
int br1 = getBrightness(layer, x + 1, y, z);
int br2 = getBrightness(layer, x - 1, y, z);
int br3 = getBrightness(layer, x, y, z + 1);
int br4 = getBrightness(layer, x, y, z - 1);
if (br1 > br) br = br1;
if (br2 > br) br = br2;
if (br3 > br) br = br3;
if (br4 > br) br = br4;
return br;
}
}
if(layer == LightLayer::Sky)
return getBrightnessSky(x, y, z);
return getBrightnessBlock(x, y, z);
}
int ChunkRebuildData::getLightColor(int x, int y, int z, int emitt) // 4J - change brought forward from 1.8.2
{
int s = getBrightnessPropagate(LightLayer::Sky, x, y, z);
int b = getBrightnessPropagate(LightLayer::Block, x, y, z);
if (b < emitt) b = emitt;
return s << 20 | b << 4;
}
int ChunkRebuildData::getRawBrightness(int x, int y, int z)
{
return getRawBrightness(x, y, z, true);
}
int ChunkRebuildData::getRawBrightness(int x, int y, int z, bool propagate)
{
if (x < -Level_MAX_LEVEL_SIZE || z < -Level_MAX_LEVEL_SIZE || x >= Level_MAX_LEVEL_SIZE || z > Level_MAX_LEVEL_SIZE)
{
return Level_MAX_BRIGHTNESS;
}
if (propagate)
{
int id = getTile(x, y, z);
switch(id)
{
case Tile_SPU::stoneSlabHalf_Id:
case Tile_SPU::woodSlabHalf_Id:
case Tile_SPU::farmland_Id:
case Tile_SPU::stairs_stone_Id:
case Tile_SPU::stairs_wood_Id:
{
int br = getRawBrightness(x, y + 1, z, false);
int br1 = getRawBrightness(x + 1, y, z, false);
int br2 = getRawBrightness(x - 1, y, z, false);
int br3 = getRawBrightness(x, y, z + 1, false);
int br4 = getRawBrightness(x, y, z - 1, false);
if (br1 > br) br = br1;
if (br2 > br) br = br2;
if (br3 > br) br = br3;
if (br4 > br) br = br4;
return br;
}
break;
}
}
if (y < 0) return 0;
if (y >= Level_maxBuildHeight)
{
int br = Level_MAX_BRIGHTNESS - m_levelSkyDarken;
if (br < 0) br = 0;
return br;
}
return LevelChunk_getRawBrightness(x, y, z, m_levelSkyDarken);
}
int ChunkRebuildData::LevelChunk_getRawBrightness(int x, int y, int z, int skyDampen)
{
int light = (m_flags & e_flag_HasCeiling) ? 0 : getBrightnessSky(x, y, z);
if (light > 0)
m_flags |= e_flag_TouchedSky;
light -= skyDampen;
int block = getBrightnessBlock(x, y, z);
if (block > light) light = block;
/*
* int xd = (absFloor(level.player.x-(this->x*16+x))); int yd =
* (absFloor(level.player.y-(y))); int zd =
* (absFloor(level.player.z-(this->z*16+z))); int dd = xd+yd+zd; if
* (dd<15){ int carried = 15-dd; if (carried<0) carried = 0; if
* (carried>15) carried = 15; if (carried > light) light = carried; }
*/
return light;
}
Material_SPU *ChunkRebuildData::getMaterial(int x, int y, int z)
{
int t = getTile(x, y, z);
int matID = Material_SPU::air_Id;
if (t != 0)
matID = m_tileData.materialIDs[t];
return &m_tileData.materials[matID];
}