Jump to content


  • Posts

  • Joined

  • Last visited


  • Gender
  • Location
  • Personal Text
    Bad models incoming!

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

XFactHD's Achievements

Diamond Finder

Diamond Finder (5/8)



  1. I looked a little more through the vanilla code and as far as I can see, there is no way to make this work without modifying MC base code. Does anyone have another idea how to do this? For reference, this screenshot pretty much sums up the problems:
  2. My mod adds cameras which are viewed by setting the renderViewEntity to a dummy entity sitting in the camera. This works perfectly apart from the fact that the local player is not rendered. In other threads in this forum where people had the exact same problem, I found the hint to try using RenderWorldLastEvent to draw the local player anyway. This works for the most part but it has several issues: The player is not visible when looking through half transparent blocks like stained glass The shadow overlaps the feet instead of being obscured by the feet The shadow is visible through everything The item in hand is visible through everything This is the code I tried: @SubscribeEvent public static void onRenderWorldLast(final RenderWorldLastEvent event) { //FIXME: player isn't rendered through half transparent objects, shadow draws over feet and through objects, item in hand draws through objects Entity viewEntity = mc().getRenderViewEntity(); if (viewEntity instanceof ICameraEntity && mc().player != null) { float partialTicks = event.getPartialTicks(); Vec3d camera = Minecraft.getInstance().gameRenderer.getActiveRenderInfo().getProjectedView(); double x = MathHelper.lerp(partialTicks, mc().player.lastTickPosX, mc().player.getPosX()) - camera.x; double y = MathHelper.lerp(partialTicks, mc().player.lastTickPosY, mc().player.getPosY()) - camera.y; double z = MathHelper.lerp(partialTicks, mc().player.lastTickPosZ, mc().player.getPosZ()) - camera.z; float rotationYaw = MathHelper.lerp(partialTicks, mc().player.prevRotationYaw, mc().player.rotationYaw); MatrixStack matrix = event.getMatrixStack(); IRenderTypeBuffer buffer = mc().getRenderTypeBuffers().getBufferSource(); int packedLight = mc().getRenderManager().getPackedLight(mc().player, partialTicks); mc().getRenderManager().renderEntityStatic(mc().player, x, y, z, rotationYaw, partialTicks, matrix, buffer, packedLight); } } I have also tried adding different combinations of RenderSystem calls (alpha test, blending, depth test) before rendering the entity but nothing seems to help. I also looked into overriding the PlayerRenderer but shouldEntityRender() can't overrule the other checks done to decide if the entity should be rendered. Is there any better way to do this, am I just doing it wrong or is this simply not doable without hooking the check if an entity should be rendered?
  3. That will probably not get me anywhere as the wrapper is not only used to tell the ItemRenderer to call my ISTER but also to get the ItemCameraTransforms.TransformType that the ItemRenderer was called with. I read through the code multiple times and also came to the conclusion that there is no way the ItemModelMesher's cache is not getting rebuilt but when I put a breakpoint in RenderGun.loadModels(event.getModelRegistry()); and in ItemRenderer just before the ISTER gets called I get different instances of the model wrapper. I just walked through the code in the debugger again while writing this and as it turns out Forge is doing nothing wrong and I am the idiot here because my own caching fucked me over. Because every instance of the gun item has its own instance of the ISTER, I thought it would be a good idea to get the specific model from the big cache and cache it again so I don't have to access the cache map every frame... As soon as I remove this redundant layer of caching it works 🤦‍♂️
  4. You can probably call ClientRegistry.registerEntityShader() in a KeyBinding handler and call it with the correct ResourceLocation to activate it and with null to deactivate it. For the change to take effect you can just set the renderViewEntity again with if (Minecraft.getInstance().getRenderViewEntity() instanceof PlayerEntity) { Minecraft.getInstance().setRenderViewEntity(Minecraft.getInstance().getRenderViewEntity); } This will only set the renderViewEntity if it wasn't changed by another mod or MC itself to not be a player.
  5. I have a gun item in my mod that uses an ItemStackTileEntityRenderer to render attachments onto the base model. To enable the ISTER I am replacing the IBakedModel in ModelBakeEvent with a wrapper model that returns true in isBuiltInRenderer(). Because I don't want the model to shift in the GUI when the player is aiming down the sights, I am also using the wrapper to "sniff" the ItemCameraTransforms.TransformType that is passed to handlePerspective() before calling my renderer and make it available to the renderer. This works perfectly until I reload the resources (F3 + T). When the resources are reloaded, the reloaded models are replaced by the wrapper again and the wrapper is cached in the ISTER. The model that is used by the ItemRenderer to determine how to render an item is retrieved from the ItemModelMesher. The problem is that it seems like the ItemModelMesher's cache is not rebuilt after a resource reload. This leads to the ItemModelMesher to return the old models while my renderer tries to retrieve necessary information from the new models. Am I just being stupid and overlooking something simple or should I file this as a bug in Forge? This is the code in ModelBakeEvent: @SubscribeEvent public static void onModelBake(final ModelBakeEvent event) { for (EnumGun gun : EnumGun.values()) { ResourceLocation loc = new ModelResourceLocation(new ResourceLocation("r6mod", gun.toItemName()), "inventory"); IBakedModel original = event.getModelRegistry().get(loc); IBakedModel replacement = new BakedModelISTER(original); event.getModelRegistry().put(loc, replacement); } RenderGun.loadModels(event.getModelRegistry()); } This is the wrapper model package xfacthd.r6mod.client.model; import com.mojang.blaze3d.matrix.MatrixStack; import net.minecraft.block.BlockState; import net.minecraft.client.renderer.TransformationMatrix; import net.minecraft.client.renderer.model.BakedQuad; import net.minecraft.client.renderer.model.IBakedModel; import net.minecraft.client.renderer.model.ItemCameraTransforms; import net.minecraft.client.renderer.model.ItemOverrideList; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.util.Direction; import net.minecraftforge.client.model.data.IModelData; import net.minecraftforge.common.model.TransformationHelper; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.List; import java.util.Random; @SuppressWarnings("deprecation") public class BakedModelISTER implements IBakedModel { private final IBakedModel original; private ItemCameraTransforms.TransformType transform = ItemCameraTransforms.TransformType.NONE; public BakedModelISTER(IBakedModel original) { this.original = original; } @Nonnull @Override public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand, @Nonnull IModelData extraData) { return original.getQuads(state, side, rand, extraData); } @Override public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, Random rand) { return original.getQuads(state, side, rand); } @Override public TextureAtlasSprite getParticleTexture() { return original.getParticleTexture(); } @Override public IBakedModel handlePerspective(ItemCameraTransforms.TransformType type, MatrixStack matrix) { transform = type; TransformationMatrix tr = TransformationHelper.toTransformation(this.getItemCameraTransforms().getTransform(type)); if (!tr.isIdentity()) { tr.push(matrix); } return this; } @Override public ItemOverrideList getOverrides() { return original.getOverrides(); } @Override public boolean isAmbientOcclusion() { return original.isAmbientOcclusion(); } @Override public boolean isGui3d() { return original.isGui3d(); } @Override public boolean func_230044_c_() { return original.func_230044_c_(); } @Override //INFO: Must be true for ISTERs to work public boolean isBuiltInRenderer() { return true; } public ItemCameraTransforms.TransformType getTransformType() { return transform; } @Override public ItemCameraTransforms getItemCameraTransforms() { return original.getItemCameraTransforms(); } } If you need any more code, I will be happy to provide it. PS: If someone wants to suggest using overrides: I am not going to make the model system generate over 50000 models for all possible combinations
  6. You can do that by calling ClientRegistry.registerEntityShader(PlayerEntity.class, new ResourceLocation("minecraft:shaders/post/desaturate.json")) in your FMLClientSetupEvent handler. This will desaturate the game partially. If you want full grayscale, you need to copy the shader JSON file, edit the desaturation factor and change the ResourceLocation to the new path. Be aware however that this will only grayscale the world, not the GUIs.
  7. I dug a little deeper into this and found a rather convoluted (in my opinion) way to fix this. The only way to get the ItemCameraTransform.TransformType the renderer was called with seems to be to save it in your custom IBakedModel implementation (which you need anyway for ISTERs to work at all) in IBakedModel::handlePerspective which gets called from the item renderer before calling your ISTER. This also makes the call to IBakedModel::handlePerspective in the ISTER obsolete. Now that that works I have the problem that the models that are rendered do not have any shading whatsoever.
  8. I have a gun item that needs to have additional models like sights rendered on it. I got the ISTER to do "something", but I can't for the live of me figure out how to render the original item with its appropriate transforms. I specifically have two problems: There seems to be no way to get the ItemCameraTransforms.TransformType the renderer was called for The call to IBakedModel::handlePerspective seems to have no influence This is my render code: public class RenderGun extends ItemStackTileEntityRenderer { private EnumGun gun; private IBakedModel gunModel; private Random rand = new Random(); private IModelData data = new ModelDataMap.Builder().build(); public RenderGun() { } @Override public void render(ItemStack stack, MatrixStack mstack, IRenderTypeBuffer buffer, int combinedLight, int combinedOverlay) { if (gun == null && stack.getItem() instanceof ItemGun) { gun = ((ItemGun)stack.getItem()).getGun(); } if (gun != null && gunModel == null) { gunModel = getGunModel(gun); } IVertexBuilder builder = buffer.getBuffer(RenderType.getCutoutMipped()); if (gunModel != null) { //noinspection deprecation gunModel.handlePerspective(ItemCameraTransforms.TransformType.FIXED, mstack); for (BakedQuad quad : gunModel.getQuads(null, null, rand, data)) { builder.addQuad(mstack.getLast(), quad, 1.0F, 1.0F, 1.0F, combinedLight, combinedOverlay); } } } }
  9. The first hint is definetly interesting but unfortunately it doesn't allow me to attach some kind of callback. The RenderTickEvent however is the perfect solution, I don't know why I didn't think of that. Thank you very much for that.
  10. I am creating a mod that interfaces with the Logitech LED SDK to access the lighting of certain G-series keyboards. In any game that either interfaces with the LED SDK natively or is added via a profile in the Logitech Gaming Software switches from its specific lighting profile to the standard profile when it goes out of focus and back when it regains focus. To achieve this I need to check if the game window is in focus. When the player is in a world I can use a client tick event handler and check for Display.isActive() every tick but if I am in the main menu the tick handler is not running and therefore the profile switching doesn't work. Is there a way to get notified of a change in the window focus (kinda like the WindowListener in Swing)? This is the code I am currently using: private boolean focused = true; @SubscribeEvent(priority = EventPriority.LOWEST) public void onClientTick(TickEvent.ClientTickEvent event) { if (Display.isCreated()) { if (focused && !Display.isActive()) { focused = false; //shutdown lighting } else if (!focused && Display.isActive()) { focused = true; //restart lighting } } }
  11. You can't populate those static list's of Blocks and Items in FMLPreInitializationEvent and then expect them to be populated in the RegistryEvent as the registry events are fired before the FMLPreInitializationEvent.
  12. If you implement ISpecialArmor on you ItemArmor, you can handle damaging of the item yourself.
  13. This makes no sense to me. I tried simply calculating the correct values the way you suggested by doing TRSRTransformation trsr = new TRSRTransformation(new ItemTransformVec3f(new Vector3f(0, 180, 0), new Vector3f(-1.25F, -1.5F, -3.25F), new Vector3f(.2F, .2F, .2F))); but that did not work whatsoever. The translation and scale values I get out of this are the same as those I put in and the rotation value I get out of this is a strange negative value with a high negative exponent. Those values don't get me anywhere so it looks like I have to get the correct values by changing them in the file and reloading it over and over again which is really annoying.
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.