Compare commits

...

3 Commits

Author SHA1 Message Date
e9885940e2 robot stuff wip i hate minecraft 2026-05-02 22:01:49 +02:00
c63912c1f3 fix 2026-05-02 09:00:51 +02:00
323d213291 render robot model with blockentrenderer 2026-05-01 23:25:22 +02:00
11 changed files with 216 additions and 166 deletions

View File

@@ -15,6 +15,7 @@ import org.neoflock.neocomputers.block.CableBlock;
import org.neoflock.neocomputers.entity.BlockEntities;
import org.neoflock.neocomputers.entity.render.CaseEntityRenderer;
import org.neoflock.neocomputers.entity.render.RelayEntityRenderer;
import org.neoflock.neocomputers.entity.render.RobotEntityRenderer;
import org.neoflock.neocomputers.entity.render.ScreenEntityRenderer;
import org.neoflock.neocomputers.item.Items;
import org.neoflock.neocomputers.platforms.fabric.client.model.ModelLoader;
@@ -26,6 +27,7 @@ public class NeoComputersFabricClient implements ClientModInitializer {
BlockEntityRenderers.register(BlockEntities.INSTANCE.getSCREEN_ENTITY().get(), ScreenEntityRenderer::new);
BlockEntityRenderers.register(BlockEntities.INSTANCE.getCASE_ENTITY().get(), CaseEntityRenderer::new);
BlockEntityRenderers.register(BlockEntities.INSTANCE.getRELAY_ENTITY().get(), RelayEntityRenderer::new);
BlockEntityRenderers.register(BlockEntities.INSTANCE.getROBOT_ENTITY().get(), RobotEntityRenderer::new);
ColorProviderRegistry.BLOCK.register((state, world, pos, index) -> {
if (index == 0) {

View File

@@ -1,138 +0,0 @@
//package org.neoflock.neocomputers.platforms.fabric.client.model;
//
//import net.fabricmc.fabric.api.renderer.v1.Renderer;
//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.MeshBuilder;
//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.render.RenderContext;
//import net.minecraft.client.Minecraft;
//import net.minecraft.client.renderer.block.model.BakedQuad;
//import net.minecraft.client.renderer.block.model.ItemOverrides;
//import net.minecraft.client.renderer.block.model.ItemTransforms;
//import net.minecraft.client.renderer.texture.TextureAtlas;
//import net.minecraft.client.renderer.texture.TextureAtlasSprite;
//import net.minecraft.client.resources.model.*;
//import net.minecraft.core.BlockPos;
//import net.minecraft.core.Direction;
//import net.minecraft.resources.ResourceLocation;
//import net.minecraft.util.RandomSource;
//import net.minecraft.world.level.BlockAndTintGetter;
//import net.minecraft.world.level.block.state.BlockState;
//import org.jetbrains.annotations.Nullable;
//import org.neoflock.neocomputers.NeoComputers;
//
//import java.util.ArrayList;
//import java.util.Collection;
//import java.util.List;
//import java.util.function.Function;
//import java.util.function.Supplier;
//
//// this totally could have been done with datagen, why do i do this
//public class CableModel implements BakedModel, UnbakedModel, FabricBakedModel {
// private TextureAtlasSprite sprite = Minecraft
//// TextureAtlasSprite sprite = atlas.apply(new Material(TextureAtlas.LOCATION_BLOCKS, ResourceLocation.withDefaultNamespace("block/furnace_top")));
//
// private float MIN = 6/16F;
// private float MAX = 10/16F;
//
// private BlockState state;
//
// private Mesh mesh;
// @Override
// public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction direction, RandomSource random) {
//// NeoComputers.INSTANCE.getLOGGER().info("Obtained blockstate!");
// this.state = state;
// return List.of();
// }
//
// @Override
// public boolean useAmbientOcclusion() {
// return false;
// }
//
// @Override
// public boolean isGui3d() {
// return true;
// }
//
// @Override
// public boolean usesBlockLight() {
// return true;
// }
//
// @Override
// public boolean isCustomRenderer() {
// return false;
// }
//
// @Override
// public TextureAtlasSprite getParticleIcon() {
// Function<ResourceLocation, TextureAtlasSprite> atlas = Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS);
// return atlas.apply(ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "block/teto"));
// }
//
// @Override
// public ItemTransforms getTransforms() {
// return ItemTransforms.NO_TRANSFORMS;
// }
//
// @Override
// public ItemOverrides getOverrides() {
// return ItemOverrides.EMPTY;
// }
//
// @Override
// public Collection<ResourceLocation> getDependencies() {
// return List.of();
// }
//
// @Override
// public void resolveParents(Function<ResourceLocation, UnbakedModel> resolver) {
// }
//
// @Override
// public @Nullable BakedModel bake(ModelBaker baker, Function<Material, TextureAtlasSprite> spriteGetter, ModelState state) {
// TextureAtlasSprite sprite = spriteGetter.apply(new Material(TextureAtlas.LOCATION_BLOCKS, ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "block/teto")));
//
// Renderer renderer = RendererAccess.INSTANCE.getRenderer();
// MeshBuilder builder = renderer.meshBuilder();
// QuadEmitter emitter = builder.getEmitter();
//
// bakeCenter(emitter, sprite);
//
//
// mesh = builder.build();
// return this;
// }
//
// @Override
// public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier<RandomSource> randomSupplier, RenderContext context) {
// mesh.outputTo(context.getEmitter());
// }
//
// public void bakeCenter(QuadEmitter emitter, TextureAtlasSprite sprite) {
// for (Direction dir : Direction.values()) {
// emitter.square(dir, MIN, MIN, MAX, MAX, MIN);
// emitter.spriteBake(sprite, MutableQuadView.BAKE_LOCK_UV);
// emitter.color(-1, -1, -1, -1);
// emitter.emit();
// }
// }
// public void bakeConnection(Direction dir, QuadEmitter emitter, TextureAtlasSprite sprite) {
// int mag = dir.getStepX()+dir.getStepZ(); // i dont want to hear it
// float bottom = dir.getStepY()==0 ? 6/16F : (dir.getStepY()==1 ? 10/16F : 0F);
//
// for (Direction d : dir.getAxis().getPlane().faces) {
// emitter.square(d, (6/16F)+0.5F*mag, bottom, 6/16F)
// }
//
// }
//
//// @Override
//// public boolean isVanillaAdapter() {
//// return false; // TODO: let this be true so maybe forge and fabric can be unified
//// }
//}

View File

@@ -1,8 +1,10 @@
package org.neoflock.neocomputers.platforms.fabric.client.model;
import kotlin.jvm.functions.Function1;
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
import net.fabricmc.fabric.impl.renderer.VanillaModelEncoder;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureAtlas;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.model.*;
@@ -49,7 +51,9 @@ public class FabricModelWrapper implements FabricBakedModel, UnbakedModel {
@Override
public @Nullable BakedModel bake(ModelBaker baker, Function<Material, TextureAtlasSprite> spriteGetter, ModelState state) {
model.bake(baker, spriteGetter, state);
// NeoComputers.INSTANCE.getLOGGER().info("{}", spriteGetter.apply(new Material()));
model._bake(spriteGetter);
// model.bake((Function1<? super ResourceLocation, ? extends TextureAtlasSprite>) Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS));
return model;
}
}

View File

@@ -15,7 +15,6 @@ public class ModelLoader implements ModelLoadingPlugin {
pluginContext.modifyModelOnLoad().register((original, context) -> {
final ModelResourceLocation id = context.topLevelId();
if (id != null && id.id().equals(ROBOT)) {
//// NeoComputers.INSTANCE.getLOGGER().error("DOING CABLEEEEEEE");
return new FabricModelWrapper(new RobotModel());
}
return original;

View File

@@ -35,7 +35,7 @@ object Blocks {
val REDSTONEIO_BLOCK: RegistrySupplier<Block> = BaseBlock.register("redio") { RedstoneIOBlock() }
val CABLE_BLOCK: RegistrySupplier<Block> = BaseBlock.register("cable") { CableBlock() }
val RELAY_BLOCK: RegistrySupplier<Block> = BaseBlock.register("relay") { RelayBlock() }
val ROBOT_BLOCK: RegistrySupplier<Block> = BaseBlock.register("robot") { BaseBlock(BlockBehaviour.Properties.of().noOcclusion()) }
val ROBOT_BLOCK: RegistrySupplier<Block> = BaseBlock.register("robot") { RobotBlock() }
fun registerBlockItems() {
BLOCKS.forEach(Consumer { sup: RegistrySupplier<Block> ->

View File

@@ -0,0 +1,34 @@
package org.neoflock.neocomputers.block
import net.minecraft.core.BlockPos
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.block.Blocks
import net.minecraft.world.level.block.EntityBlock
import net.minecraft.world.level.block.RenderShape
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.state.BlockBehaviour
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
import net.minecraft.world.phys.shapes.VoxelShape
import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.entity.RobotEntity
class RobotBlock : BaseBlock(Properties.of().noOcclusion()), EntityBlock { // todo: node stuff
override fun newBlockEntity(pos: BlockPos, state: BlockState): BlockEntity {
NeoComputers.LOGGER.info("block entity created..")
Blocks.CHEST
return RobotEntity(pos, state)
}
override fun getShape(state: BlockState, level: BlockGetter, pos: BlockPos, context: CollisionContext): VoxelShape? {
return Shapes.box(0.1, 0.1, 0.1, 0.9, 0.9, 0.9)
}
override fun getRenderShape(state: BlockState): RenderShape {
return RenderShape.INVISIBLE // this is so not good
}
// public RenderShape getRenderShape(BlockState state) {
// return RenderShape.ENTITYBLOCK_ANIMATED;
// }
}

View File

@@ -17,9 +17,10 @@ import net.minecraft.core.Direction
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.RandomSource
import net.minecraft.world.level.block.state.BlockState
import org.neoflock.neocomputers.NeoComputers
import java.util.function.Function
abstract class AbstractModel : BakedModel, UnbakedModel {
abstract class AbstractModel : BakedModel {
val atlas = Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS)
var baker: ModelBaker? = null;
var mesh: Map<Direction, List<BakedQuad>> = mapOf(
@@ -43,11 +44,16 @@ abstract class AbstractModel : BakedModel, UnbakedModel {
}
}
fun _bake(spriteGetter: Function<Material, TextureAtlasSprite>): BakedModel {
bake { r: Material -> spriteGetter.apply(r) }
return this
}
override fun getParticleIcon(): TextureAtlasSprite? {
return atlas.apply(particle())
}
// abstract fun bake(atlas: (ResourceLocation) -> TextureAtlasSprite)
abstract fun bake(atlas: (Material) -> TextureAtlasSprite)
abstract fun particle(): ResourceLocation
@@ -81,6 +87,8 @@ class SchizoConsumer {
if (sprite == null || normal == null) {
throw Error("quad not started")
}
// NeoComputers.LOGGER.info("{} {} -> {} {} ", u, v, sprite!!.getU(u), sprite!!.getV(v))
vertices.add(x.toBits())
vertices.add(y.toBits())
vertices.add(z.toBits())

View File

@@ -23,47 +23,44 @@ class RobotModel() : AbstractModel() {
val size = 0.4f
val l = 0.5f-size;
val h = 0.5f+size;
override fun getDependencies(): Collection<ResourceLocation?> = listOf()
override fun resolveParents(resolver: Function<ResourceLocation?, UnbakedModel?>) { }
// override fun bake(atlas: (ResourceLocation) -> TextureAtlasSprite) {
override fun bake(baker: ModelBaker, atlas: Function<Material?, TextureAtlasSprite?>, state: ModelState): BakedModel? {
NeoComputers.LOGGER.info("baking")
val sprite = atlas.apply(Material(TextureAtlas.LOCATION_BLOCKS, ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "block/robot")))!!
// TODO: fix dimensions (i eyeballed it)
override fun bake(atlas: (Material) -> TextureAtlasSprite) {
// override fun bake(atlas: Function<Material?, TextureAtlasSprite?>, state: ModelState): BakedModel {
val sprite = atlas(Material(TextureAtlas.LOCATION_BLOCKS, ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "block/robot")))
// val sprite = atlas.apply(Material(TextureAtlas.LOCATION_BLOCKS, ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "robot")))!!
var verts: SchizoConsumer = SchizoConsumer()
// top pyramid, enjoy reading this schizo mess
bakeTri(verts, Direction.WEST, sprite, l,l, l, h, 9f/16f,1F, 0f, 0f, 0f, 16f/32f)
bakeTri(verts, Direction.EAST, sprite, h, h, h, l, 9f/16f, 1F, 16/32f, 16/32f, 16/32f, 0f)
bakeTri(verts, Direction.SOUTH, sprite, l, h, h, h, 9f/16f, 1F, 0f, 16f/32f, 16f/32f, 16f/32f)
bakeTri(verts, Direction.NORTH, sprite, h, l, l,l, 9f/16f, 1F, 16/32f, 0f, 0f, 0f)
bakeTri(verts, Direction.WEST, sprite, l,l, l, h, 9f/16f,1f, 0f, 0f, 0f, 16f/32f)
bakeTri(verts, Direction.EAST, sprite, h, h, h, l, 9f/16f, 1f, 16/32f, 16/32f, 16/32f, 0f)
bakeTri(verts, Direction.SOUTH, sprite, l, h, h, h, 9f/16f, 1f, 0f, 16f/32f, 16f/32f, 16f/32f)
bakeTri(verts, Direction.NORTH, sprite, h, l, l,l, 9f/16f, 1f, 16/32f, 0f, 0f, 0f)
verts.startQuad(Direction.DOWN, sprite)
verts.startQuad(Direction.DOWN, sprite, 0)
verts.vertex(l, 9f/16F, h, 0xFFFFFFFF.toInt(), 16f/32f, 16/32F)
verts.vertex(l, 9f/16f, l, 0xFFFFFFFF.toInt(), 0F, 16/32F)
verts.vertex(h, 9f/16f, l, 0xFFFFFFFF.toInt(), 0F, 1F)
verts.vertex(h, 9f/16f, h, 0xFFFFFFFF.toInt(), 16/32F, 1F)
// bottom
bakeTri(verts, Direction.WEST, sprite, l, h, l, l, 7f/16f, 0F, 0f, 0f, 0f, 16f/32f)
bakeTri(verts, Direction.EAST, sprite, h, l, h, h, 7f/16f, 0F, 0f, 0f, 0f, 16f/32f)
bakeTri(verts, Direction.SOUTH, sprite, h, h, l, h, 7f/16f, 0F, 0f, 0f, 0f, 16f/32f)
bakeTri(verts, Direction.NORTH, sprite, l, l, h,l, 7f/16f, 0F, 0f, 0f, 0f, 16f/32f)
bakeTri(verts, Direction.WEST, sprite, l, h, l, l, 8f/16f, 1/16f, 0f, 0f, 0f, 16f/32f)
bakeTri(verts, Direction.EAST, sprite, h, l, h, h, 8f/16f, 1/16f, 0f, 0f, 0f, 16f/32f)
bakeTri(verts, Direction.SOUTH, sprite, h, h, l, h, 8f/16f, 1/16f, 0f, 0f, 0f, 16f/32f)
bakeTri(verts, Direction.NORTH, sprite, l, l, h,l, 8f/16f, 1/16f, 0f, 0f, 0f, 16f/32f)
verts.startQuad(Direction.UP, sprite)
verts.vertex(h, 7f/16F, l, 0xFFFFFFFF.toInt(), 16/32F, 16/32F)
verts.vertex(l, 7f/16f, l, 0xFFFFFFFF.toInt(), 0F, 16/32F)
verts.vertex(l, 7f/16f, h, 0xFFFFFFFF.toInt(), 0F, 1F)
verts.vertex(h, 7f/16f, h, 0xFFFFFFFF.toInt(), 16/32F, 1F)
verts.startQuad(Direction.UP, sprite, 0)
verts.vertex(h, 8f/16F, l, 0xFFFFFFFF.toInt(), 16/32F, 16/32F)
verts.vertex(l, 8f/16f, l, 0xFFFFFFFF.toInt(), 0F, 16/32F)
verts.vertex(l, 8f/16f, h, 0xFFFFFFFF.toInt(), 0F, 1F)
verts.vertex(h, 8f/16f, h, 0xFFFFFFFF.toInt(), 16/32F, 1F)
this.mesh = verts.mesh
return this
}
fun bakeTri(verts: SchizoConsumer, normal: Direction, sprite: TextureAtlasSprite, lx: Float, lz: Float, rx: Float, rz: Float, dy: Float, uy: Float, lu: Float, lv: Float, ru: Float, rv: Float) {
verts.startQuad(normal, sprite)
verts.startQuad(normal, sprite, 0)
verts.vertex(0.5F, uy, 0.5F, 0xFFFFFFFF.toInt(), 8F/32F, 8F/32F)
verts.vertex(0.5F, uy, 0.5F, 0xFFFFFFFF.toInt(), 8F/32F, 8F/32F)
verts.vertex(lx, dy, lz, 0xFFFFFFFF.toInt(), lu, lv)

View File

@@ -94,6 +94,12 @@ object BlockEntities {
)
}
val ROBOT_ENTITY: RegistrySupplier<BlockEntityType<RobotEntity>> = BLOCKENTITIES.register("robot") {
BlockEntityType(
::RobotEntity, setOf(Blocks.ROBOT_BLOCK.get()), BullshitFix()
)
}
fun registerPowerBlocks() {
PowerManager.registerPowerDevice(CAPACITOR_ENTITY.get())
PowerManager.registerPowerDevice(CAPACITOR2_ENTITY.get())

View File

@@ -0,0 +1,16 @@
package org.neoflock.neocomputers.entity
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.core.BlockPos
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.state.BlockState
import org.neoflock.neocomputers.NeoComputers
class RobotEntity(pos: BlockPos, state: BlockState) : BlockEntity(BlockEntities.ROBOT_ENTITY.get(), pos, state,) {
val body: ModelPart? = null
val name = "Diddyx" //TODO: names
init {
NeoComputers.LOGGER.info("yooo")
}
}

View File

@@ -0,0 +1,122 @@
package org.neoflock.neocomputers.entity.render
import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.DefaultVertexFormat
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.blaze3d.vertex.VertexConsumer
import com.mojang.blaze3d.vertex.VertexFormat
import com.mojang.math.Axis
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.Font
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.client.renderer.GameRenderer
import net.minecraft.client.renderer.ItemBlockRenderTypes
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.RenderStateShard
import net.minecraft.client.renderer.RenderType
import net.minecraft.client.renderer.RenderType.CompositeState
import net.minecraft.client.renderer.block.ModelBlockRenderer
import net.minecraft.client.renderer.block.model.BakedQuad
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
import net.minecraft.client.renderer.entity.LivingEntityRenderer
import net.minecraft.client.renderer.texture.OverlayTexture
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.Material
import net.minecraft.client.resources.model.ModelResourceLocation
import net.minecraft.client.resources.model.ModelState
import net.minecraft.core.Direction
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.RandomSource
import net.minecraft.world.item.DyeColor
import net.minecraft.world.phys.Vec3
import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.block.model.RobotModel
import org.neoflock.neocomputers.entity.RobotEntity
import kotlin.math.sin
class RobotEntityRenderer(val context: BlockEntityRendererProvider.Context) : BlockEntityRenderer<RobotEntity> {
val atlas: (Material) -> TextureAtlasSprite = { m ->
Minecraft.getInstance().getTextureAtlas(m.atlasLocation()).apply(m.texture())
}
val loc: ResourceLocation = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "robot")
var model: BakedModel? = Minecraft.getInstance().modelManager.getModel(ModelResourceLocation.inventory(loc))
val renderer: ModelBlockRenderer = ModelBlockRenderer(Minecraft.getInstance().blockColors) // so ass
val STREAK_RENDER_TYPE = RenderType.create("nc_robot_streak", DefaultVertexFormat.POSITION_TEX_COLOR, VertexFormat.Mode.QUADS, RenderType.TRANSIENT_BUFFER_SIZE,
CompositeState.builder()
.setShaderState(RenderStateShard.ShaderStateShard { GameRenderer.getPositionTexColorShader() })
.setTransparencyState(RenderStateShard.ADDITIVE_TRANSPARENCY)
.setTextureState(RenderStateShard.TextureStateShard(ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/block/robot.png"), false, false))
.createCompositeState(false))
override fun render(ent: RobotEntity, partialTick: Float, poseStack: PoseStack, bufferSource: MultiBufferSource, packedLight: Int, packedOverlay: Int) {
poseStack.pushPose()
// poseStack.translate(0f, sin(ent.level!!.dayTime.toFloat()/20F)*0.02F, 0f)
val modelbuffer = bufferSource.getBuffer(RenderType.entitySolid(TextureAtlas.LOCATION_BLOCKS))
val colorbuffer = bufferSource.getBuffer(STREAK_RENDER_TYPE)
val col = DyeColor.LIGHT_GRAY.fireworkColor
val red = ((col and 0xFF0000) shr 8*2) / 255f
val green = ((col and 0xFF00) shr 8) / 255f
val blue = ((col and 0xFF)) / 255f
renderer.renderModel(poseStack.last(), modelbuffer, ent.blockState, model!!, red, green, blue, packedLight, packedOverlay)
renderLight(poseStack, colorbuffer, (ent.level!!.dayTime%16).toInt())
// TODO: crafting table and chest little models
poseStack.popPose()
renderTag(ent, Component.literal(ent.name), poseStack, bufferSource, packedLight, partialTick)
}
// offset is 0-15
fun renderLight(poseStack: PoseStack, buffer: VertexConsumer, offset: Int) {
poseStack.pushPose()
val u1 = 0.5f
val v1 = 0.5f + offset*1/32f
val u2 = 1F
val v2 = 17/32f + offset*1/32f
for (i in 0..3) {
poseStack.rotateAround(Axis.YP.rotationDegrees(90f), 0.5f, 0.5f, 0.5f)
buffer.addVertex(poseStack.last(),0.1f+2/16f, 7/16f, 0.9f-2/16f).setColor(1f, 0f, 0f, 1f).setUv(u2, v2)
buffer.addVertex(poseStack.last(),0.1f+2/16f, 9/16f, 0.9f-2/16f).setColor(1f, 0f, 0f, 1f).setUv(u2, v1)
buffer.addVertex(poseStack.last(),0.1f+2/16f, 9/16f, 0.1f+2/16f).setColor(1f, 0f, 0f, 1f).setUv(u1, v1)
buffer.addVertex(poseStack.last(),0.1f+2/16f, 7/16f, 0.1f+2/16f).setColor(1f, 0f, 0f, 1f).setUv(u1, v2)
}
poseStack.popPose()
}
fun renderTag(ent: RobotEntity, name: Component, stack: PoseStack, source: MultiBufferSource, light: Int, ptick: Float) {
val d = Minecraft.getInstance().cameraEntity!!.distanceToSqr(ent.blockPos.center)
if (d > 4096.0) return
val vec = Vec3(0.5, 20 / 16.0, 0.5)
stack.pushPose()
stack.translate(vec.x, vec.y, vec.z)
// stack.mulPose(context.entityRenderer.cameraOrientation())
stack.scale(0.025F, -0.025F, 0.025F)
val opacity = Minecraft.getInstance().options.getBackgroundOpacity(0.25F)
val alpha: Int = (opacity * 255.0f).toInt() shl 24
// val alpha = 255
val halfwidth = (-context.font.width(name)) / 2;
RenderSystem.disableDepthTest()
context.font.drawInBatch(name, halfwidth.toFloat(), 2f, 0xFFFFFF, false, stack.last().pose(), source, Font.DisplayMode.SEE_THROUGH, alpha, light)
RenderSystem.enableDepthTest()
stack.popPose()
}
}