This commit is contained in:
paulevsGitch 2020-10-13 01:08:07 +03:00
parent 8286b914d7
commit 0d5e6d544c
7 changed files with 795 additions and 805 deletions

View file

@ -4,7 +4,6 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.SlabBlock; import net.minecraft.block.SlabBlock;

View file

@ -1,223 +1,221 @@
package ru.betterend.blocks.model; package ru.betterend.blocks.model;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import com.mojang.datafixers.util.Pair; import com.mojang.datafixers.util.Pair;
import net.fabricmc.fabric.api.renderer.v1.Renderer; import net.fabricmc.fabric.api.renderer.v1.Renderer;
import net.fabricmc.fabric.api.renderer.v1.RendererAccess; import net.fabricmc.fabric.api.renderer.v1.RendererAccess;
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh; import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder; import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder;
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel; import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
import net.minecraft.block.BlockState;
import net.minecraft.block.BlockState; import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.render.model.BakedQuad;
import net.minecraft.client.render.model.BakedQuad; import net.minecraft.client.render.model.ModelBakeSettings;
import net.minecraft.client.render.model.ModelBakeSettings; import net.minecraft.client.render.model.ModelLoader;
import net.minecraft.client.render.model.ModelLoader; import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.client.render.model.UnbakedModel; import net.minecraft.client.render.model.json.JsonUnbakedModel;
import net.minecraft.client.render.model.json.JsonUnbakedModel; import net.minecraft.client.render.model.json.ModelOverrideList;
import net.minecraft.client.render.model.json.ModelOverrideList; import net.minecraft.client.render.model.json.ModelTransformation;
import net.minecraft.client.render.model.json.ModelTransformation; import net.minecraft.client.texture.Sprite;
import net.minecraft.client.texture.Sprite; import net.minecraft.client.texture.SpriteAtlasTexture;
import net.minecraft.client.texture.SpriteAtlasTexture; import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.client.util.SpriteIdentifier; import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemStack; import net.minecraft.util.Identifier;
import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Direction; import net.minecraft.world.BlockRenderView;
import net.minecraft.world.BlockRenderView; import ru.betterend.BetterEnd;
import ru.betterend.BetterEnd; public class BaseBlockModel implements UnbakedModel, BakedModel, FabricBakedModel {
public class BaseBlockModel implements UnbakedModel, BakedModel, FabricBakedModel { private static final Identifier DEFAULT_BLOCK_MODEL = new Identifier("minecraft:block/block");
private static final Identifier DEFAULT_BLOCK_MODEL = new Identifier("minecraft:block/block"); private final SpriteIdentifier[] spritesIDs;
private final Sprite[] sprites;
private final SpriteIdentifier[] spritesIDs; private ModelTransformation transformation;
private final Sprite[] sprites; private Mesh mesh;
private ModelTransformation transformation;
private Mesh mesh; public BaseBlockModel(String... textures) {
this.spritesIDs = new SpriteIdentifier[textures.length];
public BaseBlockModel(String... textures) { this.sprites = new Sprite[textures.length];
this.spritesIDs = new SpriteIdentifier[textures.length]; for (int i = 0; i < textures.length; i++) {
this.sprites = new Sprite[textures.length]; this.spritesIDs[i] = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, BetterEnd.makeID(textures[i]));
for (int i = 0; i < textures.length; i++) { }
this.spritesIDs[i] = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, BetterEnd.makeID(textures[i])); }
}
} @Override
public BakedModel bake(ModelLoader loader, Function<SpriteIdentifier, Sprite> textureGetter,
@Override ModelBakeSettings rotationContainer, Identifier modelId) {
public BakedModel bake(ModelLoader loader, Function<SpriteIdentifier, Sprite> textureGetter, for(int i = 0; i < sprites.length; i++) {
ModelBakeSettings rotationContainer, Identifier modelId) { this.sprites[i] = textureGetter.apply(spritesIDs[i]);
for(int i = 0; i < sprites.length; i++) { }
this.sprites[i] = textureGetter.apply(spritesIDs[i]);
} JsonUnbakedModel jsonBlockModel = (JsonUnbakedModel) loader.getOrLoadModel(DEFAULT_BLOCK_MODEL);
this.transformation = jsonBlockModel.getTransformations();
JsonUnbakedModel jsonBlockModel = (JsonUnbakedModel) loader.getOrLoadModel(DEFAULT_BLOCK_MODEL);
this.transformation = jsonBlockModel.getTransformations(); Renderer renderer = RendererAccess.INSTANCE.getRenderer();
MeshBuilder builder = renderer.meshBuilder();
Renderer renderer = RendererAccess.INSTANCE.getRenderer(); QuadEmitter emitter = builder.getEmitter();
MeshBuilder builder = renderer.meshBuilder();
QuadEmitter emitter = builder.getEmitter(); Direction[] directions = Direction.values();
for (Direction direction : directions) {
Direction[] directions = Direction.values(); emitter.square(direction, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f);
for (Direction direction : directions) { switch (sprites.length) {
emitter.square(direction, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f); case 1: {
switch (sprites.length) { emitter.spriteBake(0, sprites[0], MutableQuadView.BAKE_LOCK_UV);
case 1: { break;
emitter.spriteBake(0, sprites[0], MutableQuadView.BAKE_LOCK_UV); }
break; case 2: {
} switch (direction) {
case 2: { case DOWN:
switch (direction) { case UP: {
case DOWN: emitter.spriteBake(0, sprites[0], MutableQuadView.BAKE_LOCK_UV);
case UP: { break;
emitter.spriteBake(0, sprites[0], MutableQuadView.BAKE_LOCK_UV); }
break; default: {
} emitter.spriteBake(0, sprites[1], MutableQuadView.BAKE_LOCK_UV);
default: { }
emitter.spriteBake(0, sprites[1], MutableQuadView.BAKE_LOCK_UV); }
} }
} case 3: {
} switch (direction) {
case 3: { case DOWN:
switch (direction) { case UP: {
case DOWN: emitter.spriteBake(0, sprites[0], MutableQuadView.BAKE_LOCK_UV);
case UP: { break;
emitter.spriteBake(0, sprites[0], MutableQuadView.BAKE_LOCK_UV); }
break; case NORTH:
} case SOUTH: {
case NORTH: emitter.spriteBake(0, sprites[1], MutableQuadView.BAKE_LOCK_UV);
case SOUTH: { break;
emitter.spriteBake(0, sprites[1], MutableQuadView.BAKE_LOCK_UV); }
break; default: {
} emitter.spriteBake(0, sprites[2], MutableQuadView.BAKE_LOCK_UV);
default: { }
emitter.spriteBake(0, sprites[2], MutableQuadView.BAKE_LOCK_UV); }
} }
} case 4: {
} switch (direction) {
case 4: { case DOWN:
switch (direction) { case UP: {
case DOWN: emitter.spriteBake(0, sprites[0], MutableQuadView.BAKE_LOCK_UV);
case UP: { break;
emitter.spriteBake(0, sprites[0], MutableQuadView.BAKE_LOCK_UV); }
break; case NORTH: {
} emitter.spriteBake(0, sprites[1], MutableQuadView.BAKE_LOCK_UV);
case NORTH: { break;
emitter.spriteBake(0, sprites[1], MutableQuadView.BAKE_LOCK_UV); }
break; case SOUTH: {
} emitter.spriteBake(0, sprites[2], MutableQuadView.BAKE_LOCK_UV);
case SOUTH: { break;
emitter.spriteBake(0, sprites[2], MutableQuadView.BAKE_LOCK_UV); }
break; default: {
} emitter.spriteBake(0, sprites[3], MutableQuadView.BAKE_LOCK_UV);
default: { }
emitter.spriteBake(0, sprites[3], MutableQuadView.BAKE_LOCK_UV); }
} }
} case 5: {
} switch (direction) {
case 5: { case DOWN:
switch (direction) { case UP:
case DOWN: case NORTH:
case UP: case SOUTH: {
case NORTH: emitter.spriteBake(0, sprites[direction.ordinal()], MutableQuadView.BAKE_LOCK_UV);
case SOUTH: { break;
emitter.spriteBake(0, sprites[direction.ordinal()], MutableQuadView.BAKE_LOCK_UV); }
break; default: {
} emitter.spriteBake(0, sprites[4], MutableQuadView.BAKE_LOCK_UV);
default: { }
emitter.spriteBake(0, sprites[4], MutableQuadView.BAKE_LOCK_UV); }
} }
} default: {
} emitter.spriteBake(0, sprites[direction.ordinal()], MutableQuadView.BAKE_LOCK_UV);
default: { }
emitter.spriteBake(0, sprites[direction.ordinal()], MutableQuadView.BAKE_LOCK_UV); }
}
} emitter.spriteColor(0, -1, -1, -1, -1);
emitter.emit();
emitter.spriteColor(0, -1, -1, -1, -1); }
emitter.emit(); this.mesh = builder.build();
}
this.mesh = builder.build(); return this;
}
return this;
} @Override
public boolean isVanillaAdapter() {
@Override return false;
public boolean isVanillaAdapter() { }
return false;
} @Override
public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos,
@Override Supplier<Random> randomSupplier, RenderContext context) {
public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, context.meshConsumer().accept(mesh);
Supplier<Random> randomSupplier, RenderContext context) { }
context.meshConsumer().accept(mesh);
} @Override
public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) {
@Override context.meshConsumer().accept(mesh);
public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) { }
context.meshConsumer().accept(mesh);
} @Override
public List<BakedQuad> getQuads(BlockState state, Direction face, Random random) {
@Override return null;
public List<BakedQuad> getQuads(BlockState state, Direction face, Random random) { }
return null;
} @Override
public boolean useAmbientOcclusion() {
@Override return false;
public boolean useAmbientOcclusion() { }
return false;
} @Override
public boolean hasDepth() {
@Override return false;
public boolean hasDepth() { }
return false;
} @Override
public boolean isSideLit() {
@Override return true;
public boolean isSideLit() { }
return true;
} @Override
public boolean isBuiltin() {
@Override return false;
public boolean isBuiltin() { }
return false;
} @Override
public Sprite getSprite() {
@Override return this.sprites[0];
public Sprite getSprite() { }
return this.sprites[0];
} @Override
public ModelTransformation getTransformation() {
@Override return this.transformation;
public ModelTransformation getTransformation() { }
return this.transformation;
} @Override
public ModelOverrideList getOverrides() {
@Override return ModelOverrideList.EMPTY;
public ModelOverrideList getOverrides() { }
return ModelOverrideList.EMPTY;
} @Override
public Collection<Identifier> getModelDependencies() {
@Override return Arrays.asList(DEFAULT_BLOCK_MODEL);
public Collection<Identifier> getModelDependencies() { }
return Arrays.asList(DEFAULT_BLOCK_MODEL);
} @Override
public Collection<SpriteIdentifier> getTextureDependencies(Function<Identifier, UnbakedModel> unbakedModelGetter,
@Override Set<Pair<String, String>> unresolvedTextureReferences) {
public Collection<SpriteIdentifier> getTextureDependencies(Function<Identifier, UnbakedModel> unbakedModelGetter, return Arrays.asList(spritesIDs);
Set<Pair<String, String>> unresolvedTextureReferences) { }
return Arrays.asList(spritesIDs); }
}
}

