Rendering tweaks and fixes: Part 4 (#9065)

This commit is contained in:
Néstor Amador authored and GitHub committed 2022-11-23 09:17:43 +01:00
1 parent 97a9ca65f1
commit 2d3ee8a228
9 files changed
+82 -39

No files matched your search

@@ -23,10 +23,12 @@ import net.minecraft.client.resources.model.Material;
import net.minecraft.client.resources.model.ModelBakery;
import net.minecraft.client.resources.model.ModelState;
import net.minecraft.client.resources.model.UnbakedModel;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.RandomSource;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.client.ChunkRenderTypeSet;
import net.minecraftforge.client.RenderTypeGroup;
@@ -169,6 +171,15 @@ public class CompositeModel implements IUnbakedGeometry<CompositeModel>
return ConcatenatedListView.of(quadLists);
}
@Override
public @NotNull ModelData getModelData(@NotNull BlockAndTintGetter level, @NotNull BlockPos pos, @NotNull BlockState state, @NotNull ModelData modelData)
{
var builder = Data.builder();
for (var entry : children.entrySet())
builder.with(entry.getKey(), entry.getValue().getModelData(level, pos, state, Data.resolve(modelData, entry.getKey())));
return modelData.derive().with(Data.PROPERTY, builder.build()).build();
}
@Override
public boolean useAmbientOcclusion()
{
@@ -62,9 +62,11 @@ public class ElementsModel extends SimpleUnbakedGeometry<ElementsModel>
if (deprecatedLoader)
LOGGER.warn("Model \"" + modelLocation + "\" is using the deprecated loader \"minecraft:elements\" instead of \"forge:elements\". This loader will be removed in 1.20.");
var rootTransform = context.getRootTransform();
if (!rootTransform.isIdentity())
modelState = new SimpleModelState(modelState.getRotation().compose(rootTransform), modelState.isUvLocked());
// If there is a root transform, undo the ModelState transform, apply it, then re-apply the ModelState transform.
// This is necessary because of things like UV locking, which should only respond to the ModelState, and as such
// that is the only transform that should be applied during face bake.
var postTransform = context.getRootTransform().isIdentity() ? QuadTransformers.empty() :
QuadTransformers.applying(modelState.getRotation().compose(context.getRootTransform()).compose(modelState.getRotation().inverse()));
for (BlockElement element : elements)
{
@@ -73,6 +75,7 @@ public class ElementsModel extends SimpleUnbakedGeometry<ElementsModel>
var face = element.faces.get(direction);
var sprite = spriteGetter.apply(context.getMaterial(face.texture));
var quad = BlockModel.bakeFace(element, face, sprite, direction, modelState, modelLocation);
postTransform.processInPlace(quad);
if (face.cullForDirection == null)
modelBuilder.addUnculledFace(quad);
@@ -64,7 +64,7 @@ public final class QuadTransformers {
{
int offset = i * IQuadTransformer.STRIDE + IQuadTransformer.NORMAL;
int normalIn = vertices[offset];
if ((normalIn >> 8) != 0)
if ((normalIn & 0x00FFFFFF) != 0) // The ignored byte is padding and may be filled with user data
{
float x = ((byte) (normalIn & 0xFF)) / 127.0f;
float y = ((byte) ((normalIn >> 8) & 0xFF)) / 127.0f;
@@ -72,12 +72,11 @@ public final class QuadTransformers {
Vector3f pos = new Vector3f(x, y, z);
transform.transformNormal(pos);
pos.normalize();
vertices[offset] = (((byte) (x * 127.0f)) & 0xFF) |
((((byte) (y * 127.0f)) & 0xFF) << 8) |
((((byte) (z * 127.0f)) & 0xFF) << 16) |
(normalIn & 0xFF000000);
vertices[offset] = (((byte) (pos.x() * 127.0f)) & 0xFF) |
((((byte) (pos.y() * 127.0f)) & 0xFF) << 8) |
((((byte) (pos.z() * 127.0f)) & 0xFF) << 16) |
(normalIn & 0xFF000000); // Restore padding, just in case
}
}
};
@@ -19,12 +19,13 @@ import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureAtlas;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.client.resources.model.BuiltInModel;
import net.minecraft.client.resources.model.Material;
import net.minecraft.client.resources.model.ModelBakery;
import net.minecraft.client.resources.model.ModelState;
import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.client.RenderTypeGroup;
import net.minecraftforge.client.model.ElementsModel;
import net.minecraftforge.client.model.IModelBuilder;
import net.minecraftforge.client.model.SimpleModelState;
import org.jetbrains.annotations.ApiStatus;
@@ -98,17 +99,30 @@ public class UnbakedGeometryHelper
if (customModel != null)
return customModel.bake(blockModel.customData, modelBakery, spriteGetter, modelState, blockModel.getOverrides(modelBakery, owner, spriteGetter), modelLocation);
Transformation rootTransform = blockModel.customData.getRootTransform();
if (!rootTransform.isIdentity())
modelState = new SimpleModelState(modelState.getRotation().compose(rootTransform), modelState.isUvLocked());
// Handle vanilla item models here, since vanilla has a shortcut for them
if (blockModel.getRootModel() == ModelBakery.GENERATION_MARKER)
return ITEM_MODEL_GENERATOR.generateBlockModel(spriteGetter, blockModel).bake(modelBakery, blockModel, spriteGetter, modelState, modelLocation, guiLight3d);
var renderTypeHint = blockModel.customData.getRenderTypeHint();
var renderTypes = renderTypeHint != null ? blockModel.customData.getRenderType(renderTypeHint) : RenderTypeGroup.EMPTY;
return blockModel.bakeVanilla(modelBakery, owner, spriteGetter, modelState, modelLocation, guiLight3d, renderTypes);
return bakeVanilla(blockModel, modelBakery, owner, spriteGetter, modelState, modelLocation);
}
/**
* Helper for baking vanilla {@link BlockModel} instances.
*
* @deprecated Merge into the method above in 1.20 once the call from {@link BlockModel} is gone.
*/
@ApiStatus.Internal
@Deprecated(forRemoval = true, since = "1.19.2")
public static BakedModel bakeVanilla(BlockModel blockModel, ModelBakery modelBakery, BlockModel owner, Function<Material, TextureAtlasSprite> spriteGetter, ModelState modelState, ResourceLocation modelLocation)
{
if (blockModel.getRootModel() == ModelBakery.BLOCK_ENTITY_MARKER)
{
var particleSprite = spriteGetter.apply(blockModel.getMaterial("particle"));
return new BuiltInModel(blockModel.getTransforms(), blockModel.getOverrides(modelBakery, owner, spriteGetter), particleSprite, blockModel.getGuiLight().lightLikeBlock());
}
var elementsModel = new ElementsModel(blockModel.getElements());
return elementsModel.bake(blockModel.customData, modelBakery, spriteGetter, modelState, blockModel.getOverrides(modelBakery, owner, spriteGetter), modelLocation);
}
/**
@@ -68,7 +68,7 @@ public class ObjModel extends SimpleUnbakedGeometry<ObjModel>
new Vec2(1, 0),
};
private final Map<String, ModelGroup> parts = Maps.newHashMap();
private final Map<String, ModelGroup> parts = Maps.newLinkedHashMap();
private final Set<String> rootComponentNames = Collections.unmodifiableSet(parts.keySet());
private Set<String> allComponentNames;
@@ -402,8 +402,7 @@ public class ObjModel extends SimpleUnbakedGeometry<ObjModel>
faceNormal = abs;
}
var quad = new BakedQuad[1];
var quadBaker = new QuadBakingVertexConsumer(q -> quad[0] = q);
var quadBaker = new QuadBakingVertexConsumer.Buffered();
quadBaker.setSprite(texture);
quadBaker.setTintIndex(tintIndex);
@@ -516,7 +515,7 @@ public class ObjModel extends SimpleUnbakedGeometry<ObjModel>
}
}
return Pair.of(quad[0], cull);
return Pair.of(quadBaker.getQuad(), cull);
}
public CompositeRenderable bakeRenderable(IGeometryBakingContext configuration)
@@ -582,7 +581,7 @@ public class ObjModel extends SimpleUnbakedGeometry<ObjModel>
public class ModelGroup extends ModelObject
{
final Map<String, ModelObject> parts = Maps.newHashMap();
final Map<String, ModelObject> parts = Maps.newLinkedHashMap();
ModelGroup(String name)
{
@@ -652,9 +651,11 @@ public class ObjModel extends SimpleUnbakedGeometry<ObjModel>
int tintIndex = mat.diffuseTintIndex;
Vector4f colorTint = mat.diffuseColor;
var rootTransform = owner.getRootTransform();
var transform = rootTransform.isIdentity() ? modelTransform.getRotation() : modelTransform.getRotation().compose(rootTransform);
for (int[][] face : faces)
{
Pair<BakedQuad, Direction> quad = makeQuad(face, tintIndex, colorTint, mat.ambientColor, texture, modelTransform.getRotation());
Pair<BakedQuad, Direction> quad = makeQuad(face, tintIndex, colorTint, mat.ambientColor, texture, transform);
if (quad.getRight() == null)
modelBuilder.addUnculledFace(quad.getLeft());
else
@@ -5,6 +5,7 @@
package net.minecraftforge.client.model.pipeline;
import com.google.common.base.Preconditions;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.blaze3d.vertex.VertexFormatElement;
@@ -37,7 +38,7 @@ public class QuadBakingVertexConsumer implements VertexConsumer
private final Consumer<BakedQuad> quadConsumer;
private int vertexIndex = 0;
int vertexIndex = 0;
private int[] quadData = new int[QUAD_DATA_SIZE];
private int tintIndex;
@@ -167,4 +168,27 @@ public class QuadBakingVertexConsumer implements VertexConsumer
{
this.hasAmbientOcclusion = hasAmbientOcclusion;
}
public static class Buffered extends QuadBakingVertexConsumer
{
private final BakedQuad[] output;
public Buffered()
{
this(new BakedQuad[1]);
}
private Buffered(BakedQuad[] output)
{
super(q -> output[0] = q);
this.output = output;
}
public BakedQuad getQuad()
{
var quad = Preconditions.checkNotNull(output[0], "No quad has been emitted. Vertices in buffer: " + vertexIndex);
output[0] = null;
return quad;
}
}
}