From 5b9935f737c226847e668bde0185adbc6a5a8b7b Mon Sep 17 00:00:00 2001 From: Foghrye4 Date: Wed, 5 Apr 2017 20:41:13 +0300 Subject: some experiments --- ihl/enviroment/LightBulbBlock.java | 5 +- ihl/enviroment/LightBulbTileEntity.java | 40 ++++++++-- ihl/enviroment/LightHandler.java | 134 ++++++++++++++++++++++++++++++++ ihl/enviroment/LightSource.java | 78 +++++++++++++++++++ ihl/enviroment/SpotlightTileEntity.java | 4 +- 5 files changed, 252 insertions(+), 9 deletions(-) create mode 100644 ihl/enviroment/LightHandler.java create mode 100644 ihl/enviroment/LightSource.java (limited to 'ihl/enviroment') diff --git a/ihl/enviroment/LightBulbBlock.java b/ihl/enviroment/LightBulbBlock.java index 77ee8f8..720ca4e 100644 --- a/ihl/enviroment/LightBulbBlock.java +++ b/ihl/enviroment/LightBulbBlock.java @@ -25,6 +25,7 @@ public class LightBulbBlock extends Block implements ITileEntityProvider { this.setResistance(0.5F); this.setCreativeTab(IHLCreativeTab.tab); this.setBlockTextureName("glass"); + this.setLightOpacity(16); } @Override @@ -108,11 +109,11 @@ public class LightBulbBlock extends Block implements ITileEntityProvider { } public int getLightValue(IBlockAccess world, int x, int y, int z) { - TileEntity te = world.getTileEntity(x, y, z); +/* TileEntity te = world.getTileEntity(x, y, z); if (te != null && te instanceof LightBulbTileEntity) { LightBulbTileEntity ate = (LightBulbTileEntity) te; return ate.getActive() ? 15 : 0; - } + }*/ return 0; } } diff --git a/ihl/enviroment/LightBulbTileEntity.java b/ihl/enviroment/LightBulbTileEntity.java index 283a72f..f2c229b 100644 --- a/ihl/enviroment/LightBulbTileEntity.java +++ b/ihl/enviroment/LightBulbTileEntity.java @@ -3,6 +3,8 @@ package ihl.enviroment; import java.util.List; import java.util.Vector; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -14,12 +16,17 @@ import ic2.api.energy.event.EnergyTileLoadEvent; import ic2.api.energy.event.EnergyTileUnloadEvent; import ic2.api.energy.tile.IEnergySink; import ic2.api.network.INetworkDataProvider; +import ic2.api.network.INetworkTileEntityEventListener; import ic2.api.tile.IWrenchable; import ic2.core.IC2; import ic2.core.ITickCallback; +import ihl.ClientProxy; +import ihl.IHLMod; +import ihl.IHLModInfo; +import ihl.model.RenderBlocksExt; import ihl.utils.IHLUtils; -public class LightBulbTileEntity extends TileEntity implements IEnergySink, IWrenchable, INetworkDataProvider { +public class LightBulbTileEntity extends TileEntity implements IEnergySink, IWrenchable, INetworkDataProvider, INetworkTileEntityEventListener { private boolean active = false; private short facing = 0; public boolean prevActive = false; @@ -28,6 +35,8 @@ public class LightBulbTileEntity extends TileEntity implements IEnergySink, IWre public boolean addedToEnergyNet = false; private boolean loaded = false; private int ticker; + @SideOnly(value = Side.CLIENT) + LightSource lightSource; @Override public void readFromNBT(NBTTagCompound nbttagcompound) { @@ -99,7 +108,7 @@ public class LightBulbTileEntity extends TileEntity implements IEnergySink, IWre this.addedToEnergyNet = false; } this.active = false; - this.updateLightState(true); + this.updateLightState(); } } @@ -123,9 +132,18 @@ public class LightBulbTileEntity extends TileEntity implements IEnergySink, IWre } } - protected void updateLightState(boolean spreadDarkness) { + protected void updateLightState() { if (IC2.platform.isSimulating()) { worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); + } else if (IC2.platform.isRendering()) { + if (lightSource == null && this.getActive()) { + lightSource = ((ClientProxy) IHLMod.proxy).getLightHandler().calculateOmniLightSource(worldObj, xCoord, + yCoord, zCoord, 8096, 255, 255, 0); + ((ClientProxy) IHLMod.proxy).getLightHandler().addLightSource(lightSource); + } else if (lightSource != null) { + ((ClientProxy) IHLMod.proxy).getLightHandler().removeLightSource(lightSource); + lightSource = null; + } } } @@ -230,10 +248,10 @@ public class LightBulbTileEntity extends TileEntity implements IEnergySink, IWre public void setActive(boolean active1) { this.active = active1; - if (this.prevActive != active1) { IC2.network.get().updateTileEntityField(this, "active"); - updateLightState(!active1); + IC2.network.get().initiateTileEntityEvent(this, active1?1:0, true); + updateLightState(); } this.prevActive = active1; } @@ -242,4 +260,16 @@ public class LightBulbTileEntity extends TileEntity implements IEnergySink, IWre this.active = active1; this.prevActive = active1; } + + @Override + public void onNetworkEvent(int event) + { + boolean active1 = event==1; + this.active = active1; + if (this.prevActive != active1) { + updateLightState(); + } + this.prevActive = active1; + } + } diff --git a/ihl/enviroment/LightHandler.java b/ihl/enviroment/LightHandler.java new file mode 100644 index 0000000..b3f8da6 --- /dev/null +++ b/ihl/enviroment/LightHandler.java @@ -0,0 +1,134 @@ +package ihl.enviroment; + +import java.util.BitSet; +import java.util.HashSet; +import java.util.Set; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import ihl.IHLMod; +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.world.World; + +@SideOnly(value = Side.CLIENT) +public class LightHandler { + + private int[][] directionMasks; + private int[][] vectors; + private int bits; + private int halfValue; + + private int lightBitsPerDimension = 10; + private int maxLightRadius = (1 << lightBitsPerDimension - 1) - 1; + private int bitmask = (1 << lightBitsPerDimension) - 1; + public final Set lightSources = new HashSet(); + + public LightHandler() { + this.directionMasks = IHLMod.explosionHandler.directionMasks; + this.vectors = IHLMod.explosionHandler.vectors; + this.bits = IHLMod.explosionHandler.bits; + this.halfValue = IHLMod.explosionHandler.halfValue; + } + + public int encodeXYZ(int x, int y, int z) { + return x + maxLightRadius << lightBitsPerDimension * 2 | y + maxLightRadius << lightBitsPerDimension + | z + maxLightRadius; + } + + public int[] decodeXYZ(int l) { + return new int[] { (l >>> lightBitsPerDimension * 2) - maxLightRadius, + ((l >>> lightBitsPerDimension) & bitmask) - maxLightRadius, (l & bitmask) - maxLightRadius }; + } + + public LightSource calculateOmniLightSource(World world, int sourceX, int sourceY, int sourceZ, int power, int red, + int green, int blue) { + LightSource lightSource = new LightSource(sourceX, sourceY, sourceZ, red, green, blue, power); + int[] borders = { sourceX, sourceY, sourceZ, sourceX, sourceY, sourceZ }; + int[] evSource = { sourceX, sourceY, sourceZ }; + int[] lightSourceXYZ = { sourceX, sourceY, sourceZ }; + for (int i = 0; i < directionMasks.length; i++) { + int[] directionMask = directionMasks[i]; + this.litBlocksAndGetDescendants(world, evSource, lightSourceXYZ, lightSource.illuminatedBlocks, 0, power, + directionMask, borders); + } + lightSource.setBorders(borders[0], borders[1], borders[2], borders[3], borders[4], borders[5]); + return lightSource; + } + + private void litBlocksAndGetDescendants(World world, int[] evSource, int[] lightSource, BitSet illuminatedBlocksSet, + int ev, int power, int[] directionMask, int[] borders) { + power = this.getNewPower(world, ev, evSource, lightSource, power, directionMask, illuminatedBlocksSet, borders); + power = (power<<1)/3 - 1; + if (power > 1) { + if (vectors[ev][0] == 0) { + int[] xyz = IHLMod.explosionHandler.decodeXYZ(ev); + int xb = xyz[0] >> bits - 1; + int yb = xyz[1] >> bits - 1; + int zb = xyz[2] >> bits - 1; + int hashb = xb << 2 | yb << 1 | zb; + xyz[0] -= xb * halfValue; + xyz[1] -= yb * halfValue; + xyz[2] -= zb * halfValue; + if (hashb == 0 || xb > 1 || yb > 1 || zb > 1) { + throw new ArithmeticException("End vectors shall be higher than half value"); + } + int ev2 = IHLMod.explosionHandler.encodeXYZ(xyz[0], xyz[1], xyz[2]); + int[] nextEVSource = { evSource[0] + xb * halfValue * directionMask[0], + evSource[1] + yb * halfValue * directionMask[1], + evSource[2] + zb * halfValue * directionMask[2] }; + litBlocksAndGetDescendants(world, nextEVSource, lightSource, illuminatedBlocksSet, ev2, power, + directionMask, borders); + } else { + for (int d1 : this.vectors[ev]) { + if (d1 != 0) { + litBlocksAndGetDescendants(world, evSource, lightSource, illuminatedBlocksSet, d1, power, + directionMask, borders); + } + } + } + } + + } + + private int getNewPower(World world, int ev, int[] evSource, int[] lightSource, int power, int[] directionMask, + BitSet illuminatedBlocksSet, int[] borders) { + int power1 = power; + int[] xyz = IHLMod.explosionHandler.decodeXYZ(ev); + int absX = xyz[0] * directionMask[0] + evSource[0]; + int absY = xyz[1] * directionMask[1] + evSource[1]; + int absZ = xyz[2] * directionMask[2] + evSource[2]; + if (absX < borders[0]) { + borders[0] = absX; + } else if (absY < borders[1]) { + borders[1] = absY; + } else if (absZ < borders[2]) { + borders[2] = absZ; + } else if (absX > borders[3]) { + borders[3] = absX; + } else if (absY > borders[4]) { + borders[4] = absY; + } else if (absZ > borders[5]) { + borders[5] = absZ; + } + Block block = world.getBlock(absX, absY, absZ); + if (block.equals(Blocks.air) || block.isAir(world, absX, absY, absZ)) { + return power; + } + power1 *= world.getBlockLightOpacity(absX, absY, absZ) / 16; + int lightBitAddress = this.encodeXYZ(absX - lightSource[0], absY - lightSource[1], absZ - lightSource[2]); + illuminatedBlocksSet.set(lightBitAddress); + return power1; + } + + public void addLightSource(LightSource lightSource) { + System.out.println("Adding light source. Borders:"); + System.out.println("from " + lightSource.fromX + ";" + lightSource.fromY + ";" + lightSource.fromZ); + System.out.println("to " + lightSource.toX + ";" + lightSource.toY + ";" + lightSource.toZ); + this.lightSources.add(lightSource); + } + + public void removeLightSource(LightSource lightSource) { + this.lightSources.remove(lightSource); + } +} diff --git a/ihl/enviroment/LightSource.java b/ihl/enviroment/LightSource.java new file mode 100644 index 0000000..291b15a --- /dev/null +++ b/ihl/enviroment/LightSource.java @@ -0,0 +1,78 @@ +package ihl.enviroment; + +import java.util.BitSet; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import ihl.ClientProxy; +import ihl.IHLMod; + +@SideOnly(value=Side.CLIENT) +public class LightSource { + private final int centerX; + private final int centerY; + private final int centerZ; + public int fromX; + public int fromY; + public int fromZ; + public int toX; + public int toY; + public int toZ; + private final int red; + private final int green; + private final int blue; + private final int power; + public final BitSet illuminatedBlocks = new BitSet(); + + public LightSource(int centerX1, int centerY1, int centerZ1, + int red1, int green1, int blue1, int power1) { + centerX = centerX1; + centerY = centerY1; + centerZ = centerZ1; + red = red1; + green = green1; + blue = blue1; + power = power1; + } + + public void setBorders(int fromX1, int fromY1, int fromZ1, + int toX1, int toY1, int toZ1) + { + fromX=fromX1; + fromY=fromY1; + fromZ=fromZ1; + toX=toX1; + toY=toY1; + toZ=toZ1; + } + + public boolean isBlockIlluminated(int x, int y, int z) { + if(xtoX || ytoY || ztoZ) + { + return false; + } + else + { + int rx = x - centerX; + int ry = y - centerY; + int rz = z - centerZ; + int l = ((ClientProxy)IHLMod.proxy).getLightHandler().encodeXYZ(rx, ry, rz); + return illuminatedBlocks.get(l); + } + } + + public int[] getLightValue(int x, int y, int z, int[] normal) { + int dx = centerX-x; + int dy = centerY-y; + int dz = centerZ-z; + int d = dx*dx+dy*dy+dz*dz; + dx=normal[0]*dx; + dy=normal[1]*dy; + dz=normal[2]*dz; + dx=dx>0?(dx<<16)/d:0; + dy=dy>0?(dy<<16)/d:0; + dz=dz>0?(dz<<16)/d:0; + int brightness = Math.min(power*(dx+dy+dz)>>16,255); + return new int[]{brightness, this.red, this.blue, this.green}; + } +} diff --git a/ihl/enviroment/SpotlightTileEntity.java b/ihl/enviroment/SpotlightTileEntity.java index 287ef9f..ab18ebe 100644 --- a/ihl/enviroment/SpotlightTileEntity.java +++ b/ihl/enviroment/SpotlightTileEntity.java @@ -111,7 +111,7 @@ public class SpotlightTileEntity extends LightBulbTileEntity implements INetwork if(needLightTargetUpdate) { this.generateGlowningAirList(); - this.updateLightState(this.getActive()); + this.updateLightState(); needLightTargetUpdate=false; } if(this.prevRotationPitch!=this.rotationPitch) @@ -214,7 +214,7 @@ public class SpotlightTileEntity extends LightBulbTileEntity implements INetwork } @Override - protected void updateLightState(boolean spreadDarkness) + protected void updateLightState() { if(this.getActive()) { -- cgit v1.2.3