View file

@ -1,240 +1,238 @@
package ru.betterend.blocks.model; package ru.betterend.blocks.model;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import com.mojang.datafixers.util.Pair; import com.mojang.datafixers.util.Pair;
import net.fabricmc.fabric.api.renderer.v1.Renderer; import net.fabricmc.fabric.api.renderer.v1.Renderer;
import net.fabricmc.fabric.api.renderer.v1.RendererAccess; import net.fabricmc.fabric.api.renderer.v1.RendererAccess;
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh; import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder; import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder;
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel; import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
import net.minecraft.block.BlockState;
import net.minecraft.block.BlockState; import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.render.model.BakedQuad;
import net.minecraft.client.render.model.BakedQuad; import net.minecraft.client.render.model.ModelBakeSettings;
import net.minecraft.client.render.model.ModelBakeSettings; import net.minecraft.client.render.model.ModelLoader;
import net.minecraft.client.render.model.ModelLoader; import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.client.render.model.UnbakedModel; import net.minecraft.client.render.model.json.JsonUnbakedModel;
import net.minecraft.client.render.model.json.JsonUnbakedModel; import net.minecraft.client.render.model.json.ModelOverrideList;
import net.minecraft.client.render.model.json.ModelOverrideList; import net.minecraft.client.render.model.json.ModelTransformation;
import net.minecraft.client.render.model.json.ModelTransformation; import net.minecraft.client.texture.Sprite;
import net.minecraft.client.texture.Sprite; import net.minecraft.client.texture.SpriteAtlasTexture;
import net.minecraft.client.texture.SpriteAtlasTexture; import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.client.util.SpriteIdentifier; import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemStack; import net.minecraft.util.Identifier;
import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Direction; import net.minecraft.world.BlockRenderView;
import net.minecraft.world.BlockRenderView; import ru.betterend.BetterEnd;
import ru.betterend.BetterEnd; public class SlabModel implements UnbakedModel, BakedModel, FabricBakedModel {
public class SlabModel implements UnbakedModel, BakedModel, FabricBakedModel { private static final Identifier DEFAULT_SLAB_MODEL = new Identifier("minecraft:block/slab");
private static final Identifier DEFAULT_SLAB_MODEL = new Identifier("minecraft:block/slab"); private final SpriteIdentifier[] spritesIDs;
private final Sprite[] sprites;
private final SpriteIdentifier[] spritesIDs; private ModelTransformation transformation;
private final Sprite[] sprites; private Mesh mesh;
private ModelTransformation transformation;
private Mesh mesh; public SlabModel(String... textures) {
this.spritesIDs = new SpriteIdentifier[textures.length];
public SlabModel(String... textures) { this.sprites = new Sprite[textures.length];
this.spritesIDs = new SpriteIdentifier[textures.length]; for (int i = 0; i < textures.length; i++) {
this.sprites = new Sprite[textures.length]; this.spritesIDs[i] = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, BetterEnd.makeID(textures[i]));
for (int i = 0; i < textures.length; i++) { }
this.spritesIDs[i] = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, BetterEnd.makeID(textures[i])); }
}
} @Override
public BakedModel bake(ModelLoader loader, Function<SpriteIdentifier, Sprite> textureGetter,
@Override ModelBakeSettings rotationContainer, Identifier modelId) {
public BakedModel bake(ModelLoader loader, Function<SpriteIdentifier, Sprite> textureGetter, for(int i = 0; i < sprites.length; i++) {
ModelBakeSettings rotationContainer, Identifier modelId) { this.sprites[i] = textureGetter.apply(spritesIDs[i]);
for(int i = 0; i < sprites.length; i++) { }
this.sprites[i] = textureGetter.apply(spritesIDs[i]);
} JsonUnbakedModel jsonBlockModel = (JsonUnbakedModel) loader.getOrLoadModel(DEFAULT_SLAB_MODEL);
this.transformation = jsonBlockModel.getTransformations();
JsonUnbakedModel jsonBlockModel = (JsonUnbakedModel) loader.getOrLoadModel(DEFAULT_SLAB_MODEL);
this.transformation = jsonBlockModel.getTransformations(); Renderer renderer = RendererAccess.INSTANCE.getRenderer();
MeshBuilder builder = renderer.meshBuilder();
Renderer renderer = RendererAccess.INSTANCE.getRenderer(); QuadEmitter emitter = builder.getEmitter();
MeshBuilder builder = renderer.meshBuilder();
QuadEmitter emitter = builder.getEmitter(); for (Direction direction : Direction.values()) {
switch (sprites.length) {
for (Direction direction : Direction.values()) { case 1: {
switch (sprites.length) { this.buildFace(emitter, direction, sprites[0]);
case 1: { break;
this.buildFace(emitter, direction, sprites[0]); }
break; case 2: {
} switch (direction) {
case 2: { case DOWN:
switch (direction) { case UP: {
case DOWN: this.buildFace(emitter, direction, sprites[0]);
case UP: { break;
this.buildFace(emitter, direction, sprites[0]); }
break; default: {
} this.buildFace(emitter, direction, sprites[1]);
default: { }
this.buildFace(emitter, direction, sprites[1]); }
} }
} case 3: {
} switch (direction) {
case 3: { case DOWN:
switch (direction) { case UP: {
case DOWN: this.buildFace(emitter, direction, sprites[0]);
case UP: { break;
this.buildFace(emitter, direction, sprites[0]); }
break; case NORTH:
} case SOUTH: {
case NORTH: this.buildFace(emitter, direction, sprites[1]);
case SOUTH: { break;
this.buildFace(emitter, direction, sprites[1]); }
break; default: {
} this.buildFace(emitter, direction, sprites[2]);
default: { }
this.buildFace(emitter, direction, sprites[2]); }
} }
} case 4: {
} switch (direction) {
case 4: { case DOWN:
switch (direction) { case UP: {
case DOWN: this.buildFace(emitter, direction, sprites[0]);
case UP: { break;
this.buildFace(emitter, direction, sprites[0]); }
break; case NORTH: {
} this.buildFace(emitter, direction, sprites[1]);
case NORTH: { break;
this.buildFace(emitter, direction, sprites[1]); }
break; case SOUTH: {
} this.buildFace(emitter, direction, sprites[2]);
case SOUTH: { break;
this.buildFace(emitter, direction, sprites[2]); }
break; default: {
} this.buildFace(emitter, direction, sprites[3]);
default: { }
this.buildFace(emitter, direction, sprites[3]); }
} }
} case 5: {
} switch (direction) {
case 5: { case DOWN:
switch (direction) { case UP:
case DOWN: case NORTH:
case UP: case SOUTH: {
case NORTH: this.buildFace(emitter, direction, sprites[direction.ordinal()]);
case SOUTH: { break;
this.buildFace(emitter, direction, sprites[direction.ordinal()]); }
break; default: {
} this.buildFace(emitter, direction, sprites[4]);
default: { }
this.buildFace(emitter, direction, sprites[4]); }
} }
} default: {
} this.buildFace(emitter, direction, sprites[direction.ordinal()]);
default: { }
this.buildFace(emitter, direction, sprites[direction.ordinal()]); }
}
} emitter.spriteColor(0, -1, -1, -1, -1);
emitter.emit();
emitter.spriteColor(0, -1, -1, -1, -1); }
emitter.emit(); this.mesh = builder.build();
}
this.mesh = builder.build(); return this;
}
return this;
} private void buildFace(QuadEmitter emitter, Direction direction, Sprite sprite) {
switch(direction) {
private void buildFace(QuadEmitter emitter, Direction direction, Sprite sprite) { case DOWN: {
switch(direction) { emitter.square(direction, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f);
case DOWN: { emitter.cullFace(direction);
emitter.square(direction, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f); break;
emitter.cullFace(direction); }
break; case UP: {
} emitter.square(direction, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f);
case UP: { break;
emitter.square(direction, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f); }
break; default: {
} emitter.square(direction, 0.0f, 0.0f, 1.0f, 0.5f, 0.0f);
default: { emitter.cullFace(direction);
emitter.square(direction, 0.0f, 0.0f, 1.0f, 0.5f, 0.0f); }
emitter.cullFace(direction); }
} emitter.spriteBake(0, sprite, MutableQuadView.BAKE_LOCK_UV);
} }
emitter.spriteBake(0, sprite, MutableQuadView.BAKE_LOCK_UV);
} @Override
public boolean isVanillaAdapter() {
@Override return false;
public boolean isVanillaAdapter() { }
return false;
} @Override
public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos,
@Override Supplier<Random> randomSupplier, RenderContext context) {
public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, context.meshConsumer().accept(mesh);
Supplier<Random> randomSupplier, RenderContext context) { }
context.meshConsumer().accept(mesh);
} @Override
public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) {
@Override context.meshConsumer().accept(mesh);
public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) { }
context.meshConsumer().accept(mesh);
} @Override
public List<BakedQuad> getQuads(BlockState state, Direction face, Random random) {
@Override return null;
public List<BakedQuad> getQuads(BlockState state, Direction face, Random random) { }
return null;
} @Override
public boolean useAmbientOcclusion() {
@Override return false;
public boolean useAmbientOcclusion() { }
return false;
} @Override
public boolean hasDepth() {
@Override return false;
public boolean hasDepth() { }
return false;
} @Override
public boolean isSideLit() {
@Override return true;
public boolean isSideLit() { }
return true;
} @Override
public boolean isBuiltin() {
@Override return false;
public boolean isBuiltin() { }
return false;
} @Override
public Sprite getSprite() {
@Override return this.sprites[0];
public Sprite getSprite() { }
return this.sprites[0];
} @Override
public ModelTransformation getTransformation() {
@Override return this.transformation;
public ModelTransformation getTransformation() { }
return this.transformation;
} @Override
public ModelOverrideList getOverrides() {
@Override return ModelOverrideList.EMPTY;
public ModelOverrideList getOverrides() { }
return ModelOverrideList.EMPTY;
} @Override
public Collection<Identifier> getModelDependencies() {
@Override return Arrays.asList(DEFAULT_SLAB_MODEL);
public Collection<Identifier> getModelDependencies() { }
return Arrays.asList(DEFAULT_SLAB_MODEL);
} @Override
public Collection<SpriteIdentifier> getTextureDependencies(Function<Identifier, UnbakedModel> unbakedModelGetter,
@Override Set<Pair<String, String>> unresolvedTextureReferences) {
public Collection<SpriteIdentifier> getTextureDependencies(Function<Identifier, UnbakedModel> unbakedModelGetter, return Arrays.asList(spritesIDs);
Set<Pair<String, String>> unresolvedTextureReferences) { }
return Arrays.asList(spritesIDs); }
}
}

