Hamster_Furtif Posted October 20, 2015 Posted October 20, 2015 Hey guys ! I recently decided to try do make a 3D armor with a custom rendering. Here is the tutorial I followed : http://bit.ly/1M5FpFh And here are my classes: The model: package com.hamsterfurtif.masks.models; import net.minecraft.client.model.ModelBiped; import net.minecraft.client.model.ModelRenderer; import net.minecraft.entity.Entity; public class MasqueWolf extends ModelBiped { //fields ModelRenderer Corde_back; ModelRenderer Corde_left; ModelRenderer Right; ModelRenderer Top; ModelRenderer WolfHead; ModelRenderer Ear1; ModelRenderer Ear2; ModelRenderer Nose; ModelRenderer Left; ModelRenderer Corde_right; public MasqueWolf(float f) { textureWidth = 64; textureHeight = 64; Corde_back = new ModelRenderer(this, 0, 0); Corde_back.addBox(0F, 0F, 0F, 8, 1, 0); Corde_back.setRotationPoint(-4F, 13.5F, -1F); Corde_back.setTextureSize(64, 32); Corde_back.mirror = true; setRotation(Corde_back, 0F, 0F, 0F); Corde_left = new ModelRenderer(this, 0, 0); Corde_left.addBox(0F, 0F, 0F, 0, 1, 4); Corde_left.setRotationPoint(4F, 13.5F, -5F); Corde_left.setTextureSize(64, 32); Corde_left.mirror = true; setRotation(Corde_left, 0F, 0F, 0F); Right = new ModelRenderer(this, 0, 0); Right.addBox(0F, 0F, 0F, 0, 8, 4); Right.setRotationPoint(4F, 10.5F, -9F); Right.setTextureSize(64, 32); Right.mirror = true; setRotation(Right, 0F, 0F, 0F); Top = new ModelRenderer(this, 0, 0); Top.addBox(0F, 0F, 0F, 8, 0, 4); Top.setRotationPoint(-4F, 10.53333F, -9F); Top.setTextureSize(64, 32); Top.mirror = true; setRotation(Top, 0F, 0F, 0F); WolfHead = new ModelRenderer(this, 0, 0); WolfHead.addBox(-3F, -3F, -2F, 8, 8, 0); WolfHead.setRotationPoint(-1F, 13.5F, -7F); WolfHead.setTextureSize(64, 32); WolfHead.mirror = true; setRotation(WolfHead, 0F, 0F, 0F); Ear1 = new ModelRenderer(this, 16, 14); Ear1.addBox(-3F, -5F, 0F, 2, 2, 1); Ear1.setRotationPoint(0F, 13.5F, -7F); Ear1.setTextureSize(64, 32); Ear1.mirror = true; setRotation(Ear1, 0F, 0F, 0F); Ear2 = new ModelRenderer(this, 16, 14); Ear2.addBox(1F, -5F, 0F, 2, 2, 1); Ear2.setRotationPoint(0F, 13.5F, -7F); Ear2.setTextureSize(64, 32); Ear2.mirror = true; setRotation(Ear2, 0F, 0F, 0F); Nose = new ModelRenderer(this, 0, 10); Nose.addBox(-2F, 0F, -5F, 4, 4, 4); Nose.setRotationPoint(0F, 13.5F, -8F); Nose.setTextureSize(64, 32); Nose.mirror = true; setRotation(Nose, 0F, 0F, 0F); Left = new ModelRenderer(this, 0, 0); Left.addBox(0F, 0F, 0F, 0, 8, 4); Left.setRotationPoint(-4F, 10.53333F, -9F); Left.setTextureSize(64, 32); Left.mirror = true; setRotation(Left, 0F, 0F, 0F); Corde_right = new ModelRenderer(this, 0, 0); Corde_right.addBox(0F, 0F, 0F, 0, 1, 4); Corde_right.setRotationPoint(-4F, 13.5F, -5F); Corde_right.setTextureSize(64, 32); Corde_right.mirror = true; setRotation(Corde_right, 0F, 0F, 0F); } public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) { super.render(entity, f, f1, f2, f3, f4, f5); setRotationAngles(f, f1, f2, f3, f4, f5, entity); Corde_back.render(f5); Corde_left.render(f5); Right.render(f5); Top.render(f5); WolfHead.render(f5); Ear1.render(f5); Ear2.render(f5); Nose.render(f5); Left.render(f5); Corde_right.render(f5); } private void setRotation(ModelRenderer model, float x, float y, float z) { model.rotateAngleX = x; model.rotateAngleY = y; model.rotateAngleZ = z; } public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity e) { super.setRotationAngles(f, f1, f2, f3, f4, f5, e); } } The item: package com.hamsterfurtif.masks.masques; import com.hamsterfurtif.masks.Masks; import com.hamsterfurtif.masks.lib.References; import net.minecraft.client.model.ModelBiped; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; public class ItemMaskLoup extends ItemMask{ public ItemMaskLoup() { super("wolf"); this.setHasShader(true); this.setUnlocalizedName("mask_wolf"); } public String getArmorTexture(ItemStack stack, Entity entity, int slot, String type) { if (stack.getItem() == Masks.mask_wolf) { return References.MODID + ":" + "mask_wolf"; } return null; } @SideOnly(Side.CLIENT) public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, int armorSlot) { ModelBiped armorModel = null; if (itemStack != null) { if (itemStack.getItem() == Masks.mask_wolf) { armorModel = Masks.proxy.getArmorModel(); } } if(armorModel != null){ armorModel.bipedHead.showModel = armorSlot == 0; armorModel.bipedHeadwear.showModel = armorSlot == 0; armorModel.bipedBody.showModel = armorSlot == 1 || armorSlot == 2; armorModel.bipedRightArm.showModel = armorSlot == 1; armorModel.bipedLeftArm.showModel = armorSlot == 1; armorModel.bipedRightLeg.showModel = armorSlot == 2 || armorSlot == 3; armorModel.bipedLeftLeg.showModel = armorSlot == 2 || armorSlot == 3; armorModel.isSneak = entityLiving.isSneaking(); armorModel.isRiding = entityLiving.isRiding(); armorModel.isChild = entityLiving.isChild(); armorModel.heldItemRight = entityLiving.getCurrentArmor(0) != null ? 1 :0; if(entityLiving instanceof EntityPlayer){ armorModel.aimedBow =((EntityPlayer)entityLiving).getItemInUseDuration() > 2; } return armorModel; } return null; } } The proxyclient class: package com.hamsterfurtif.masks.lib; import com.hamsterfurtif.masks.models.MasqueWolf; import net.minecraft.client.model.ModelBiped; public class ProxyClient extends ProxyCommon { private static final MasqueWolf masque_loup = new MasqueWolf(0.5F); public ModelBiped getArmorModel(){ return masque_loup; } } Note: the armor can only be a helmet. When I wear the armor, the item I'm holding and the armors I'm wearing stop rendering, and this shows up in the console: [19:07:54] [Client thread/ERROR]: Couldn't render entity java.lang.NullPointerException at com.hamsterfurtif.masks.masques.ItemMaskLoup.getArmorModel(ItemMaskLoup.java:35) ~[itemMaskLoup.class:?] at net.minecraftforge.client.ForgeHooksClient.getArmorModel(ForgeHooksClient.java:319) ~[ForgeHooksClient.class:?] at net.minecraft.client.renderer.entity.layers.LayerArmorBase.func_177182_a(LayerArmorBase.java:59) ~[LayerArmorBase.class:?] at net.minecraft.client.renderer.entity.layers.LayerArmorBase.doRenderLayer(LayerArmorBase.java:38) ~[LayerArmorBase.class:?] at net.minecraft.client.renderer.entity.RendererLivingEntity.func_177093_a(RendererLivingEntity.java:457) ~[RendererLivingEntity.class:?] at net.minecraft.client.renderer.entity.RendererLivingEntity.doRender(RendererLivingEntity.java:179) [RendererLivingEntity.class:?] at net.minecraft.client.renderer.entity.RenderPlayer.func_180596_a(RenderPlayer.java:67) [RenderPlayer.class:?] at net.minecraft.client.renderer.entity.RenderPlayer.doRender(RenderPlayer.java:242) [RenderPlayer.class:?] at net.minecraft.client.renderer.entity.RenderManager.doRenderEntity(RenderManager.java:370) [RenderManager.class:?] at net.minecraft.client.renderer.entity.RenderManager.renderEntityStatic(RenderManager.java:327) [RenderManager.class:?] at net.minecraft.client.renderer.entity.RenderManager.renderEntitySimple(RenderManager.java:294) [RenderManager.class:?] at net.minecraft.client.renderer.RenderGlobal.renderEntities(RenderGlobal.java:631) [RenderGlobal.class:?] at net.minecraft.client.renderer.EntityRenderer.renderWorldPass(EntityRenderer.java:1294) [EntityRenderer.class:?] at net.minecraft.client.renderer.EntityRenderer.renderWorld(EntityRenderer.java:1207) [EntityRenderer.class:?] at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1032) [EntityRenderer.class:?] at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1055) [Minecraft.class:?] at net.minecraft.client.Minecraft.run(Minecraft.java:345) [Minecraft.class:?] at net.minecraft.client.main.Main.main(SourceFile:120) [Main.class:?] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_31] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_31] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_31] at java.lang.reflect.Method.invoke(Method.java:483) ~[?:1.8.0_31] at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.11.jar:?] at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.11.jar:?] at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source) [start/:?] at GradleStart.main(Unknown Source) [start/:?] Thank you a lot for your help ! Quote
Choonster Posted October 21, 2015 Posted October 21, 2015 The exception was thrown on line 35 of ItemMaskLoup , but line 35 of the code you posted couldn't have thrown that exception. Can you upload the latest version of your code and the crash report to Gist and link them here? Quote Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.
Hamster_Furtif Posted October 21, 2015 Author Posted October 21, 2015 Here you have the ItemMaskLoup class: https://gist.github.com/Hamster-Furtif/7445a1ada0f7a7f3790a And the crash report: https://gist.github.com/Hamster-Furtif/8d81d491b354ac962139 I did not change anything. Maybe I'm using an old Forge version, I'll try to update when I have more time. Quote
Hamster_Furtif Posted October 21, 2015 Author Posted October 21, 2015 Thank you, it now renders ! Quote
Hamster_Furtif Posted October 23, 2015 Author Posted October 23, 2015 Well, I have another issue: Some texture render at weird places. Here is the new code for the model: package com.hamsterfurtif.masks.models; import net.minecraft.client.model.ModelBiped; import net.minecraft.client.model.ModelRenderer; import net.minecraft.entity.Entity; public class ModelMasqueWolf extends ModelBiped { //fields ModelRenderer Shape1; ModelRenderer Face; ModelRenderer LString; ModelRenderer LEar; ModelRenderer Top; ModelRenderer Nez; ModelRenderer Right; ModelRenderer Left; ModelRenderer REar; ModelRenderer RString; public ModelMasqueWolf(float f) { textureWidth = 64; textureHeight = 32; Shape1 = new ModelRenderer(this, 25, 9); Shape1.addBox(0F, 0F, 0F, 9, 1, 0); Shape1.setRotationPoint(-4.5F, -6F, 4.5F); Shape1.setTextureSize(64, 32); Shape1.mirror = true; setRotation(Shape1, 0F, 0F, 0F); Face = new ModelRenderer(this, 4, 6); Face.addBox(0F, 0F, 0F, 9, 9, 0); Face.setRotationPoint(-4.5F, -8.5F, -4.5F); Face.setTextureSize(64, 32); Face.mirror = true; setRotation(Face, 0F, 0F, 0F); LString = new ModelRenderer(this, 27, 13); LString.addBox(0F, 0F, 0F, 0, 1, 6); LString.setRotationPoint(4.5F, -6F, -1.5F); LString.setTextureSize(64, 32); LString.mirror = true; setRotation(LString, 0F, 0F, 0F); LEar = new ModelRenderer(this, 15, 0); LEar.addBox(0F, 0F, 0F, 2, 2, 1); LEar.setRotationPoint(2.5F, -10.5F, -2.5F); LEar.setTextureSize(64, 32); LEar.mirror = true; setRotation(LEar, 0F, 0F, 0F); Top = new ModelRenderer(this, 1, 3); Top.addBox(0F, 0F, 0F, 9, 0, 3); Top.setRotationPoint(-4.5F, -8.5F, -4.5F); Top.setTextureSize(64, 32); Top.mirror = true; setRotation(Top, 0F, 0F, 0F); Nez = new ModelRenderer(this, 0, 15); Nez.addBox(0F, 0F, 0F, 4, 4, 4); Nez.setRotationPoint(-2F, -4.7F, -8.5F); Nez.setTextureSize(64, 32); Nez.mirror = true; setRotation(Nez, 0F, 0F, 0F); Right = new ModelRenderer(this, 45, 3); Right.addBox(0F, 0F, 0F, 0, 9, 3); Right.setRotationPoint(4.5F, -8.5F, -4.5F); Right.setTextureSize(64, 32); Right.mirror = true; setRotation(Right, 0F, 0F, 0F); Left = new ModelRenderer(this, -2, 3); Left.addBox(0F, 0F, 0F, 0, 9, 3); Left.setRotationPoint(-4.5F, -8.5F, -4.5F); Left.setTextureSize(64, 32); Left.mirror = true; setRotation(Left, 0F, 0F, 0F); REar = new ModelRenderer(this, 15, 0); REar.addBox(0F, 0F, 0F, 2, 2, 1); REar.setRotationPoint(-4.5F, -10.5F, -2.5F); REar.setTextureSize(64, 32); REar.mirror = true; setRotation(REar, 0F, 0F, 0F); RString = new ModelRenderer(this, 21, 13); RString.addBox(0F, 0F, 0F, 0, 1, 6); RString.setRotationPoint(-4.5F, -6F, -1.5F); RString.setTextureSize(64, 32); RString.mirror = true; setRotation(RString, 0F, 0F, 0F); this.bipedHead.addChild(Shape1); this.bipedHead.addChild(LString); this.bipedHead.addChild(Right); this.bipedHead.addChild(Top); this.bipedHead.addChild(Face); this.bipedHead.addChild(LEar); this.bipedHead.addChild(REar); this.bipedHead.addChild(Nez); this.bipedHead.addChild(Left); this.bipedHead.addChild(RString); } public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) { super.render(entity, f, f1, f2, f3, f4, f5); setRotationAngles(f, f1, f2, f3, f4, f5, entity); } private void setRotation(ModelRenderer model, float x, float y, float z) { model.rotateAngleX = x; model.rotateAngleY = y; model.rotateAngleZ = z; } public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity entity) { super.setRotationAngles(f, f1, f2, f3, f4, f5, entity); } } Quote
Hamster_Furtif Posted October 25, 2015 Author Posted October 25, 2015 So, I made a few test, and when you remove this part: this.bipedHead.addChild(Shape1); this.bipedHead.addChild(LString); this.bipedHead.addChild(Right); this.bipedHead.addChild(Top); this.bipedHead.addChild(Face); this.bipedHead.addChild(LEar); this.bipedHead.addChild(REar); this.bipedHead.addChild(Nez); this.bipedHead.addChild(Left); this.bipedHead.addChild(RString); The "right" texture stop rendering, the bugged textures only remains. It looks like this: Quote
coolAlias Posted October 25, 2015 Posted October 25, 2015 That's an issue with your model rotation points and values - if you made your model in Techne, Techne doesn't support child parts, so adding all of the parts as children of the head makes everything out of whack like you are seeing. Easiest solution is to not add them as children, but just render each part separately. If you have somewhat complicated animations, however, you'll want to instead add any parts involved in that animation as children of the appropriate part, and then recalculate the rotations points/values based on the parent part (basically you just subtract the parent values from the child values to get the new child values). Quote http://i.imgur.com/NdrFdld.png[/img]
Hamster_Furtif Posted October 25, 2015 Author Posted October 25, 2015 So the tutorial I followed is not valid anymore ? Damn. How am I supposed to render each part separately then ? Do I have to create a renderer for each part ? It's a helmet, so there are no animation (except from the head movements). Quote
coolAlias Posted October 25, 2015 Posted October 25, 2015 You know how in your Model class there are a bunch of ModelBase fields? Each of those is a part of your model. When your model renders, you call part1.render(args), part2.render(args), etc. for every part that is not a child of another part. However, if your helmet has lots of individual parts, even something as simple as head rotation will cause it to become mangled beyond recognition if each part is not the child of a previous part of the helmet. You just need one parent part on the helmet, and every other part will be relative to that piece; when that piece renders, you can set the rotation to the head rotation and the rest of the pieces will follow. Quote http://i.imgur.com/NdrFdld.png[/img]
Draco18s Posted October 25, 2015 Posted October 25, 2015 If/when I do any more animated models, my process is going to be to design it in MCAnimator and Techne. I'll use Techne's exported code, but use the parent/child relationship from MCAnimator using the rotation values I figured out in there. (MCAnimator's exported code uses their custom animation system, which I had concurrent modification errors using). Quote Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable. If you think this is the case, JUST REPORT ME. Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice. Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked. DO NOT PM ME WITH PROBLEMS. No help will be given.
Hamster_Furtif Posted October 25, 2015 Author Posted October 25, 2015 Ok, I found out how to make all the parts dependant of one part, which is dependant of the head, but I still have the same problem: a weird shape in the inside of a correct rendered helmet. Quote
Hamster_Furtif Posted October 26, 2015 Author Posted October 26, 2015 So, a friend noticed that the weird part in the inside renders like a regular helmet, and if I replace my textures with some Iron Helmet textures... Tadaaa ! So, I guess my helmet is rendered once like a regular armour, and once like I want it to be rendered. And I don't think it comes from the rotation points and all that stuff. There should be a way to tell Minecraft not to render it like a regular helmet ? Quote
coolAlias Posted October 26, 2015 Posted October 26, 2015 Could be your texture is not laid out in the same format as your model expects. Does your helmet use the same model as the vanilla helmet, or is it custom? Because that's pretty weird if it renders the regular helmet texture perfectly fine, but it's a different model. Does your entity renderer extend RenderBiped? And is your mob actually wearing a helmet, as in the helmet inventory slot has a helmet item in it? Because RenderBiped will render any equipped helm automatically, though I don't recall whether how/where it fetches the model. You should take a look at that class and see, if that's the case. Quote http://i.imgur.com/NdrFdld.png[/img]
Hamster_Furtif Posted October 26, 2015 Author Posted October 26, 2015 Here is a default armour texturemap: And here is mine: There are not custom entitys, I used zombies and myself, so yes, it's a ModelBiped. I made the textures based on the texturemap Techne gave me, and it worked just fine when I loaded them into Techne. Now, the problem is that Minecraft renders the armor with the regular model, and then renders it with my custom model, so two helmet appear on the player/entity's head, the regular one, that looks broken because the textures don't match, and the custom one, that looks just fine. Here is the armor class: package com.hamsterfurtif.masks.masques; import com.hamsterfurtif.masks.Masks; import net.minecraft.client.model.ModelBiped; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; public class ItemMaskLoup extends ItemMask{ public ItemMaskLoup() { super("wolf"); this.setHasShader(true); this.setUnlocalizedName("mask_wolf"); this.setHasSpecialRender(true); } @Override @SideOnly(Side.CLIENT) public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, int armorSlot) { ModelBiped armorModel = null; if (itemStack != null) { if (itemStack.getItem() == Masks.mask_wolf) { armorModel = Masks.proxy.getArmorModel(); } } if(armorModel != null){ armorModel.bipedHead.showModel = armorSlot == 0; armorModel.bipedHeadwear.showModel = armorSlot == 0; armorModel.bipedBody.showModel = armorSlot == 1 || armorSlot == 2; armorModel.bipedRightArm.showModel = armorSlot == 1; armorModel.bipedLeftArm.showModel = armorSlot == 1; armorModel.bipedRightLeg.showModel = armorSlot == 2 || armorSlot == 3; armorModel.bipedLeftLeg.showModel = armorSlot == 2 || armorSlot == 3; armorModel.isSneak = entityLiving.isSneaking(); armorModel.isRiding = entityLiving.isRiding(); armorModel.isChild = entityLiving.isChild(); armorModel.heldItemRight = entityLiving.getCurrentArmor(0) != null ? 1 :0; if(entityLiving instanceof EntityPlayer){ armorModel.aimedBow =((EntityPlayer)entityLiving).getItemInUseDuration() > 2; } return armorModel; } return null; } } Could the problem come from the getArmorModel() methods that would be called twice ? Quote
Hamster_Furtif Posted October 26, 2015 Author Posted October 26, 2015 I solved the problem by changing this: super(f,0.0f,64,32); Into this: super(f,0.0f,0,0); But, when the helmet is weared by a player, it renders very glitchy.It's like two textures rendering on top of each other, but one of these textures is transparent. And I noticed that if I delete the line with the super, the bug comes back. Quote
coolAlias Posted October 27, 2015 Posted October 27, 2015 Make sure your texture is exactly the same size as the vanilla texture (64x64, I believe), even if you don't use the same space. If it's 64x32 or some other size, things can get really funky like you are seeing, so that may be your issue. Quote http://i.imgur.com/NdrFdld.png[/img]
Hamster_Furtif Posted October 27, 2015 Author Posted October 27, 2015 Vanilla textures are 64x32. Quote
coolAlias Posted October 27, 2015 Posted October 27, 2015 Vanilla textures are 64x32. Weird - I had a 64x32 texture for a custom entity using the vanilla ModelBiped and it was all sorts of f-ed up looking, but as soon as I resized it to 64x64 (just empty space for the bottom 32 pixels), it mapped perfectly to the model. Quote http://i.imgur.com/NdrFdld.png[/img]
Hamster_Furtif Posted October 27, 2015 Author Posted October 27, 2015 This is an armor, not an entity, so it's 64x32. I made a few test but the textures are very fine. Actually, the problem comes from the super, that stills renders even though it should not. I just need a way to say: <<Nope, I already have my model here, don't render the regular model too>> but I can't find it. Quote
Hamster_Furtif Posted October 28, 2015 Author Posted October 28, 2015 Solved, my model was just too small, and there was a conflict between the model and the player's textures. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.