Jump to content

XFactHD

Members
  • Posts

    372
  • Joined

  • Last visited

Everything posted by XFactHD

  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.
  14. I tried it and the transforms seem really off. When I use the data I would have used inside the model if it was a json model, the scaling, translation and rotation are completely off. Does the Forge Blockstate transform the item differently or am I making a dumb mistake again? This is the new Blockstate file: { "forge_marker": 1, "defaults": { }, "variants": { "gun": { ..., "mp7": { "model": "rssmc:gun/item_gun_mp7.obj", "transform": { "thirdperson_righthand": { "rotation": [ {"x": 0}, {"y": 180}, {"z": 0} ], "translation": [ -1.25, -1.50, -3.25 ], "scale": 0.20 }, "firstperson_righthand": { "rotation": [ {"x": 0}, {"y": 180}, {"z": 0} ], "translation": [ -3.75, -0.75, -6.75 ], "scale": 0.30 }, "gui": { "rotation": [ {"x": 26}, {"y": 218}, {"z": 0} ], "translation": [ -4.50, -0.25, 0.00 ], "scale": 0.20 }, "fixed": { "rotation": [ {"x": 0}, {"y": 90}, {"z": 0} ], "translation": [ 4.75, -1.00, -0.75 ], "scale": 0.15 }, "ground": { "rotation": [ {"x": 0}, {"y": 0}, {"z": 0} ], "translation": [ 1.75, 2.50, 5.00 ], "scale": 0.20 } } }, ... } } } This is what I expect it to look like: This is what it looks like:
  15. Great, thanks for the explanation, I will try that out tomorrow.
  16. In my mod I am using OBJ models for the guns which means that I have to use a Forge Blockstate file to apply transformations to the model. To find the best values I used the ItemTransformHelper mod. When I put the display section it generated into the Blockstate file, the model does load but it is not translated, scaled or rotated in any way. Do I need to create a custom implementation of the OBJModel class to be able to do this or is there a dumb mistake in the Blockstate file? This is the important part of my Blockstate file: { "forge_marker": 1, "defaults": { }, "variants": { "gun": { ..., "mp7": { "model": "rssmc:gun/item_gun_mp7.obj", "display": { "thirdperson_righthand": { "rotation": [ 0, 180, 0 ], "translation": [ -1.25, -1.50, -3.25 ], "scale": [ 0.20, 0.20, 0.20 ] }, "thirdperson_lefthand": { "rotation": [ 0, 0, 0 ], "translation": [ 0.00, 0.00, 0.00 ], "scale": [ 1.00, 1.00, 1.00 ] }, "firstperson_righthand": { "rotation": [ 0, 180, 0 ], "translation": [ -3.75, -0.75, -6.75 ], "scale": [ 0.30, 0.30, 0.30 ] }, "firstperson_lefthand": { "rotation": [ 0, 0, 0 ], "translation": [ 0.00, 0.00, 0.00 ], "scale": [ 1.00, 1.00, 1.00 ] }, "gui": { "rotation": [ 26, 218, 0 ], "translation": [ -4.50, -0.25, 0.00 ], "scale": [ 0.20, 0.20, 0.20 ] }, "head": { "rotation": [ 0, 0, 0 ], "translation": [ 0.00, 0.00, 0.00 ], "scale": [ 1.00, 1.00, 1.00 ] }, "fixed": { "rotation": [ 0, 90, 0 ], "translation": [ 4.75, -1.00, -0.75 ], "scale": [ 0.15, 0.15, 0.15 ] }, "ground": { "rotation": [ 0, 0, 0 ], "translation": [ 1.75, 2.50, 5.00 ], "scale": [ 0.20, 0.20, 0.20 ] } } }, ... } } }
  17. I got it fixed now. After rewriting the ItemBlockBarricade class it still didn't work until I noticed that the TileEntity wasn't existing anymore at the time I tried to access it in onBlockDestroyedByPlayer(). When I moved the destruction of the other blocks to breakBlock() it worked flawlessly eventhough this might be ineffecient because that method is also called for the blocks I destroy in this method which means that I am once destroying blocks and 5 times destroying air.
  18. In the end I had to make one enum like value out of three booleans in the statemapper. I would have preferred to be able to do nested conditions but that seems to not be possible.
  19. I am already using a custom IStateMapper and because of the obscene amount of states the block has, I am already dividing it into four blockstate files.
  20. I have used the debugger while setting as well as while reading the values in the TileEntity. When I set them, they are all correct, when I read them on the client they are also correct but when I read them on the server I only get bullshit. The values are however saved correctly on the server. I even tested this with the dedicated server. @Draco18s OK, fair enough, I could have been more precise from the beginning.
  21. You could have assumed it as I said after your first reply that I am already taking care of the synchronisation.
  22. The class it extends already does that to only refresh when the blocks are not the same.
×
×
  • Create New...

Important Information

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