View file

@ -1,241 +1,239 @@
package ru.betterend.blocks.model; package ru.betterend.blocks.model;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import com.mojang.datafixers.util.Pair; import com.mojang.datafixers.util.Pair;
import net.fabricmc.fabric.api.renderer.v1.Renderer; import net.fabricmc.fabric.api.renderer.v1.Renderer;
import net.fabricmc.fabric.api.renderer.v1.RendererAccess; import net.fabricmc.fabric.api.renderer.v1.RendererAccess;
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh; import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder; import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder;
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel; import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
import net.minecraft.block.BlockState;
import net.minecraft.block.BlockState; import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.render.model.BakedQuad;
import net.minecraft.client.render.model.BakedQuad; import net.minecraft.client.render.model.ModelBakeSettings;
import net.minecraft.client.render.model.ModelBakeSettings; import net.minecraft.client.render.model.ModelLoader;
import net.minecraft.client.render.model.ModelLoader; import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.client.render.model.UnbakedModel; import net.minecraft.client.render.model.json.JsonUnbakedModel;
import net.minecraft.client.render.model.json.JsonUnbakedModel; import net.minecraft.client.render.model.json.ModelOverrideList;
import net.minecraft.client.render.model.json.ModelOverrideList; import net.minecraft.client.render.model.json.ModelTransformation;
import net.minecraft.client.render.model.json.ModelTransformation; import net.minecraft.client.texture.Sprite;
import net.minecraft.client.texture.Sprite; import net.minecraft.client.texture.SpriteAtlasTexture;
import net.minecraft.client.texture.SpriteAtlasTexture; import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.client.util.SpriteIdentifier; import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemStack; import net.minecraft.util.Identifier;
import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Direction; import net.minecraft.world.BlockRenderView;
import net.minecraft.world.BlockRenderView; import ru.betterend.BetterEnd;
import ru.betterend.BetterEnd; public class SlabTopModel implements UnbakedModel, BakedModel, FabricBakedModel {
public class SlabTopModel implements UnbakedModel, BakedModel, FabricBakedModel { private static final Identifier DEFAULT_MODEL = new Identifier("minecraft:block/slab_top");
private static final Identifier DEFAULT_MODEL = new Identifier("minecraft:block/slab_top"); private final SpriteIdentifier[] spritesIDs;
private final Sprite[] sprites;
private final SpriteIdentifier[] spritesIDs; private ModelTransformation transformation;
private final Sprite[] sprites; private Mesh mesh;
private ModelTransformation transformation;
private Mesh mesh; public SlabTopModel(String... textures) {
this.spritesIDs = new SpriteIdentifier[textures.length];
public SlabTopModel(String... textures) { this.sprites = new Sprite[textures.length];
this.spritesIDs = new SpriteIdentifier[textures.length]; for (int i = 0; i < textures.length; i++) {
this.sprites = new Sprite[textures.length]; this.spritesIDs[i] = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, BetterEnd.makeID(textures[i]));
for (int i = 0; i < textures.length; i++) { }
this.spritesIDs[i] = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, BetterEnd.makeID(textures[i])); }
}
} @Override
public BakedModel bake(ModelLoader loader, Function<SpriteIdentifier, Sprite> textureGetter,
@Override ModelBakeSettings rotationContainer, Identifier modelId) {
public BakedModel bake(ModelLoader loader, Function<SpriteIdentifier, Sprite> textureGetter, for(int i = 0; i < sprites.length; i++) {
ModelBakeSettings rotationContainer, Identifier modelId) { this.sprites[i] = textureGetter.apply(spritesIDs[i]);
for(int i = 0; i < sprites.length; i++) { }
this.sprites[i] = textureGetter.apply(spritesIDs[i]);
} JsonUnbakedModel jsonBlockModel = (JsonUnbakedModel) loader.getOrLoadModel(DEFAULT_MODEL);
this.transformation = jsonBlockModel.getTransformations();
JsonUnbakedModel jsonBlockModel = (JsonUnbakedModel) loader.getOrLoadModel(DEFAULT_MODEL);
this.transformation = jsonBlockModel.getTransformations(); Renderer renderer = RendererAccess.INSTANCE.getRenderer();
MeshBuilder builder = renderer.meshBuilder();
Renderer renderer = RendererAccess.INSTANCE.getRenderer(); QuadEmitter emitter = builder.getEmitter();
MeshBuilder builder = renderer.meshBuilder();
QuadEmitter emitter = builder.getEmitter(); Direction[] directions = Direction.values();
for (Direction direction : directions) {
Direction[] directions = Direction.values(); switch (sprites.length) {
for (Direction direction : directions) { case 1: {
switch (sprites.length) { this.buildModel(emitter, direction, sprites[0]);
case 1: { break;
this.buildModel(emitter, direction, sprites[0]); }
break; case 2: {
} switch (direction) {
case 2: { case DOWN:
switch (direction) { case UP: {
case DOWN: this.buildModel(emitter, direction, sprites[0]);
case UP: { break;
this.buildModel(emitter, direction, sprites[0]); }
break; default: {
} this.buildModel(emitter, direction, sprites[1]);
default: { }
this.buildModel(emitter, direction, sprites[1]); }
} }
} case 3: {
} switch (direction) {
case 3: { case DOWN:
switch (direction) { case UP: {
case DOWN: this.buildModel(emitter, direction, sprites[0]);
case UP: { break;
this.buildModel(emitter, direction, sprites[0]); }
break; case NORTH:
} case SOUTH: {
case NORTH: this.buildModel(emitter, direction, sprites[1]);
case SOUTH: { break;
this.buildModel(emitter, direction, sprites[1]); }
break; default: {
} this.buildModel(emitter, direction, sprites[2]);
default: { }
this.buildModel(emitter, direction, sprites[2]); }
} }
} case 4: {
} switch (direction) {
case 4: { case DOWN:
switch (direction) { case UP: {
case DOWN: this.buildModel(emitter, direction, sprites[0]);
case UP: { break;
this.buildModel(emitter, direction, sprites[0]); }
break; case NORTH: {
} this.buildModel(emitter, direction, sprites[1]);
case NORTH: { break;
this.buildModel(emitter, direction, sprites[1]); }
break; case SOUTH: {
} this.buildModel(emitter, direction, sprites[2]);
case SOUTH: { break;
this.buildModel(emitter, direction, sprites[2]); }
break; default: {
} this.buildModel(emitter, direction, sprites[3]);
default: { }
this.buildModel(emitter, direction, sprites[3]); }
} }
} case 5: {
} switch (direction) {
case 5: { case DOWN:
switch (direction) { case UP:
case DOWN: case NORTH:
case UP: case SOUTH: {
case NORTH: this.buildModel(emitter, direction, sprites[direction.ordinal()]);
case SOUTH: { break;
this.buildModel(emitter, direction, sprites[direction.ordinal()]); }
break; default: {
} this.buildModel(emitter, direction, sprites[4]);
default: { }
this.buildModel(emitter, direction, sprites[4]); }
} }
} default: {
} this.buildModel(emitter, direction, sprites[direction.ordinal()]);
default: { }
this.buildModel(emitter, direction, sprites[direction.ordinal()]); }
}
} emitter.spriteColor(0, -1, -1, -1, -1);
emitter.emit();
emitter.spriteColor(0, -1, -1, -1, -1); }
emitter.emit(); this.mesh = builder.build();
}
this.mesh = builder.build(); return this;
}
return this;
} private void buildModel(QuadEmitter emitter, Direction direction, Sprite sprite) {
switch(direction) {
private void buildModel(QuadEmitter emitter, Direction direction, Sprite sprite) { case DOWN: {
switch(direction) { emitter.square(direction, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f);
case DOWN: { break;
emitter.square(direction, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f); }
break; case UP: {
} emitter.square(direction, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f);
case UP: { emitter.cullFace(direction);
emitter.square(direction, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f); break;
emitter.cullFace(direction); }
break; default: {
} emitter.square(direction, 0.0f, 0.5f, 1.0f, 1.0f, 0.0f);
default: { emitter.cullFace(direction);
emitter.square(direction, 0.0f, 0.5f, 1.0f, 1.0f, 0.0f); }
emitter.cullFace(direction); }
} emitter.spriteBake(0, sprite, MutableQuadView.BAKE_LOCK_UV);
} }
emitter.spriteBake(0, sprite, MutableQuadView.BAKE_LOCK_UV);
} @Override
public boolean isVanillaAdapter() {
@Override return false;
public boolean isVanillaAdapter() { }
return false;
} @Override
public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos,
@Override Supplier<Random> randomSupplier, RenderContext context) {
public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, context.meshConsumer().accept(mesh);
Supplier<Random> randomSupplier, RenderContext context) { }
context.meshConsumer().accept(mesh);
} @Override
public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) {
@Override context.meshConsumer().accept(mesh);
public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) { }
context.meshConsumer().accept(mesh);
} @Override
public List<BakedQuad> getQuads(BlockState state, Direction face, Random random) {
@Override return null;
public List<BakedQuad> getQuads(BlockState state, Direction face, Random random) { }
return null;
} @Override
public boolean useAmbientOcclusion() {
@Override return false;
public boolean useAmbientOcclusion() { }
return false;
} @Override
public boolean hasDepth() {
@Override return false;
public boolean hasDepth() { }
return false;
} @Override
public boolean isSideLit() {
@Override return true;
public boolean isSideLit() { }
return true;
} @Override
public boolean isBuiltin() {
@Override return false;
public boolean isBuiltin() { }
return false;
} @Override
public Sprite getSprite() {
@Override return this.sprites[0];
public Sprite getSprite() { }
return this.sprites[0];
} @Override
public ModelTransformation getTransformation() {
@Override return this.transformation;
public ModelTransformation getTransformation() { }
return this.transformation;
} @Override
public ModelOverrideList getOverrides() {
@Override return ModelOverrideList.EMPTY;
public ModelOverrideList getOverrides() { }
return ModelOverrideList.EMPTY;
} @Override
public Collection<Identifier> getModelDependencies() {
@Override return Arrays.asList(DEFAULT_MODEL);
public Collection<Identifier> getModelDependencies() { }
return Arrays.asList(DEFAULT_MODEL);
} @Override
public Collection<SpriteIdentifier> getTextureDependencies(Function<Identifier, UnbakedModel> unbakedModelGetter,
@Override Set<Pair<String, String>> unresolvedTextureReferences) {
public Collection<SpriteIdentifier> getTextureDependencies(Function<Identifier, UnbakedModel> unbakedModelGetter, return Arrays.asList(spritesIDs);
Set<Pair<String, String>> unresolvedTextureReferences) { }
return Arrays.asList(spritesIDs); }
}
}

