mirror of
https://github.com/FabricMC/fabric.git
synced 2024-11-14 19:25:23 -05:00
Add a block appearance API (#2579)
* Add block appearance API * Add class javadoc for FabricBlock and FabricBlockState * Address reviews * Remove OverrideOnly from getAppearance * Fix javadoc issues
This commit is contained in:
parent
a1d87cb885
commit
12bfe4ea1a
22 changed files with 531 additions and 2 deletions
2
fabric-block-api-v1/build.gradle
Normal file
2
fabric-block-api-v1/build.gradle
Normal file
|
@ -0,0 +1,2 @@
|
|||
archivesBaseName = "fabric-block-api-v1"
|
||||
version = getSubprojectVersion(project)
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.block.v1;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
* General-purpose Fabric-provided extensions for {@link Block} subclasses.
|
||||
*
|
||||
* <p>Note: This interface is automatically implemented on all blocks via Mixin and interface injection.
|
||||
*/
|
||||
// Note to maintainers: Functions should only be added to this interface if they are general-purpose enough,
|
||||
// to be evaluated on a case-by-case basis. Otherwise, they are better suited for more specialized APIs.
|
||||
public interface FabricBlock {
|
||||
/**
|
||||
* Return the current appearance of the block, i.e. which block state this block reports to look like on a given side.
|
||||
*
|
||||
* <p>Common implementors are covers and facades, or any other mimic blocks that proxy another block's model.
|
||||
* These will want to override this method. In that case, make sure to carefully read the implementation guidelines below.
|
||||
*
|
||||
* <p>Common consumers are models with connected textures that wish to seamlessly connect to mimic blocks.
|
||||
* These will want to check the apparent block state using {@link FabricBlockState#getAppearance}.
|
||||
*
|
||||
* <p>Generally, the appearance will be queried from a nearby block,
|
||||
* identified by the optional {@code sourcePos} and {@code sourceState} parameters.
|
||||
*
|
||||
* <p>When a block changes appearance, it should trigger a chunk remesh for itself and the adjacent blocks,
|
||||
* for example by calling {@link World#updateListeners}.
|
||||
*
|
||||
* <p>Note: Overriding this method for a block does <strong>not</strong> change how it renders.
|
||||
* It's up to modded models to check for the appearance of nearby blocks and adjust accordingly.
|
||||
*
|
||||
* <h3>Implementation guidelines</h3>
|
||||
*
|
||||
* <p>This can be called on the server, where block entity data can be safely accessed,
|
||||
* and on the client, possibly in a meshing thread, where block entity data is not safe to access!
|
||||
* Here is an example of how data from a block entity can be handled safely.
|
||||
* The block entity needs to implement {@code RenderAttachmentBlockEntity} for this to work.
|
||||
* <pre>{@code @Override
|
||||
* public BlockState getAppearance(BlockState state, BlockRenderView renderView, BlockPos pos, Direction side, @Nullable BlockState sourceState, @Nullable BlockPos sourcePos) {
|
||||
* if (renderView instanceof ServerWorld serverWorld) {
|
||||
* // Server side, ok to use block entity directly!
|
||||
* BlockEntity blockEntity = serverWorld.getBlockEntity(pos);
|
||||
*
|
||||
* if (blockEntity instanceof ...) {
|
||||
* // Get data from block entity
|
||||
* return ...;
|
||||
* }
|
||||
* } else {
|
||||
* // Client side, need to use the render attachment!
|
||||
* RenderAttachedBlockView attachmentView = (RenderAttachedBlockView) renderView;
|
||||
* Object data = attachmentView.getBlockEntityRenderAttachment(pos);
|
||||
*
|
||||
* // Check if data is not null and of the correct type, and use that to determine the appearance
|
||||
* if (data instanceof ...) {
|
||||
* // get appearance for side ...
|
||||
* return ...;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // Example of varying the appearance based on the source pos
|
||||
* if (sourcePos != null) {
|
||||
* // get appearance for side ...
|
||||
* return ...;
|
||||
* }
|
||||
*
|
||||
* // If there is no other appearance, just return the original block state
|
||||
* return state;
|
||||
* });
|
||||
* }</pre>
|
||||
*
|
||||
* @param state state of this block, whose appearance is being queried
|
||||
* @param renderView the world this block is in
|
||||
* @param pos position of this block, whose appearance is being queried
|
||||
* @param side the side for which the appearance is being queried
|
||||
* @param sourceState (optional) state of the block that is querying the appearance, or null if unknown
|
||||
* @param sourcePos (optional) position of the block that is querying the appearance, or null if unknown
|
||||
* @return the appearance of the block on the given side; the original {@code state} can be returned if there is no better option
|
||||
*/
|
||||
default BlockState getAppearance(BlockState state, BlockRenderView renderView, BlockPos pos, Direction side, @Nullable BlockState sourceState, @Nullable BlockPos sourcePos) {
|
||||
return state;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.block.v1;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
|
||||
/**
|
||||
* General-purpose Fabric-provided extensions for {@link BlockState}, matching the functionality provided in {@link FabricBlock}.
|
||||
*
|
||||
* <p>Note: This interface is automatically implemented on all block states via Mixin and interface injection.
|
||||
*/
|
||||
public interface FabricBlockState {
|
||||
/**
|
||||
* Return the current appearance of the block, i.e. which block state this block reports to look like on a given side.
|
||||
*
|
||||
* @param renderView the world this block is in
|
||||
* @param pos position of this block, whose appearance is being queried
|
||||
* @param side the side for which the appearance is being queried
|
||||
* @param sourceState (optional) state of the block that is querying the appearance, or null if unknown
|
||||
* @param sourcePos (optional) position of the block that is querying the appearance, or null if unknown
|
||||
* @return the appearance of the block on the given side; the original {@code state} can be returned if there is no better option
|
||||
* @see FabricBlock#getAppearance
|
||||
*/
|
||||
default BlockState getAppearance(BlockRenderView renderView, BlockPos pos, Direction side, @Nullable BlockState sourceState, @Nullable BlockPos sourcePos) {
|
||||
BlockState self = (BlockState) this;
|
||||
return self.getBlock().getAppearance(self, renderView, pos, side, sourceState, sourcePos);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.block;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
|
||||
import net.fabricmc.fabric.api.block.v1.FabricBlock;
|
||||
|
||||
@Mixin(Block.class)
|
||||
public class BlockMixin implements FabricBlock { }
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.block;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
|
||||
import net.fabricmc.fabric.api.block.v1.FabricBlockState;
|
||||
|
||||
@Mixin(BlockState.class)
|
||||
public class BlockStateMixin implements FabricBlockState { }
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"required": true,
|
||||
"package": "net.fabricmc.fabric.mixin.block",
|
||||
"compatibilityLevel": "JAVA_17",
|
||||
"mixins": [
|
||||
"BlockMixin",
|
||||
"BlockStateMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
34
fabric-block-api-v1/src/main/resources/fabric.mod.json
Normal file
34
fabric-block-api-v1/src/main/resources/fabric.mod.json
Normal file
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "fabric-block-api-v1",
|
||||
"name": "Fabric Block API (v1)",
|
||||
"version": "${version}",
|
||||
"environment": "*",
|
||||
"license": "Apache-2.0",
|
||||
"icon": "assets/fabric-block-api-v1/icon.png",
|
||||
"contact": {
|
||||
"homepage": "https://fabricmc.net",
|
||||
"irc": "irc://irc.esper.net:6667/fabric",
|
||||
"issues": "https://github.com/FabricMC/fabric/issues",
|
||||
"sources": "https://github.com/FabricMC/fabric"
|
||||
},
|
||||
"authors": [
|
||||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.14.9"
|
||||
},
|
||||
"entrypoints": {
|
||||
},
|
||||
"description": "Hooks for blocks",
|
||||
"mixins": [
|
||||
"fabric-block-api-v1.mixins.json"
|
||||
],
|
||||
"custom": {
|
||||
"fabric-api:module-lifecycle": "stable",
|
||||
"loom:injected_interfaces": {
|
||||
"net/minecraft/class_2248": ["net/fabricmc/fabric/api/block/v1/FabricBlock"],
|
||||
"net/minecraft/class_2680": ["net/fabricmc/fabric/api/block/v1/FabricBlockState"]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ moduleDependencies(project, [
|
|||
])
|
||||
|
||||
testDependencies(project, [
|
||||
':fabric-block-api-v1',
|
||||
':fabric-blockrenderlayer-v1',
|
||||
':fabric-models-v0',
|
||||
':fabric-object-builder-api-v1',
|
||||
|
|
|
@ -30,11 +30,16 @@ import net.minecraft.util.Hand;
|
|||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import net.fabricmc.fabric.api.block.v1.FabricBlock;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachedBlockView;
|
||||
|
||||
public final class FrameBlock extends Block implements BlockEntityProvider {
|
||||
// Need to implement FabricBlock manually because this is a testmod for another Fabric module, otherwise it would be injected.
|
||||
public final class FrameBlock extends Block implements BlockEntityProvider, FabricBlock {
|
||||
public final Identifier id;
|
||||
|
||||
public FrameBlock(Identifier id) {
|
||||
|
@ -94,4 +99,16 @@ public final class FrameBlock extends Block implements BlockEntityProvider {
|
|||
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
|
||||
return new FrameBlockEntity(pos, state);
|
||||
}
|
||||
|
||||
// The frames don't look exactly like the block they are mimicking,
|
||||
// but the goal here is just to test the behavior with the pillar's connected textures. ;-)
|
||||
@Override
|
||||
public BlockState getAppearance(BlockState state, BlockRenderView renderView, BlockPos pos, Direction side, @Nullable BlockState sourceState, @Nullable BlockPos sourcePos) {
|
||||
// For this specific block, the render attachment works on both the client and the server, so let's use that.
|
||||
if (((RenderAttachedBlockView) renderView).getBlockEntityRenderAttachment(pos) instanceof Block mimickedBlock) {
|
||||
return mimickedBlock.getDefaultState();
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package net.fabricmc.fabric.test.renderer.simple;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Material;
|
||||
import net.minecraft.block.entity.BlockEntityType;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.Item;
|
||||
|
@ -24,6 +26,7 @@ import net.minecraft.util.Identifier;
|
|||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
|
||||
|
||||
/**
|
||||
|
@ -41,6 +44,9 @@ public final class RendererTest implements ModInitializer {
|
|||
};
|
||||
public static final BlockEntityType<FrameBlockEntity> FRAME_BLOCK_ENTITY = FabricBlockEntityTypeBuilder.create(FrameBlockEntity::new, FRAMES).build(null);
|
||||
|
||||
public static final Identifier PILLAR_ID = id("pillar");
|
||||
public static final Block PILLAR = new Block(FabricBlockSettings.of(Material.STONE));
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
for (FrameBlock frameBlock : FRAMES) {
|
||||
|
@ -48,6 +54,12 @@ public final class RendererTest implements ModInitializer {
|
|||
Registry.register(Registry.ITEM, frameBlock.id, new BlockItem(frameBlock, new Item.Settings().group(ItemGroup.MISC)));
|
||||
}
|
||||
|
||||
// To anyone testing this: pillars are supposed to connect vertically with each other.
|
||||
// Additionally, they should also connect vertically to frame blocks containing a pillar.
|
||||
// (The frame block will not change, but adjacent pillars should adjust their textures).
|
||||
Registry.register(Registry.BLOCK, PILLAR_ID, PILLAR);
|
||||
Registry.register(Registry.ITEM, PILLAR_ID, new BlockItem(PILLAR, new Item.Settings().group(ItemGroup.MISC)));
|
||||
|
||||
Registry.register(Registry.BLOCK_ENTITY_TYPE, id("frame"), FRAME_BLOCK_ENTITY);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.renderer.simple.client;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.render.model.BakedQuad;
|
||||
import net.minecraft.client.render.model.json.ModelOverrideList;
|
||||
import net.minecraft.client.render.model.json.ModelTransformation;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
|
||||
import net.fabricmc.fabric.api.block.v1.FabricBlockState;
|
||||
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.model.FabricBakedModel;
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper;
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||
import net.fabricmc.fabric.test.renderer.simple.RendererTest;
|
||||
|
||||
/**
|
||||
* Very crude implementation of a pillar block model that connects with pillars above and below.
|
||||
*/
|
||||
public class PillarBakedModel implements BakedModel, FabricBakedModel {
|
||||
private enum ConnectedTexture {
|
||||
ALONE, BOTTOM, MIDDLE, TOP
|
||||
}
|
||||
|
||||
// alone, bottom, middle, top
|
||||
private final Sprite[] sprites;
|
||||
|
||||
public PillarBakedModel(Sprite[] sprites) {
|
||||
this.sprites = sprites;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVanillaAdapter() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
|
||||
emitQuads(context.getEmitter(), blockView, state, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) {
|
||||
emitQuads(context.getEmitter(), null, null, null);
|
||||
}
|
||||
|
||||
private void emitQuads(QuadEmitter emitter, @Nullable BlockRenderView blockView, @Nullable BlockState state, @Nullable BlockPos pos) {
|
||||
for (Direction side : Direction.values()) {
|
||||
ConnectedTexture texture = ConnectedTexture.ALONE;
|
||||
|
||||
if (side.getAxis().isHorizontal() && blockView != null && state != null && pos != null) {
|
||||
boolean connectAbove = canConnect(blockView, pos.offset(Direction.UP), side, state, pos);
|
||||
boolean connectBelow = canConnect(blockView, pos.offset(Direction.DOWN), side, state, pos);
|
||||
|
||||
if (connectAbove && connectBelow) {
|
||||
texture = ConnectedTexture.MIDDLE;
|
||||
} else if (connectAbove) {
|
||||
texture = ConnectedTexture.BOTTOM;
|
||||
} else if (connectBelow) {
|
||||
texture = ConnectedTexture.TOP;
|
||||
}
|
||||
}
|
||||
|
||||
emitter.square(side, 0, 0, 1, 1, 0);
|
||||
emitter.spriteBake(0, sprites[texture.ordinal()], MutableQuadView.BAKE_LOCK_UV);
|
||||
emitter.spriteColor(0, -1, -1, -1, -1);
|
||||
emitter.emit();
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean canConnect(BlockRenderView blockView, BlockPos pos, Direction side, BlockState sourceState, BlockPos sourcePos) {
|
||||
// In this testmod we can't rely on injected interfaces - in normal mods the (FabricBlockState) cast will be unnecessary
|
||||
return ((FabricBlockState) blockView.getBlockState(pos)).getAppearance(blockView, pos, side, sourceState, sourcePos).isOf(RendererTest.PILLAR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction face, Random random) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useAmbientOcclusion() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDepth() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSideLit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltin() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sprite getParticleSprite() {
|
||||
return sprites[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelTransformation getTransformation() {
|
||||
return ModelHelper.MODEL_TRANSFORM_BLOCK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelOverrideList getOverrides() {
|
||||
return ModelOverrideList.EMPTY;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.renderer.simple.client;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.client.render.model.UnbakedModel;
|
||||
import net.minecraft.client.util.ModelIdentifier;
|
||||
|
||||
import net.fabricmc.fabric.api.client.model.ModelProviderContext;
|
||||
import net.fabricmc.fabric.api.client.model.ModelVariantProvider;
|
||||
import net.fabricmc.fabric.test.renderer.simple.RendererTest;
|
||||
|
||||
public class PillarModelVariantProvider implements ModelVariantProvider {
|
||||
@Override
|
||||
@Nullable
|
||||
public UnbakedModel loadModelVariant(ModelIdentifier modelId, ModelProviderContext context) {
|
||||
if (RendererTest.PILLAR_ID.equals(modelId)) {
|
||||
return new PillarUnbakedModel();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.renderer.simple.client;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.render.model.ModelBakeSettings;
|
||||
import net.minecraft.client.render.model.ModelLoader;
|
||||
import net.minecraft.client.render.model.UnbakedModel;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.client.util.SpriteIdentifier;
|
||||
import net.minecraft.screen.PlayerScreenHandler;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.test.renderer.simple.RendererTest;
|
||||
|
||||
public class PillarUnbakedModel implements UnbakedModel {
|
||||
private static final List<SpriteIdentifier> SPRITES = Stream.of("alone", "bottom", "middle", "top")
|
||||
.map(suffix -> new SpriteIdentifier(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, RendererTest.id("block/pillar_" + suffix)))
|
||||
.toList();
|
||||
|
||||
@Override
|
||||
public Collection<Identifier> getModelDependencies() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SpriteIdentifier> getTextureDependencies(Function<Identifier, UnbakedModel> unbakedModelGetter, Set<Pair<String, String>> unresolvedTextureReferences) {
|
||||
return SPRITES;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BakedModel bake(ModelLoader loader, Function<SpriteIdentifier, Sprite> textureGetter, ModelBakeSettings rotationContainer, Identifier modelId) {
|
||||
Sprite[] sprites = new Sprite[SPRITES.size()];
|
||||
|
||||
for (int i = 0; i < sprites.length; ++i) {
|
||||
sprites[i] = textureGetter.apply(SPRITES.get(i));
|
||||
}
|
||||
|
||||
return new PillarBakedModel(sprites);
|
||||
}
|
||||
}
|
|
@ -28,6 +28,7 @@ public final class RendererClientTest implements ClientModInitializer {
|
|||
@Override
|
||||
public void onInitializeClient() {
|
||||
ModelLoadingRegistry.INSTANCE.registerResourceProvider(manager -> new FrameModelResourceProvider());
|
||||
ModelLoadingRegistry.INSTANCE.registerVariantProvider(manager -> new PillarModelVariantProvider());
|
||||
|
||||
for (FrameBlock frameBlock : RendererTest.FRAMES) {
|
||||
BlockRenderLayerMap.INSTANCE.putBlock(frameBlock, RenderLayer.getCutoutMipped());
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 201 B |
Binary file not shown.
After Width: | Height: | Size: 194 B |
Binary file not shown.
After Width: | Height: | Size: 189 B |
Binary file not shown.
After Width: | Height: | Size: 196 B |
|
@ -48,7 +48,7 @@ import net.minecraft.world.BlockRenderView;
|
|||
* and then use {@link #getBlockEntityRenderAttachment(BlockPos)} to retrieve it. When called from the
|
||||
* main thread, that method will simply retrieve the data directly.
|
||||
*
|
||||
* <p>This interface is only guaranteed to be present in the client environment.
|
||||
* <p>This interface is guaranteed to be implemented on every {@link BlockRenderView} subclass.
|
||||
*/
|
||||
// XXX can not link net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel
|
||||
public interface RenderAttachedBlockView extends BlockRenderView {
|
||||
|
|
|
@ -12,6 +12,7 @@ prerelease=false
|
|||
fabric-api-base-version=0.4.12
|
||||
fabric-api-lookup-api-v1-version=1.6.10
|
||||
fabric-biome-api-v1-version=9.0.18
|
||||
fabric-block-api-v1-version=1.0.0
|
||||
fabric-blockrenderlayer-v1-version=1.1.21
|
||||
fabric-command-api-v1-version=1.2.12
|
||||
fabric-command-api-v2-version=2.1.8
|
||||
|
|
|
@ -15,6 +15,7 @@ include 'fabric-api-base'
|
|||
|
||||
include 'fabric-api-lookup-api-v1'
|
||||
include 'fabric-biome-api-v1'
|
||||
include 'fabric-block-api-v1'
|
||||
include 'fabric-blockrenderlayer-v1'
|
||||
include 'fabric-command-api-v2'
|
||||
include 'fabric-content-registries-v0'
|
||||
|
|
Loading…
Reference in a new issue