From f8e19cc17aeacec6c156c98ec1f55d470bf481df Mon Sep 17 00:00:00 2001 From: Sollace Date: Sat, 27 Feb 2021 22:05:57 +0200 Subject: [PATCH] Separate wing and amulet rendering and give the wings of icarus their own texture --- .../unicopia/client/URenderers.java | 2 + .../client/render/AmuletFeatureRenderer.java | 105 +------------- .../client/render/WingsFeatureRenderer.java | 136 ++++++++++++++++++ .../textures/models/armor/pegasus_amulet.png | Bin 4460 -> 4450 bytes .../unicopia/textures/models/wings/icarus.png | Bin 0 -> 983 bytes .../textures/models/wings/pegasus.png | Bin 0 -> 1114 bytes 6 files changed, 145 insertions(+), 98 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/client/render/WingsFeatureRenderer.java create mode 100644 src/main/resources/assets/unicopia/textures/models/wings/icarus.png create mode 100644 src/main/resources/assets/unicopia/textures/models/wings/pegasus.png diff --git a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java index a28f0f40..df5cb893 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java +++ b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java @@ -15,6 +15,7 @@ import com.minelittlepony.unicopia.client.render.AccessoryFeatureRenderer; import com.minelittlepony.unicopia.client.render.AmuletFeatureRenderer; import com.minelittlepony.unicopia.client.render.BraceletFeatureRenderer; import com.minelittlepony.unicopia.client.render.FloatingArtefactEntityRenderer; +import com.minelittlepony.unicopia.client.render.WingsFeatureRenderer; import com.minelittlepony.unicopia.item.ChameleonItem; import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.particle.UParticles; @@ -51,6 +52,7 @@ public interface URenderers { AccessoryFeatureRenderer.register(BraceletFeatureRenderer::new); AccessoryFeatureRenderer.register(AmuletFeatureRenderer::new); + AccessoryFeatureRenderer.register(WingsFeatureRenderer::new); EntityRendererRegistry.INSTANCE.register(UEntities.THROWN_ITEM, (manager, context) -> new FlyingItemEntityRenderer<>(manager, context.getItemRenderer())); EntityRendererRegistry.INSTANCE.register(UEntities.FLOATING_ARTEFACT, FloatingArtefactEntityRenderer::new); diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/AmuletFeatureRenderer.java b/src/main/java/com/minelittlepony/unicopia/client/render/AmuletFeatureRenderer.java index bdf0cd3d..1d058bee 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/AmuletFeatureRenderer.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/AmuletFeatureRenderer.java @@ -3,10 +3,7 @@ package com.minelittlepony.unicopia.client.render; import java.util.HashMap; import java.util.Map; -import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.item.AmuletItem; -import com.minelittlepony.unicopia.item.UItems; - import net.minecraft.client.model.Model; import net.minecraft.client.model.ModelPart; import net.minecraft.client.render.OverlayTexture; @@ -19,15 +16,13 @@ import net.minecraft.client.render.item.ItemRenderer; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; public class AmuletFeatureRenderer implements AccessoryFeatureRenderer.Feature { - private final BraceletModel model = new BraceletModel(0.3F); + private final AmuletModel model = new AmuletModel(0.3F); private final Map textures = new HashMap<>(); @@ -41,121 +36,35 @@ public class AmuletFeatureRenderer implements AccessoryF public void render(MatrixStack matrices, VertexConsumerProvider renderContext, int lightUv, E entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) { ItemStack stack = entity.getEquippedStack(EquipmentSlot.CHEST); - Item item = stack.getItem(); - boolean amulet = item instanceof AmuletItem; - boolean wings = - (amulet && ((AmuletItem)item).isApplicable(stack)) - || (entity instanceof PlayerEntity && Pony.of((PlayerEntity)entity).getSpecies().canInteractWithClouds()); - - if (wings || amulet) { - Identifier texture = textures.computeIfAbsent(Registry.ITEM.getId(amulet ? item : UItems.PEGASUS_AMULET), id -> new Identifier(id.getNamespace(), "textures/models/armor/" + id.getPath() + ".png")); + if (stack.getItem() instanceof AmuletItem) { + Identifier texture = textures.computeIfAbsent(Registry.ITEM.getId(stack.getItem()), id -> new Identifier(id.getNamespace(), "textures/models/armor/" + id.getPath() + ".png")); VertexConsumer consumer = ItemRenderer.getArmorGlintConsumer(renderContext, RenderLayer.getArmorCutoutNoCull(texture), false, false); - model.setVisible(amulet, wings); model.setAngles(entity, context.getModel()); model.render(matrices, consumer, lightUv, OverlayTexture.DEFAULT_UV, 1, 1, 1, 1); } } - static class BraceletModel extends Model { + static class AmuletModel extends Model { private final ModelPart torso; - private final ModelPart amulet; - private final Wing[] wings; - - public BraceletModel(float dilate) { + public AmuletModel(float dilate) { super(RenderLayer::getEntityTranslucent); torso = new ModelPart(this, 0, 0); - amulet = new ModelPart(this, 0, 0); - amulet.addCuboid(-4, 0, -2, 8, 12, 4, dilate); - amulet.setPivot(0, 0, 0); - torso.addChild(amulet); - wings = new Wing[] { - new Wing(this, torso, -1), - new Wing(this, torso, 1) - }; - } - - public void setVisible(boolean amulet, boolean wings) { - this.amulet.visible = amulet; - for (Wing wing : this.wings) { - wing.base.visible = wings; - } + torso.addCuboid(-4, 0, -2, 8, 12, 4, dilate); + torso.setPivot(0, 0, 0); } public void setAngles(LivingEntity entity, BipedEntityModel biped) { torso.copyPositionAndRotation(biped.torso); - for (Wing wing : wings) { - wing.setAngles(entity); - } } @Override public void render(MatrixStack matrices, VertexConsumer vertexConsumer, int i, int j, float f, float g, float h, float k) { torso.render(matrices, vertexConsumer, i, j, f, g, h, k); } - - static class Wing { - ModelPart base; - - ModelPart[] feathers; - - int k; - - Wing(Model model, ModelPart torso, int k) { - this.k = k; - base = new ModelPart(model, 0, 16); - - base.setPivot(k * 2, 2, 2 + k * 0.5F); - base.addCuboid(0, 0, 0, 2, 10, 2); - - feathers = new ModelPart[8]; - - for (int i = 0; i < feathers.length; i++) { - int texX = (i % 2) * 8; - - ModelPart feather = new ModelPart(model, 24 + texX, 0); - feather.setPivot(0, 9, 0); - - int featherLength = 21 - i * 2; - - feather.addCuboid(-k * (i % 2) / 90F, 0, 0, 2, featherLength, 2); - - base.addChild(feather); - feathers[i] = feather; - } - - torso.addChild(base); - } - - void setAngles(LivingEntity entity) { - if (entity instanceof PlayerEntity) { - Pony pony = Pony.of((PlayerEntity)entity); - - float spreadAmount = pony.getMotion().getWingAngle(); - - base.pitch = 1.5F + 0.8F - spreadAmount / 9F; - base.yaw = k * (0.8F + spreadAmount / 3F); - - spreadAmount /= 7F; - - final float ratio = 4F; - - for (int i = 0; i < feathers.length; i++) { - - float spread = i/ratio + 1.5F; - spread -= spreadAmount * ratio; - spread += spreadAmount * i / ratio; - - feathers[i].pitch = -spread; - feathers[i].yaw = k * 0.3F; - } - - } - } - } } } diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/WingsFeatureRenderer.java b/src/main/java/com/minelittlepony/unicopia/client/render/WingsFeatureRenderer.java new file mode 100644 index 00000000..c749f5da --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/client/render/WingsFeatureRenderer.java @@ -0,0 +1,136 @@ +package com.minelittlepony.unicopia.client.render; + +import com.minelittlepony.unicopia.entity.player.Pony; +import com.minelittlepony.unicopia.item.UItems; + +import net.minecraft.client.model.Model; +import net.minecraft.client.model.ModelPart; +import net.minecraft.client.render.OverlayTexture; +import net.minecraft.client.render.RenderLayer; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.entity.feature.FeatureRendererContext; +import net.minecraft.client.render.entity.model.BipedEntityModel; +import net.minecraft.client.render.item.ItemRenderer; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.Identifier; + +public class WingsFeatureRenderer implements AccessoryFeatureRenderer.Feature { + + private static final Identifier ICARUS_WINGS = new Identifier("unicopia", "textures/models/wings/icarus.png"); + private static final Identifier PEGASUS_WINGS = new Identifier("unicopia", "textures/models/wings/pegasus.png"); + + private final WingsModel model = new WingsModel(); + + private final FeatureRendererContext> context; + + public WingsFeatureRenderer(FeatureRendererContext> context) { + this.context = context; + } + + @Override + public void render(MatrixStack matrices, VertexConsumerProvider renderContext, int lightUv, E entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) { + + boolean pegasus = (entity instanceof PlayerEntity && Pony.of((PlayerEntity)entity).getSpecies().canInteractWithClouds()); + boolean icarus = UItems.PEGASUS_AMULET.isApplicable(entity); + + if (icarus || pegasus) { + Identifier texture = pegasus ? PEGASUS_WINGS : ICARUS_WINGS; + VertexConsumer consumer = ItemRenderer.getArmorGlintConsumer(renderContext, RenderLayer.getEntityTranslucent(texture), false, false); + + model.setAngles(entity, context.getModel()); + model.render(matrices, consumer, lightUv, OverlayTexture.DEFAULT_UV, 1, 1, 1, 1); + } + } + + static class WingsModel extends Model { + + private final ModelPart root; + private final Wing[] wings; + + public WingsModel() { + super(RenderLayer::getEntityTranslucent); + this.textureHeight = 23; + this.textureWidth = 24; + root = new ModelPart(this, 0, 0); + wings = new Wing[] { + new Wing(this, root, -1), + new Wing(this, root, 1) + }; + } + + public void setAngles(LivingEntity entity, BipedEntityModel biped) { + root.copyPositionAndRotation(biped.torso); + for (Wing wing : wings) { + wing.setAngles(entity); + } + } + + @Override + public void render(MatrixStack matrices, VertexConsumer vertexConsumer, int i, int j, float f, float g, float h, float k) { + root.render(matrices, vertexConsumer, i, j, f, g, h, k); + } + + static class Wing { + ModelPart base; + + ModelPart[] feathers; + + int k; + + Wing(Model model, ModelPart torso, int k) { + this.k = k; + base = new ModelPart(model, 0, 0); + + base.setPivot(k * 2, 2, 2 + k * 0.5F); + base.addCuboid(0, 0, 0, 2, 10, 2); + + feathers = new ModelPart[8]; + + for (int i = 0; i < feathers.length; i++) { + int texX = (i % 2) * 8; + + ModelPart feather = new ModelPart(model, 8 + texX, 0); + feather.setPivot(0, 9, 0); + + int featherLength = 21 - i * 2; + + feather.addCuboid(-k * (i % 2) / 90F, 0, 0, 2, featherLength, 2); + + base.addChild(feather); + feathers[i] = feather; + } + + torso.addChild(base); + } + + void setAngles(LivingEntity entity) { + if (entity instanceof PlayerEntity) { + Pony pony = Pony.of((PlayerEntity)entity); + + float spreadAmount = pony.getMotion().getWingAngle(); + + base.pitch = 1.5F + 0.8F - spreadAmount / 9F; + base.yaw = k * (0.8F + spreadAmount / 3F); + + spreadAmount /= 7F; + + final float ratio = 4F; + + for (int i = 0; i < feathers.length; i++) { + + float spread = i/ratio + 1.5F; + spread -= spreadAmount * ratio; + spread += spreadAmount * i / ratio; + + feathers[i].pitch = -spread; + feathers[i].yaw = k * 0.3F; + } + + } + } + } + } +} diff --git a/src/main/resources/assets/unicopia/textures/models/armor/pegasus_amulet.png b/src/main/resources/assets/unicopia/textures/models/armor/pegasus_amulet.png index 39f204338479ea4da1c8819fbe9565aae0c02515..78aa925cc9b66cc29315657e8853b35b48da3093 100644 GIT binary patch delta 4212 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�mJ*q^k^KO1Y#e7`G9(LQ zZaoPULHB_|@3^rB?eu@Ub?Y^!f?enOPq_;?Po;P7y6EuDF&RuJ;RMvA1P9TSV-dy> zX=7v+#RcVfskmdKMWqrc0lYcZQh#CXp)e+c`MTjW-2p*}8w-cIk{?4O;-Vujo+`$o z5LP2PLrxW!0)FU&-|e1`J94CfP9E$oYk8ULa5h9c;*gkNi08;$zcYxG-hFmKd0zKT+fctthJlOLssNx>V3Bpa{#OOd9%a8D$W>SIP`= z6KGzMjbIf7gNvRp-n8kV5r0e&53>rhz-Fi%PB1SJrBM}9a8wH{)fk_1z3KC0xYCt9 zx`H)fx4#Z;9^!?=oZ@q2@XBKS`7uLmuG7r7-2rM4VuH9eiZ_l&fea2qT^BtBrwjtR z8cCoOL1$rGo`NK3GK%x$;uwP=9t_Vm^_H&a0+RYg5@^K@Lam-1{ePMlAHhj)881$m zj}Rv%ur;Hmz~mj9Bv@6pa{KGSVH*S&j9MUiho-Km)uWJ-Q6n@_+|n7q z>_CcORt?< zGeQiggO(h@z*V7@*nd^G^g2NSL^5tN&UV`!AbLt|%mp^ZaIq2-=uw$hNHL{qbJWoF}hRMb{_VNHZk&IoYp9e+SYnP>!q&0lm zyhbJ`$i~qWE*?b6^#uwW4|6zA;H`In=!G296A|TchMJA>J}h&=il+c;@#M#aV7+^$ zU~JNP0&jm3=ncymZ35z%#(s**tzWgmwlb-*9~+Djx9R_vM`l>A&J%e15dbg=sIMdx zt&qjh2>7`Ys%21oudc~j(AhJ7xrdD)yYmFzdIz9Jrd_372`39gU{jUBRb)!6X2jGl z+{gxE4O<#PjIf?3@N8#0+u6=`wzHk>Y-c;$+0J&hvz_g>*na_!6)0904TT*50000< KMNUMnLSTX=J;x9L delta 4268 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�#=>E) zr;4#Cgw=@7kWqzAuo)_c6U+-lX;g(29Mu9#HOA*$Z~8nL zu5@LOu3$~r?XN?dhj`&Ir}!Khys}t-e#{V?>ooIicYqp%m>_PA;*H}`AcMnD*F_J( zDT9EnMiMAR&{^1)ryvQMjN&}GIL2Uz2g9>Xy`?LuzW`r0}2Q4{*fvZA)E3vC?>2-nvh-BPkob9$dK=hQ_mB*wmZNS6tkd31$Ts(-B>kAY%9_DbKz+3MC(F-}ICnCz@3^g0$eOTs#6;A=y;>nK- z!Fu;h!Punp1m6B6&>NOB+62Tijr|mrTfb_BZDmqrKQ6I~z@{pLtH_jC z&4{UAxRDLS8n!fo7-2n6;MvZ0wzHk>Y-c;$+0J&hvz_g1XFJ<%vHt diff --git a/src/main/resources/assets/unicopia/textures/models/wings/icarus.png b/src/main/resources/assets/unicopia/textures/models/wings/icarus.png new file mode 100644 index 0000000000000000000000000000000000000000..0ee3f958536dce907c51d7e0787489a0084ba35b GIT binary patch literal 983 zcmV;|11S87P)MIB!aD^}|4B z;2eY-8KwfP1V8I++(T&LYz^LnUqJ-81b3pnl)(9HJdP?qB?t+c5_|&zxVV9)hF6zz zezk+s4*q@#wug%=*}P$DJw+K|z~OG74jYHf8(=We+ena@Y(Clt%4$PnE41G#zX%1Z5huzv&fV^M_z^ zBxT?|_!B`DJ(N4x8L-Zo)_|9TR6uN@_i$6gwuIp$h$lb~wBSF?6*LX_)7*nW&mjq# zlL$8@*bKIUtz{T%a2=QvBuxW{Av5q4QUHG|U(QU zPCt;nb9H7=0&Ae1~e=J)LE6eHEg$n&@Ya@|Jt+ez+vnUC0~6v-Q5jTYPfU9X$qp@ zewJRG(>tiy?Ni|2dlh&RDJ4=g{4m{B5VB)eE7NPQfGO!-sCKGo3Ep+ux7T|2KYRne z@Px{kX9Hg_+02jMLSY5;vuKzzd^Ew3$HQim^|6w(Mfo0S%6jnLK>`lZSeFos86OLZ zFf*@U3`>PaSngQ0XlIb)5bo(CE82w;@QJR4JzxpUX7&!^e#TESg5y7A#ZH;~4ys4@ znV~_)1TL0Pk1!<1VS?IVE+MR7m2pi;RW9SfoYWq3!>xuY9`AIIoKu0bJxo?m&4%v^ zh6!Q?(>3g?LLVJ8am|EzaCu(kdz&QaLV$9WZ@5{-{0C4d^0sesCr1DP002ovPDHLk FV1hzy!e0OY literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/unicopia/textures/models/wings/pegasus.png b/src/main/resources/assets/unicopia/textures/models/wings/pegasus.png new file mode 100644 index 0000000000000000000000000000000000000000..f1ae57a0a2d72e057601064f9c3aa2b0698b55c5 GIT binary patch literal 1114 zcmV-g1f~0lP)Y{Iwn=U)-oK@4_>pZ=cj*#G)# z;w8cO2)w|Lzr5`E-wqkW4Adc4=lg2Uz$@?!iT_ruu-?F)VYmOB%h#U~Su#U$A{>&? zYTydu!gvpEKo{@=*`Nb^gK2>`35E>0zya_C=>`R82AUO2V6RSc=pN)Mj1Fan(ZMoI z1?qNPUKC!>@bV6Phb#~VYlG}pTS-U%z^IkY6hF&$v`rQzJ9`C#6im(ZKJJZ!k1qfV>sHnG&v7gWqOo369%(2n*(%QAvT(88hrX zlgG}oI7mW7kP);SwL`R^-{IVXq;Pn~9F73YId(@E2$V*k#CP|}|I(j+o1+g#GG(hy zHn_ck*x>yjyy-z63uEf^5bDtp%~)~<7xZHR%3^2(>yA2%pTPbE&nBz{Wd*FWcc*nB z6qe!)J(%YH@c=IyXoK28rbO8Vy(MlXXf2U?A`OW!K#d^{)WaDT;kfhh0C`XjFC-FT zox=pbJ6)kfr*%P_kQ1n7PAc-4xStNox7PJnpJu+t0|5T;moMNnyqu)S)Lxm(!VyOI zMsY=p(rd=cNw0?Hk;Nxo`Zpiv!7qODIf+ih)q^@g-><*1JOt|oO_gbIq(drjl!88W za&hGA&*1;@;Ag-4WrP%J7gSF~2E3h=veMbvcVV7k+urlIEP(LOm*A86q@@M<<8Q#o zh#R*AHGyt|3_;97twgk78HB9{0K=rzE-YhbY9Gi2lmTiKa%$N90#66q@T~F2;487w8hFj*P zLl4jgC-2T-ABfl$&bYRKpU_+=;pA1=8`N?^{w#v)#n;22MUY0o2I^tBf(qCRcnQYo gnu)VH74T601v^DzWKGpzpa1{>07*qoM6N<$g3@XVJ^%m! literal 0 HcmV?d00001