View file

@ -1,55 +1,53 @@
package ru.betterend.mixin.client; package ru.betterend.mixin.client;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.At.Shift; import org.spongepowered.asm.mixin.injection.At.Shift;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.block.Block;
import net.minecraft.block.Block; import net.minecraft.client.render.model.ModelLoader;
import net.minecraft.client.render.model.ModelLoader; import net.minecraft.client.render.model.json.JsonUnbakedModel;
import net.minecraft.client.render.model.json.JsonUnbakedModel; import net.minecraft.client.render.model.json.ModelVariantMap.DeserializationContext;
import net.minecraft.client.render.model.json.ModelVariantMap.DeserializationContext; import net.minecraft.util.Identifier;
import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.Registry; import ru.betterend.BetterEnd;
import ru.betterend.interfaces.IdentifiedContext;
import ru.betterend.BetterEnd; import ru.betterend.interfaces.Patterned;
import ru.betterend.interfaces.IdentifiedContext;
import ru.betterend.interfaces.Patterned; @Mixin(ModelLoader.class)
public class ModelLoaderMixin {
@Mixin(ModelLoader.class)
public class ModelLoaderMixin { @Shadow
private DeserializationContext variantMapDeserializationContext;
@Shadow
private DeserializationContext variantMapDeserializationContext; @Inject(method = "loadModelFromJson", at = @At("HEAD"), cancellable = true)
private void loadModelFromJson(Identifier id, CallbackInfoReturnable<JsonUnbakedModel> info) {
@Inject(method = "loadModelFromJson", at = @At("HEAD"), cancellable = true) if (id.getNamespace().equals(BetterEnd.MOD_ID) && id.getPath().contains("pattern")) {
private void loadModelFromJson(Identifier id, CallbackInfoReturnable<JsonUnbakedModel> info) { String data[] = id.getPath().split("/");
if (id.getNamespace().equals(BetterEnd.MOD_ID) && id.getPath().contains("pattern")) { Identifier blockId = new Identifier(id.getNamespace(), data[1]);
String data[] = id.getPath().split("/"); Block block = Registry.BLOCK.get(blockId);
Identifier blockId = new Identifier(id.getNamespace(), data[1]); if (block instanceof Patterned) {
Block block = Registry.BLOCK.get(blockId); String pattern = ((Patterned) block).modelPattern(data[1]);
if (block instanceof Patterned) { info.setReturnValue(JsonUnbakedModel.deserialize(pattern));
String pattern = ((Patterned) block).modelPattern(data[1]); info.cancel();
info.setReturnValue(JsonUnbakedModel.deserialize(pattern)); }
info.cancel(); }
} }
}
} @Inject(method = "loadModel", at = @At(
value = "INVOKE",
@Inject(method = "loadModel", at = @At( target = "Lnet/minecraft/client/render/model/json/ModelVariantMap$DeserializationContext;setStateFactory(Lnet/minecraft/state/StateManager;)V",
value = "INVOKE", shift = Shift.AFTER))
target = "Lnet/minecraft/client/render/model/json/ModelVariantMap$DeserializationContext;setStateFactory(Lnet/minecraft/state/StateManager;)V", private void loadModel(Identifier id, CallbackInfo info) {
shift = Shift.AFTER)) IdentifiedContext context = IdentifiedContext.class.cast(variantMapDeserializationContext);
private void loadModel(Identifier id, CallbackInfo info) { if (id.getNamespace().equals(BetterEnd.MOD_ID)) {
IdentifiedContext context = IdentifiedContext.class.cast(variantMapDeserializationContext); context.setContextId(BetterEnd.makeID("pattern/" + id.getPath()));
if (id.getNamespace().equals(BetterEnd.MOD_ID)) { } else {
context.setContextId(BetterEnd.makeID("pattern/" + id.getPath())); context.setContextId(null);
} else { }
context.setContextId(null); }
} }
}
}

