diff --git a/src/main/java/net/minecraftforge/client/model/ItemLayerModel.java b/src/main/java/net/minecraftforge/client/model/ItemLayerModel.java index e2c633b36..4e871a002 100644 --- a/src/main/java/net/minecraftforge/client/model/ItemLayerModel.java +++ b/src/main/java/net/minecraftforge/client/model/ItemLayerModel.java @@ -21,25 +21,31 @@ package net.minecraftforge.client.model; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; +import com.google.gson.JsonArray; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; import com.mojang.datafixers.util.Pair; +import it.unimi.dsi.fastutil.ints.IntSet; import net.minecraft.client.renderer.TransformationMatrix; import net.minecraft.client.renderer.model.*; import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.client.renderer.vertex.VertexFormatElement; +import net.minecraft.resources.IResourceManager; import net.minecraft.util.Direction; +import net.minecraft.util.JSONUtils; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.Vec2f; import net.minecraftforge.client.model.geometry.IModelGeometry; import net.minecraftforge.client.model.pipeline.BakedQuadBuilder; import net.minecraftforge.client.model.pipeline.IVertexConsumer; import net.minecraftforge.client.model.pipeline.TRSRTransformer; -import java.util.Arrays; -import java.util.BitSet; -import java.util.Collection; -import java.util.EnumMap; -import java.util.List; -import java.util.Set; +import javax.annotation.Nullable; +import java.util.*; import java.util.function.Function; /** @@ -59,15 +65,22 @@ public final class ItemLayerModel implements IModelGeometry private static final Direction[] VERTICALS = {Direction.WEST, Direction.EAST}; private ImmutableList textures; - - public ItemLayerModel(ImmutableList textures) - { - this.textures = textures; - } + private final ImmutableSet fullbrightLayers; public ItemLayerModel() { - this.textures = null; + this(null, ImmutableSet.of()); + } + + public ItemLayerModel(ImmutableList textures) + { + this(textures, ImmutableSet.of()); + } + + public ItemLayerModel(@Nullable ImmutableList textures, ImmutableSet fullbrightLayers) + { + this.textures = textures; + this.fullbrightLayers = fullbrightLayers; } private static ImmutableList getTextures(IModelConfiguration model) @@ -85,7 +98,7 @@ public final class ItemLayerModel implements IModelGeometry { //TODO: Verify TransformationMatrix transform = modelTransform.getRotation(); - ImmutableList quads = getQuadsForSprites(textures, transform, spriteGetter); + ImmutableList quads = getQuadsForSprites(textures, transform, spriteGetter, fullbrightLayers); TextureAtlasSprite particle = spriteGetter.apply( owner.isTexturePresent("particle") ? owner.resolveTexture("particle") : textures.get(0) ); @@ -94,17 +107,27 @@ public final class ItemLayerModel implements IModelGeometry } public static ImmutableList getQuadsForSprites(List textures, TransformationMatrix transform, Function spriteGetter) + { + return getQuadsForSprites(textures, transform, spriteGetter, Collections.emptySet()); + } + + public static ImmutableList getQuadsForSprites(List textures, TransformationMatrix transform, Function spriteGetter, Set fullbrights) { ImmutableList.Builder builder = ImmutableList.builder(); for(int i = 0; i < textures.size(); i++) { TextureAtlasSprite tas = spriteGetter.apply(textures.get(i)); - builder.addAll(getQuadsForSprite(i, tas, transform)); + builder.addAll(getQuadsForSprite(i, tas, transform, fullbrights.contains(i))); } return builder.build(); } public static ImmutableList getQuadsForSprite(int tint, TextureAtlasSprite sprite, TransformationMatrix transform) + { + return getQuadsForSprite(tint, sprite, transform, false); + } + + public static ImmutableList getQuadsForSprite(int tint, TextureAtlasSprite sprite, TransformationMatrix transform, boolean fullbright) { ImmutableList.Builder builder = ImmutableList.builder(); @@ -124,7 +147,7 @@ public final class ItemLayerModel implements IModelGeometry ptu = true; for(int u = 0; u < uMax; u++) { - int alpha = sprite.getPixelRGBA(f, u, v) >> 24 & 0xFF; + int alpha = sprite.getPixelRGBA(f, u, vMax - v - 1) >> 24 & 0xFF; boolean t = alpha / 255f <= 0.1f; if (!t && alpha < 255) @@ -195,7 +218,7 @@ public final class ItemLayerModel implements IModelGeometry { // make quad [uStart, u] int off = facing == Direction.DOWN ? 1 : 0; - builder.add(buildSideQuad(transform, facing, tint, sprite, uStart, v+off, u-uStart)); + builder.add(buildSideQuad(transform, facing, tint, sprite, uStart, v+off, u-uStart, fullbright)); building = false; } else if (!building && face) // start new quad @@ -209,7 +232,7 @@ public final class ItemLayerModel implements IModelGeometry { // make quad [uStart, uEnd] int off = facing == Direction.DOWN ? 1 : 0; - builder.add(buildSideQuad(transform, facing, tint, sprite, uStart, v+off, uEnd-uStart)); + builder.add(buildSideQuad(transform, facing, tint, sprite, uStart, v+off, uEnd-uStart, fullbright)); } } } @@ -242,7 +265,7 @@ public final class ItemLayerModel implements IModelGeometry { // make quad [vStart, v] int off = facing == Direction.EAST ? 1 : 0; - builder.add(buildSideQuad(transform, facing, tint, sprite, u+off, vStart, v-vStart)); + builder.add(buildSideQuad(transform, facing, tint, sprite, u+off, vStart, v-vStart, fullbright)); building = false; } else if (!building && face) // start new quad @@ -256,20 +279,20 @@ public final class ItemLayerModel implements IModelGeometry { // make quad [vStart, vEnd] int off = facing == Direction.EAST ? 1 : 0; - builder.add(buildSideQuad(transform, facing, tint, sprite, u+off, vStart, vEnd-vStart)); + builder.add(buildSideQuad(transform, facing, tint, sprite, u+off, vStart, vEnd-vStart, fullbright)); } } } // front - builder.add(buildQuad(transform, Direction.NORTH, sprite, tint, + builder.add(buildQuad(transform, Direction.NORTH, sprite, tint, fullbright, 0, 0, 7.5f / 16f, sprite.getMinU(), sprite.getMaxV(), 0, 1, 7.5f / 16f, sprite.getMinU(), sprite.getMinV(), 1, 1, 7.5f / 16f, sprite.getMaxU(), sprite.getMinV(), 1, 0, 7.5f / 16f, sprite.getMaxU(), sprite.getMaxV() )); // back - builder.add(buildQuad(transform, Direction.SOUTH, sprite, tint, + builder.add(buildQuad(transform, Direction.SOUTH, sprite, tint, fullbright, 0, 0, 8.5f / 16f, sprite.getMinU(), sprite.getMaxV(), 1, 0, 8.5f / 16f, sprite.getMaxU(), sprite.getMaxV(), 1, 1, 8.5f / 16f, sprite.getMaxU(), sprite.getMinV(), @@ -318,7 +341,7 @@ public final class ItemLayerModel implements IModelGeometry } } - private static BakedQuad buildSideQuad(TransformationMatrix transform, Direction side, int tint, TextureAtlasSprite sprite, int u, int v, int size) + private static BakedQuad buildSideQuad(TransformationMatrix transform, Direction side, int tint, TextureAtlasSprite sprite, int u, int v, int size, boolean fullbright) { final float eps = 1e-2f; @@ -357,7 +380,7 @@ public final class ItemLayerModel implements IModelGeometry float v1 = 16f * (1f - y1 - dy); return buildQuad( - transform, remap(side), sprite, tint, + transform, remap(side), sprite, tint, fullbright, x0, y0, z0, sprite.getInterpolatedU(u0), sprite.getInterpolatedV(v0), x1, y1, z0, sprite.getInterpolatedU(u1), sprite.getInterpolatedV(v1), x1, y1, z1, sprite.getInterpolatedU(u1), sprite.getInterpolatedV(v1), @@ -371,7 +394,7 @@ public final class ItemLayerModel implements IModelGeometry return side.getAxis() == Direction.Axis.Y ? side.getOpposite() : side; } - private static BakedQuad buildQuad(TransformationMatrix transform, Direction side, TextureAtlasSprite sprite, int tint, + private static BakedQuad buildQuad(TransformationMatrix transform, Direction side, TextureAtlasSprite sprite, int tint, boolean fullbright, float x0, float y0, float z0, float u0, float v0, float x1, float y1, float z1, float u1, float v1, float x2, float y2, float z2, float u2, float v2, @@ -381,24 +404,29 @@ public final class ItemLayerModel implements IModelGeometry builder.setQuadTint(tint); builder.setQuadOrientation(side); + builder.setApplyDiffuseLighting(false); boolean hasTransform = !transform.isIdentity(); IVertexConsumer consumer = hasTransform ? new TRSRTransformer(builder, transform) : builder; - putVertex(consumer, side, x0, y0, z0, u0, v0); - putVertex(consumer, side, x1, y1, z1, u1, v1); - putVertex(consumer, side, x2, y2, z2, u2, v2); - putVertex(consumer, side, x3, y3, z3, u3, v3); + int uLight, vLight; + uLight = vLight = fullbright ? 15 : 0; + + putVertex(consumer, side, x0, y0, z0, u0, v0, uLight, vLight); + putVertex(consumer, side, x1, y1, z1, u1, v1, uLight, vLight); + putVertex(consumer, side, x2, y2, z2, u2, v2, uLight, vLight); + putVertex(consumer, side, x3, y3, z3, u3, v3, uLight, vLight); return builder.build(); } - private static void putVertex(IVertexConsumer consumer, Direction side, float x, float y, float z, float u, float v) + private static void putVertex(IVertexConsumer consumer, Direction side, float x, float y, float z, float u, float v, int uLight, int vLight) { VertexFormat format = consumer.getVertexFormat(); for(int e = 0; e < format.getElements().size(); e++) { - switch(format.getElements().get(e).getUsage()) + VertexFormatElement element = format.getElements().get(e); + outer:switch(element.getUsage()) { case POSITION: consumer.put(e, x, y, z, 1f); @@ -413,10 +441,14 @@ public final class ItemLayerModel implements IModelGeometry consumer.put(e, offX, offY, offZ, 0f); break; case UV: - if(format.getElements().get(e).getIndex() == 0) + switch(element.getIndex()) { - consumer.put(e, u, v, 0f, 1f); - break; + case 0: + consumer.put(e, u, v, 0f, 1f); + break outer; + case 2: + consumer.put(e, (uLight<<4)/32768.0f, (vLight<<4)/32768.0f, 0, 1); + break outer; } // else fallthrough to default default: @@ -425,4 +457,30 @@ public final class ItemLayerModel implements IModelGeometry } } } + + public static class Loader implements IModelLoader + { + public static final Loader INSTANCE = new Loader(); + + @Override + public void onResourceManagerReload(IResourceManager resourceManager) + { + // nothing to do + } + + @Override + public ItemLayerModel read(JsonDeserializationContext deserializationContext, JsonObject modelContents) + { + ImmutableSet.Builder fullbrightLayers = ImmutableSet.builder(); + if (modelContents.has("fullbright_layers")) + { + JsonArray arr = JSONUtils.getJsonArray(modelContents, "fullbright_layers"); + for(int i=0;i item_layers = ITEMS.register("item_layers", () -> + new Item(new Item.Properties().group(ItemGroup.MISC)) + ); + public NewModelLoaderTest() { IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); diff --git a/src/test/java/net/minecraftforge/debug/client/rendering/StencilEnableTest.java b/src/test/java/net/minecraftforge/debug/client/rendering/StencilEnableTest.java index 7d734bbfc..4fa4af0b1 100644 --- a/src/test/java/net/minecraftforge/debug/client/rendering/StencilEnableTest.java +++ b/src/test/java/net/minecraftforge/debug/client/rendering/StencilEnableTest.java @@ -1,3 +1,22 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2019. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + package net.minecraftforge.debug.client.rendering; import net.minecraft.client.Minecraft; diff --git a/src/test/resources/assets/new_model_loader_test/models/item/item_layers.json b/src/test/resources/assets/new_model_loader_test/models/item/item_layers.json new file mode 100644 index 000000000..c052343d9 --- /dev/null +++ b/src/test/resources/assets/new_model_loader_test/models/item/item_layers.json @@ -0,0 +1,9 @@ +{ + "parent": "forge:item/default", + "loader": "forge:item-layers", + "textures": { + "layer0": "minecraft:item/coal", + "layer1": "minecraft:item/stick" + }, + "fullbright_layers": [ 1 ] +} \ No newline at end of file