/newcode/src/com/prupe/mcpatcher/cc/Lightmap.java

https://bitbucket.org/michael_rodrigues/mcpatcher · Java · 138 lines · 125 code · 13 blank · 0 comment · 34 complexity · d0e7657382659a2d83ee0d754d8544a9 MD5 · raw file

  1. package com.prupe.mcpatcher.cc;
  2. import com.prupe.mcpatcher.Config;
  3. import com.prupe.mcpatcher.MCLogger;
  4. import com.prupe.mcpatcher.MCPatcherUtils;
  5. import com.prupe.mcpatcher.TexturePackAPI;
  6. import net.minecraft.src.EntityRenderer;
  7. import net.minecraft.src.ResourceLocation;
  8. import net.minecraft.src.World;
  9. import java.awt.image.BufferedImage;
  10. import java.util.HashMap;
  11. public final class Lightmap {
  12. private static final MCLogger logger = MCLogger.getLogger(MCPatcherUtils.CUSTOM_COLORS);
  13. private static final String LIGHTMAP_FORMAT = "lightmap/world%d.png";
  14. private static final int LIGHTMAP_SIZE = 16;
  15. private static final int HEIGHT_WITHOUT_NIGHTVISION = 2 * LIGHTMAP_SIZE;
  16. private static final int HEIGHT_WITH_NIGHTVISION = 4 * LIGHTMAP_SIZE;
  17. private static final boolean useLightmaps = Config.getBoolean(MCPatcherUtils.CUSTOM_COLORS, "lightmaps", true);
  18. private static final HashMap<Integer, Lightmap> lightmaps = new HashMap<Integer, Lightmap>();
  19. private final int width;
  20. private final boolean customNightvision;
  21. private final int[] origMap;
  22. private final boolean valid;
  23. private final float[] sunrgb = new float[3 * LIGHTMAP_SIZE];
  24. private final float[] torchrgb = new float[3 * LIGHTMAP_SIZE];
  25. private final float[] sunrgbnv = new float[3 * LIGHTMAP_SIZE];
  26. private final float[] torchrgbnv = new float[3 * LIGHTMAP_SIZE];
  27. private final float[] rgb = new float[3];
  28. static void reset() {
  29. lightmaps.clear();
  30. }
  31. public static boolean computeLightmap(EntityRenderer renderer, World world, int[] mapRGB, float partialTick) {
  32. if (world == null || !useLightmaps) {
  33. return false;
  34. }
  35. Lightmap lightmap = null;
  36. int worldType = world.worldProvider.worldType;
  37. if (lightmaps.containsKey(worldType)) {
  38. lightmap = lightmaps.get(worldType);
  39. } else {
  40. ResourceLocation resource = TexturePackAPI.newMCPatcherResourceLocation(String.format(LIGHTMAP_FORMAT, worldType));
  41. BufferedImage image = TexturePackAPI.getImage(resource);
  42. if (image != null) {
  43. lightmap = new Lightmap(resource, image);
  44. if (!lightmap.valid) {
  45. lightmap = null;
  46. }
  47. }
  48. lightmaps.put(worldType, lightmap);
  49. }
  50. return lightmap != null && lightmap.compute(renderer, world, mapRGB, partialTick);
  51. }
  52. private Lightmap(ResourceLocation resource, BufferedImage image) {
  53. width = image.getWidth();
  54. int height = image.getHeight();
  55. customNightvision = (height == HEIGHT_WITH_NIGHTVISION);
  56. origMap = new int[width * height];
  57. image.getRGB(0, 0, width, height, origMap, 0, width);
  58. valid = (height == HEIGHT_WITHOUT_NIGHTVISION || height == HEIGHT_WITH_NIGHTVISION);
  59. if (!valid) {
  60. logger.error("%s must be exactly %d or %d pixels high", resource, HEIGHT_WITHOUT_NIGHTVISION, HEIGHT_WITH_NIGHTVISION);
  61. }
  62. }
  63. private boolean compute(EntityRenderer renderer, World world, int[] mapRGB, float partialTick) {
  64. float sun = Colorizer.clamp(world.lightningFlash > 0 ? 1.0f : 7.0f / 6.0f * (world.getSunAngle(1.0f) - 0.2f)) * (width - 1);
  65. float torch = Colorizer.clamp(renderer.torchFlickerX + 0.5f) * (width - 1);
  66. float nightVisionStrength = renderer.getNightVisionStrength(partialTick);
  67. float gamma = Colorizer.clamp(MCPatcherUtils.getMinecraft().gameSettings.gammaSetting);
  68. for (int i = 0; i < LIGHTMAP_SIZE; i++) {
  69. interpolate(origMap, i * width, sun, sunrgb, 3 * i);
  70. interpolate(origMap, (i + LIGHTMAP_SIZE) * width, torch, torchrgb, 3 * i);
  71. if (customNightvision && nightVisionStrength > 0.0f) {
  72. interpolate(origMap, (i + 2 * LIGHTMAP_SIZE) * width, sun, sunrgbnv, 3 * i);
  73. interpolate(origMap, (i + 3 * LIGHTMAP_SIZE) * width, torch, torchrgbnv, 3 * i);
  74. }
  75. }
  76. for (int s = 0; s < LIGHTMAP_SIZE; s++) {
  77. for (int t = 0; t < LIGHTMAP_SIZE; t++) {
  78. for (int k = 0; k < 3; k++) {
  79. rgb[k] = Colorizer.clamp(sunrgb[3 * s + k] + torchrgb[3 * t + k]);
  80. }
  81. if (nightVisionStrength > 0.0f) {
  82. if (customNightvision) {
  83. for (int k = 0; k < 3; k++) {
  84. rgb[k] = Colorizer.clamp((1.0f - nightVisionStrength) * rgb[k] + nightVisionStrength * (sunrgbnv[3 * s + k] + torchrgbnv[3 * t + k]));
  85. }
  86. } else {
  87. float nightVisionMultiplier = Math.max(Math.max(rgb[0], rgb[1]), rgb[2]);
  88. if (nightVisionMultiplier > 0.0f) {
  89. nightVisionMultiplier = (1.0f - nightVisionStrength) + nightVisionStrength / nightVisionMultiplier;
  90. for (int k = 0; k < 3; k++) {
  91. rgb[k] = Colorizer.clamp(rgb[k] * nightVisionMultiplier);
  92. }
  93. }
  94. }
  95. }
  96. if (gamma != 0.0f) {
  97. for (int k = 0; k < 3; k++) {
  98. float tmp = 1.0f - rgb[k];
  99. tmp = 1.0f - tmp * tmp * tmp * tmp;
  100. rgb[k] = gamma * tmp + (1.0f - gamma) * rgb[k];
  101. }
  102. }
  103. mapRGB[s * LIGHTMAP_SIZE + t] = 0xff000000 | Colorizer.float3ToInt(rgb);
  104. }
  105. }
  106. return true;
  107. }
  108. private static void interpolate(int[] map, int offset1, float x, float[] rgb, int offset2) {
  109. int x0 = (int) Math.floor(x);
  110. int x1 = (int) Math.ceil(x);
  111. if (x0 == x1) {
  112. Colorizer.intToFloat3(map[offset1 + x0], rgb, offset2);
  113. } else {
  114. float xf = x - x0;
  115. float xg = 1.0f - xf;
  116. float[] rgb0 = new float[3];
  117. float[] rgb1 = new float[3];
  118. Colorizer.intToFloat3(map[offset1 + x0], rgb0);
  119. Colorizer.intToFloat3(map[offset1 + x1], rgb1);
  120. for (int i = 0; i < 3; i++) {
  121. rgb[offset2 + i] = xg * rgb0[i] + xf * rgb1[i];
  122. }
  123. }
  124. }
  125. }