View file

@ -1,44 +1,43 @@
package ru.betterend.mixin.client; package ru.betterend.mixin.client;
import java.io.Reader; import java.io.Reader;
import java.io.StringReader; import java.io.StringReader;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.client.render.model.json.ModelVariantMap; import net.minecraft.client.render.model.json.ModelVariantMap;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
import ru.betterend.interfaces.IdentifiedContext;
import ru.betterend.interfaces.IdentifiedContext; import ru.betterend.interfaces.Patterned;
import ru.betterend.interfaces.Patterned;
@Mixin(ModelVariantMap.class)
@Mixin(ModelVariantMap.class) public abstract class ModelVariantMapMixin {
public abstract class ModelVariantMapMixin {
@Shadow
@Shadow static ModelVariantMap deserialize(ModelVariantMap.DeserializationContext context, Reader reader) {
static ModelVariantMap deserialize(ModelVariantMap.DeserializationContext context, Reader reader) { return null;
return null; }
}
@Inject(method = "deserialize", at = @At("HEAD"), cancellable = true)
@Inject(method = "deserialize", at = @At("HEAD"), cancellable = true) private static void deserializeBlockState(ModelVariantMap.DeserializationContext context, Reader reader, CallbackInfoReturnable<ModelVariantMap> info) {
private static void deserializeBlockState(ModelVariantMap.DeserializationContext context, Reader reader, CallbackInfoReturnable<ModelVariantMap> info) { IdentifiedContext idContext = IdentifiedContext.class.cast(context);
IdentifiedContext idContext = IdentifiedContext.class.cast(context); Identifier id = idContext.getContextId();
Identifier id = idContext.getContextId(); if (id != null && id.getPath().contains("pattern")) {
if (id != null && id.getPath().contains("pattern")) { String[] data = id.getPath().split("/");
String[] data = id.getPath().split("/"); Identifier blockId = new Identifier(id.getNamespace(), data[1]);
Identifier blockId = new Identifier(id.getNamespace(), data[1]); Block block = Registry.BLOCK.get(blockId);
Block block = Registry.BLOCK.get(blockId); idContext.removeId();
idContext.removeId(); if (block instanceof Patterned) {
if (block instanceof Patterned) { String pattern = ((Patterned) block).blockStatePattern(data[1]);
String pattern = ((Patterned) block).blockStatePattern(data[1]); info.setReturnValue(deserialize(context, new StringReader(pattern)));
info.setReturnValue(deserialize(context, new StringReader(pattern))); info.cancel();
info.cancel(); }
} }
} }
} }
}

View file

@ -1,11 +1,11 @@
package ru.betterend.registry; package ru.betterend.registry;
import ru.betterend.world.features.BlueVineFeature; import ru.betterend.world.features.BlueVineFeature;
import ru.betterend.world.features.PythadendronTreeFeature;
import ru.betterend.world.features.DoublePlantFeature; import ru.betterend.world.features.DoublePlantFeature;
import ru.betterend.world.features.EndFeature; import ru.betterend.world.features.EndFeature;
import ru.betterend.world.features.EndLakeFeature; import ru.betterend.world.features.EndLakeFeature;
import ru.betterend.world.features.MossyGlowshroomFeature; import ru.betterend.world.features.MossyGlowshroomFeature;
import ru.betterend.world.features.PythadendronTreeFeature;
import ru.betterend.world.features.SinglePlantFeature; import ru.betterend.world.features.SinglePlantFeature;
import ru.betterend.world.features.VineFeature; import ru.betterend.world.features.VineFeature;