Jump to content

[SOLVED][1.8.0-9]Weird rendering bug on some clients


Zethariel

Recommended Posts

Hello there,

 

I am experiencing a weird rendering bug for a model. Unfortunately, it only happened thus far on 2/6 computers I tested it on. I checked and I think I can safely rule out other mods (such as optifine) or the java version being the issue. That being said, I have absolutely no clue what could be causing it. In-game the models render the same way and correctly, which is even more bizzare to me

 

How it looks on afflicted PCs:

PonySkins-Error.jpg

 

How it looks on mine and the rest:

PonyRaces-OK.jpg

 

Upfront, sorry about the mess in the code - still haven't gotten down to refactoring much

Relevant classes:

Abstract GuiPonyBaseManager class, contains drawPony method that does the pony drawing. It is usually called in drawGuiProper (which is called by it's child, GuiPonySkinManager)

package com.gmail.zethariel.gui;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;

import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.Project;

import com.gmail.zethariel.PonySkinInfo;
import com.gmail.zethariel.PonySkinManager;
import com.gmail.zethariel.PonySkinInfo.PonySkinOption;
import com.gmail.zethariel.client.model.ModelPonyPlayer;
import com.gmail.zethariel.utils.PonyHelper;
import com.gmail.zethariel.utils.PonyMath;
import com.gmail.zethariel.utils.GuiPonyHelper.GuiPonyState;
import com.mojang.util.UUIDTypeAdapter;

abstract class GuiPonyBaseManager extends GuiScreen implements IGuiScreenStateable {
  
  protected GuiScreen parent;
  private DynamicTexture viewportTexture;
  private ResourceLocation viewportTextureResource;
  private static final ResourceLocation minecraftTitleTextures = new ResourceLocation("textures/gui/title/minecraft.png");
  private static final ResourceLocation[] titlePanoramaPaths = new ResourceLocation[] {new ResourceLocation("textures/gui/title/background/panorama_0.png"), new ResourceLocation("textures/gui/title/background/panorama_1.png"), new ResourceLocation("textures/gui/title/background/panorama_2.png"), new ResourceLocation("textures/gui/title/background/panorama_3.png"), new ResourceLocation("textures/gui/title/background/panorama_4.png"), new ResourceLocation("textures/gui/title/background/panorama_5.png")};
  private float panoramaTimer;
  private double updateCounter;
  
  GuiPonyState guiState = GuiPonyState.IDLE;
  String guiStateMessage;
  //special handle to a dissapearing button
  GuiButton acceptButton;
  
  int lastMouseX, lastMouseY;
  float rotationX;
  float rotationY;
  
  public ModelPonyPlayer pony = new ModelPonyPlayer(0);
  public PonySkinInfo localPonyInfo, remotePonyInfo;
  
  public UUID playerID;

  public GuiPonyBaseManager(GuiScreen gui) {
    playerID = UUIDTypeAdapter.fromString(Minecraft.getMinecraft().getSession().getPlayerID());
    this.parent = gui;
  }
  
  @Override
  public void initGui() {
    super.initGui();
    
    this.viewportTexture = new DynamicTexture(256, 256);
    this.viewportTextureResource = this.mc.getTextureManager().getDynamicTextureLocation("background", this.viewportTexture);
    
    this.buttonList.add(new GuiPonyButton(13035, this.width-20, 50, 20, 20, ""));//back button
    
    acceptButton = new GuiButton(12034, this.width/2-25, this.height/2, 50, 20, "Sorry!");
    acceptButton.enabled = false;
    acceptButton.visible = false;
    this.buttonList.add(acceptButton);//accept button for the failure
    
  }
  
  public void updateScreen()
  {
      ++this.panoramaTimer;
  }
  
  @Override
  public void drawScreen(int mouseX, int mouseY, float partialTicks) {
    GlStateManager.disableAlpha();
    this.renderSkybox(mouseX, mouseY, partialTicks);
    
    GlStateManager.enableAlpha();
    Tessellator tessellator = Tessellator.getInstance();
    WorldRenderer worldrenderer = tessellator.getWorldRenderer();
    short short1 = 274;
    int k = this.width / 2 - short1 / 2;
    byte b0 = 30;
    this.drawGradientRect(0, 0, this.width, this.height, -2130706433, 16777215);
    this.drawGradientRect(0, 0, this.width, this.height, 0, Integer.MIN_VALUE);
    GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);

    GlStateManager.pushMatrix();
    GlStateManager.translate((float)(this.width / 2 + 90), 70.0F, 0.0F);
    GlStateManager.rotate(-20.0F, 0.0F, 0.0F, 1.0F);

    GlStateManager.popMatrix();
    drawGuiProper();
    super.drawScreen(mouseX, mouseY, partialTicks);
    drawGuiState(mouseX, mouseY);
  }
  
  public void drawGuiState(int mouseX, int mouseY) {
    switch (guiState){
      case ERROR:
        GlStateManager.pushMatrix();
        GlStateManager.translate(0, 0, 200);
        this.drawGradientRect(0, 0, this.width, this.height, 0xC0000000, 0xC0000000);
        this.drawCenteredString(this.fontRendererObj, "An error occured!", this.width / 2, 90, 16777215);
        this.drawCenteredString(this.fontRendererObj, guiStateMessage, this.width / 2, 110, 16777215);
        acceptButton.drawButton(this.mc, mouseX, mouseY);
        GlStateManager.popMatrix();
        break;
      case WORKING:
        GlStateManager.pushMatrix();
        GlStateManager.translate(0, 0, 200);
        this.drawGradientRect(0, 0, this.width, this.height, 0xC0000000, 0xC0000000);
        this.drawCenteredString(this.fontRendererObj, guiStateMessage, this.width / 2, 100, 16777215);
        GlStateManager.popMatrix();
        break;
    }
  }
    
  
  protected abstract void drawGuiProper();
    

  protected void drawPony(int ponyX, int ponyY, float scale, PonySkinInfo info) {
   
    GlStateManager.pushMatrix();
    GlStateManager.translate(ponyX, ponyY, 10);
    GlStateManager.scale(scale, scale, scale);
    this.drawGradientRect(-25,-25,25,50, 1996488704, 1996488704);
    GlStateManager.translate(0, 0, 30 * scale);
    RenderHelper.enableStandardItemLighting();
    //GlStateManager.translate(0, 10, 0);
    GlStateManager.rotate(rotationX+180, 0, 1, 0);
    GlStateManager.rotate(rotationY+180, 1, 0, 0);
    
    mc.getTextureManager().bindTexture(info.resourceLocation);
    //pull him inside out? Why? Iduuno
    GlStateManager.scale(-1, -1, -1);
    GL11.glDisable(GL11.GL_CULL_FACE);
    
    pony.setPonyAttributes(info);
    pony.render(null,  0, 0, 0, 0, 0, 1);
    
    GL11.glEnable(GL11.GL_CULL_FACE);

    GlStateManager.popMatrix();
    RenderHelper.disableStandardItemLighting();
    GlStateManager.disableRescaleNormal();

}

  /**
   * Draws the main menu panorama
   */
  private void drawPanorama(int p_73970_1_, int p_73970_2_, float p_73970_3_)
  {
    Tessellator tessellator = Tessellator.getInstance();
    WorldRenderer worldrenderer = tessellator.getWorldRenderer();
    GlStateManager.matrixMode(5889);
    GlStateManager.pushMatrix();
    GlStateManager.loadIdentity();
    Project.gluPerspective(120.0F, 1.0F, 0.05F, 10.0F);
    GlStateManager.matrixMode(5888);
    GlStateManager.pushMatrix();
    GlStateManager.loadIdentity();
    GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
    GlStateManager.rotate(180.0F, 1.0F, 0.0F, 0.0F);
    GlStateManager.rotate(90.0F, 0.0F, 0.0F, 1.0F);
    GlStateManager.enableBlend();
    GlStateManager.disableAlpha();
    GlStateManager.disableCull();
    GlStateManager.depthMask(false);
    GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
    int i = 8;

    for (int j = 0; j < i * i; ++j)
    {
        GlStateManager.pushMatrix();
        float f = ((float)(j % i) / (float)i - 0.5F) / 64.0F;
        float f1 = ((float)(j / i) / (float)i - 0.5F) / 64.0F;
        float f2 = 0.0F;
        GlStateManager.translate(f, f1, f2);
        GlStateManager.rotate(MathHelper.sin(((float)this.panoramaTimer + p_73970_3_) / 400.0F) * 25.0F + 20.0F, 1.0F, 0.0F, 0.0F);
        GlStateManager.rotate(-((float)this.panoramaTimer + p_73970_3_) * 0.1F, 0.0F, 1.0F, 0.0F);

        for (int k = 0; k < 6; ++k)
        {
            GlStateManager.pushMatrix();

            if (k == 1)
            {
                GlStateManager.rotate(90.0F, 0.0F, 1.0F, 0.0F);
            }

            if (k == 2)
            {
                GlStateManager.rotate(180.0F, 0.0F, 1.0F, 0.0F);
            }

            if (k == 3)
            {
                GlStateManager.rotate(-90.0F, 0.0F, 1.0F, 0.0F);
            }

            if (k == 4)
            {
                GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F);
            }

            if (k == 5)
            {
                GlStateManager.rotate(-90.0F, 1.0F, 0.0F, 0.0F);
            }

            this.mc.getTextureManager().bindTexture(titlePanoramaPaths[k]);
            worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
            int l = 255 / (j + 1);
            float f3 = 0.0F;
            worldrenderer.pos(-1.0D, -1.0D, 1.0D).tex(0.0D, 0.0D).color(255, 255, 255, l).endVertex();
            worldrenderer.pos(1.0D, -1.0D, 1.0D).tex(1.0D, 0.0D).color(255, 255, 255, l).endVertex();
            worldrenderer.pos(1.0D, 1.0D, 1.0D).tex(1.0D, 1.0D).color(255, 255, 255, l).endVertex();
            worldrenderer.pos(-1.0D, 1.0D, 1.0D).tex(0.0D, 1.0D).color(255, 255, 255, l).endVertex();
            tessellator.draw();
            GlStateManager.popMatrix();
        }

        GlStateManager.popMatrix();
        GlStateManager.colorMask(true, true, true, false);
    }

    worldrenderer.setTranslation(0.0D, 0.0D, 0.0D);
    GlStateManager.colorMask(true, true, true, true);
    GlStateManager.matrixMode(5889);
    GlStateManager.popMatrix();
    GlStateManager.matrixMode(5888);
    GlStateManager.popMatrix();
    GlStateManager.depthMask(true);
    GlStateManager.enableCull();
    GlStateManager.enableDepth();
  }

  /**
   * Rotate and blurs the skybox view in the main menu
   */
  private void rotateAndBlurSkybox(float p_73968_1_)
  {
    this.mc.getTextureManager().bindTexture(this.viewportTextureResource);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
    GL11.glCopyTexSubImage2D(GL11.GL_TEXTURE_2D, 0, 0, 0, 0, 0, 256, 256);
    GlStateManager.enableBlend();
    GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
    GlStateManager.colorMask(true, true, true, false);
    Tessellator tessellator = Tessellator.getInstance();
    WorldRenderer worldrenderer = tessellator.getWorldRenderer();
    worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
    GlStateManager.disableAlpha();
    int i = 3;

    for (int j = 0; j < i; ++j)
    {
        float f = 1.0F / (float)(j + 1);
        int k = this.width;
        int l = this.height;
        float f1 = (float)(j - i / 2) / 256.0F;
        worldrenderer.pos((double)k, (double)l, (double)this.zLevel).tex((double)(0.0F + f1), 1.0D).color(1.0F, 1.0F, 1.0F, f).endVertex();
        worldrenderer.pos((double)k, 0.0D, (double)this.zLevel).tex((double)(1.0F + f1), 1.0D).color(1.0F, 1.0F, 1.0F, f).endVertex();
        worldrenderer.pos(0.0D, 0.0D, (double)this.zLevel).tex((double)(1.0F + f1), 0.0D).color(1.0F, 1.0F, 1.0F, f).endVertex();
        worldrenderer.pos(0.0D, (double)l, (double)this.zLevel).tex((double)(0.0F + f1), 0.0D).color(1.0F, 1.0F, 1.0F, f).endVertex();
    }

    tessellator.draw();
    GlStateManager.enableAlpha();
    GlStateManager.colorMask(true, true, true, true);
  }

  /**
   * Renders the skybox in the main menu
   */
  private void renderSkybox(int p_73971_1_, int p_73971_2_, float p_73971_3_)
  {
    this.mc.getFramebuffer().unbindFramebuffer();
    GlStateManager.viewport(0, 0, 256, 256);
    this.drawPanorama(p_73971_1_, p_73971_2_, p_73971_3_);
    this.rotateAndBlurSkybox(p_73971_3_);
    this.rotateAndBlurSkybox(p_73971_3_);
    this.rotateAndBlurSkybox(p_73971_3_);
    this.rotateAndBlurSkybox(p_73971_3_);
    this.rotateAndBlurSkybox(p_73971_3_);
    this.rotateAndBlurSkybox(p_73971_3_);
    this.rotateAndBlurSkybox(p_73971_3_);
    this.mc.getFramebuffer().bindFramebuffer(true);
    GlStateManager.viewport(0, 0, this.mc.displayWidth, this.mc.displayHeight);
    float f = this.width > this.height ? 120.0F / (float)this.width : 120.0F / (float)this.height;
    float f1 = (float)this.height * f / 256.0F;
    float f2 = (float)this.width * f / 256.0F;
    int i = this.width;
    int j = this.height;
    Tessellator tessellator = Tessellator.getInstance();
    WorldRenderer worldrenderer = tessellator.getWorldRenderer();
    worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
    worldrenderer.pos(0.0D, (double)j, (double)this.zLevel).tex((double)(0.5F - f1), (double)(0.5F + f2)).color(1.0F, 1.0F, 1.0F, 1.0F).endVertex();
    worldrenderer.pos((double)i, (double)j, (double)this.zLevel).tex((double)(0.5F - f1), (double)(0.5F - f2)).color(1.0F, 1.0F, 1.0F, 1.0F).endVertex();
    worldrenderer.pos((double)i, 0.0D, (double)this.zLevel).tex((double)(0.5F + f1), (double)(0.5F - f2)).color(1.0F, 1.0F, 1.0F, 1.0F).endVertex();
    worldrenderer.pos(0.0D, 0.0D, (double)this.zLevel).tex((double)(0.5F + f1), (double)(0.5F + f2)).color(1.0F, 1.0F, 1.0F, 1.0F).endVertex();
    tessellator.draw();
  }
  
  //reset the last known mouse coords for model rotating
  @Override
  protected void mouseClicked(int mouseX, int mouseY, int mouseButton)
      throws IOException {
    super.mouseClicked(mouseX, mouseY, mouseButton);
    if (mouseButton == 1){
      lastMouseX = mouseX;
      lastMouseY = mouseY;
    }
  }
  
  @Override
  protected void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton,
      long timeSinceLastClick) {
    super.mouseClickMove(mouseX, mouseY, clickedMouseButton, timeSinceLastClick);
    if (clickedMouseButton == 1){
      rotationX = PonyMath.addDegrees(rotationX, (mouseX - lastMouseX));        
      rotationY = PonyMath.addDegrees(rotationY, (mouseY - lastMouseY));  
      
      lastMouseX = mouseX;
      lastMouseY = mouseY;
    }
  }
  
  @Override
  protected void actionPerformed(GuiButton button) throws IOException {
    super.actionPerformed(button);
    try{
      if (button.id == 12034){
        setGuiState(GuiPonyState.IDLE, "");
      }
      //disable other buttons working
      if (guiState != GuiPonyState.IDLE)
        return;
      
      if (button.id == 13035)
      {
          this.mc.displayGuiScreen(parent);
      }
      
      ponyButtonsActionPerformed(button);
      
    }catch(Exception e){
      setGuiState(e);
      e.printStackTrace();
    }
    
  }
  
  protected abstract void ponyButtonsActionPerformed(GuiButton button) throws Exception;

  public void setGuiState(Exception e){
    if (e.getCause() != null)
      setGuiState(GuiPonyState.ERROR, e.getCause().getMessage());
    else
      setGuiState(GuiPonyState.ERROR, e.getMessage());
  }
  
  public void setGuiState(GuiPonyState state, String message) {
    this.guiState = state;
    this.guiStateMessage = message;
    boolean b = (state == GuiPonyState.IDLE) ? true : false;
   
    for (Object o : this.buttonList)
      ((GuiButton)o).enabled = b;
      
    if (state == GuiPonyState.ERROR){
      acceptButton.visible = true;
      acceptButton.enabled = true;
    } else{
      acceptButton.visible = false;
      acceptButton.enabled = false;
    }
  }

  public void updateGuiElements() {
    for (Object o : this.buttonList)
      if (((GuiButton)o) instanceof IGuiUpdatable){
        ((IGuiUpdatable)o).updateValue();
      }
    
  }

}

 

GuiPonySkinManager, which calls the drawing method:

package com.gmail.zethariel.gui;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;

import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;

import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.Project;

import com.gmail.zethariel.PonySkinInfo;
import com.gmail.zethariel.PonySkinManager;
import com.gmail.zethariel.PonySkinInfo.PonySkinOption;
import com.gmail.zethariel.client.model.ModelPony;
import com.gmail.zethariel.client.model.ModelPonyPlayer;
import com.gmail.zethariel.client.render.RenderPonyPlayer;
import com.gmail.zethariel.utils.PonyHelper;
import com.gmail.zethariel.utils.PonyMath;
import com.gmail.zethariel.utils.GuiPonyHelper.GuiPonyState;
import com.mojang.util.UUIDTypeAdapter;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.inventory.GuiInventory;
import net.minecraft.client.model.ModelBook;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.monster.EntityZombie;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;

public class GuiPonySkinManager extends GuiPonyBaseManager implements IGuiScreenStateable {
  
  private File fileToUpload;
  private GuiPonySkinEditor editScreen;

  public GuiPonySkinManager(GuiScreen gui) {
    super(gui);
    editScreen = new GuiPonySkinEditor(this);
    
  }
  
  @Override
  public void initGui() {
    super.initGui();
    if (localPonyInfo == null){
      localPonyInfo = new PonySkinInfo();
      remotePonyInfo = new PonySkinInfo();
      
      remotePonyInfo.ApplyUpdateForPlayer(playerID, this);
      localPonyInfo.ApplyUpdateForPlayer(playerID, this);
    }
    
    this.buttonList.add(new GuiButton(13036, this.width/2-25, this.height/2-25, 50, 20, "-->"));
    
    this.buttonList.add(new GuiButton(13040, 10, 10, 100, 20, "Edit Skin"));
    
    this.buttonList.add(new GuiButton(13038, this.width/2-50, this.height/2 +75, 100, 20, "Load from file")); 
    
    
  }

  @Override
  protected void drawGuiProper() {
    drawPony(width/2 - 85, 75, 2, localPonyInfo);
    drawPony(width/2 + 85, 75, 2, remotePonyInfo);
    
  }

  @Override
  protected void ponyButtonsActionPerformed(GuiButton button) throws Exception {
    InputStream is, is2;
    //need two input streams because the hash function closes one
    if (button.id == 13036){
      try {
        is = PonyHelper.getStreamFromResourceLocation(localPonyInfo.resourceLocation);
        is2 = PonyHelper.getStreamFromResourceLocation(localPonyInfo.resourceLocation);
      } catch (Exception e) {
        e.printStackTrace();
        setGuiState(e);
        return;
      }
      
      PonySkinManager.instance().uploadPlayerPonySkinInfo(localPonyInfo, playerID, is, is2, this);
    }
    
    if (button.id == 13038)
    {
      JFileChooser chooser = new JFileChooser();
      FileNameExtensionFilter filter = new FileNameExtensionFilter(
          "PNG Images", "png");
      chooser.setFileFilter(filter);
      int returnVal = chooser.showOpenDialog(null);
      if(returnVal == JFileChooser.APPROVE_OPTION) {
         System.out.println("You chose to open this file: " +
              chooser.getSelectedFile().getName());
         fileToUpload = chooser.getSelectedFile();
         
         localPonyInfo.resourceLocation = PonySkinManager.instance().loadSkinFromFileAndGetResourceLocation(fileToUpload, this, localPonyInfo);

      }
    }
    
    if (button.id == 13040){
      this.mc.displayGuiScreen(editScreen);
    }
    
    
    
  }


  


  
  

}

 

Thanks!

 

EDIT: Forgot model classes...

 

ModelPony:

// Date: 22-5-2015 19:20:52
// Template version 1.1
// Java generated by Techne
// Keep in mind that you still need to fill in some blanks
// - ZeuX


package com.gmail.zethariel.client.model;

import com.gmail.zethariel.PonySkinInfo;
import com.gmail.zethariel.texture.PonyImageBuffer;
import com.gmail.zethariel.utils.PonyMath;

import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.AbstractClientPlayer;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelQuadruped;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.entity.Entity;
import net.minecraft.util.MathHelper;

public class ModelPony extends ModelBase{
  
  protected final int texWidth = 96, texHeight = 96;

public ModelRenderer head;
public ModelRenderer horn;
public ModelHornRenderer hornMagic;
public ModelRenderer headClothes;
public ModelRenderer neck;
public ModelRenderer body;
public ModelRenderer wingsFolded;
public ModelRenderer wingsUnfolded;
public ModelRenderer frontRightLeg;
public ModelRenderer frontLeftLeg;
public ModelRenderer backLeftLeg;
public ModelRenderer backRightLeg;
public ModelRenderer tailBase;
public ModelRenderer tail;
  //misc
  public boolean isSprinting;
  public boolean isSneak;
  public boolean aimedBow;
  public boolean useMagic;
  public int heldItemLeft;
  public int heldItemRight;
  public PonySkinInfo currentInfo;
  private ModelRenderer tmp;
  public ModelRenderer phantomLimb;
  
  public boolean isFlying = false;

  
  public ModelPony(float scale)
  {
    
    ModelRenderer workRenderer;
    
  	head = new ModelRenderer(this, 48, ;
  	head.setTextureSize(texWidth, texHeight);
  	head.addBox(-4F, -7F, -4F, 8, 8, 8, scale);
  	//right ear
  	head.setTextureOffset(40,16);
  	head.addBox(-4F, -9F, 1F, 2, 2, 2, scale);
  	//left ear
  	head.setTextureOffset(32,16);
  	head.addBox(2F, -9F, 1F, 2, 2, 2, scale);
  	//mouth
  	head.setTextureOffset(48,24);
  	head.addBox(-2F, -2F, -5F, 4, 3, 1, scale);
  	head.setRotationPoint(0F, 2F, -7F);
  	setRotation(head, 0F, 0F, 0F);
  	
  	horn = new ModelRenderer(this, 58,24);
  	horn.setTextureSize(texWidth, texHeight);
  	horn.addBox(0, 0, 0, 1, 4, 1, scale);
  	horn.setRotationPoint(-0.5f, -8.5f, -6.5f);
  	setRotation(horn,degToRad(45) , 0F, 0F);
  	
  	hornMagic = new ModelHornRenderer(this,58, 24);
  	hornMagic.setTextureSize(texWidth, texHeight);
  	hornMagic.addHorn(0, 0, 0, 1, 4, 1, scale+0.5f, 0);
  	setRotation(hornMagic,0 , 0F, 0F);
  	horn.addChild(hornMagic);
  	
  	headClothes = new ModelRenderer(this, 48, 56);
    headClothes.setTextureSize(texWidth, texHeight);
    headClothes.addBox(-4F, -7F, -4F, 8, 8, 8, scale+0.5f);
    headClothes.setRotationPoint(0F, 2F, -7F);
    setRotation(headClothes, 0F, 0F, 0F);

  	neck = new ModelRenderer(this, 32, 20);
  	neck.setTextureSize(texWidth, texHeight);
  	neck.addBox(-2F, 0F, -2F, 4, 4, 4, scale);
  	neck.setRotationPoint(0F, 1, -7F);
  	setRotation(neck, degToRad(15), 0F, 0F);

    body = new ModelRenderer(this, 48, 24);
    body.setTextureSize(texWidth, texWidth);
    body.addBox(-4F, -4F, -8F, 8, 8, 16, scale);
    body.setRotationPoint(0F, 8F, 0F);
    setRotation(body, 0F, 0F, 0F);
    
    //valid for batpony and pony wings. insect wings never fold
    //wings go in order - floofy, batty...
    wingsFolded = new ModelRenderer(this);
    wingsFolded.setRotationPoint(-1, -1, -3);
    setRotation(wingsFolded, 0, 0, 0);
    
    wingsUnfolded = new ModelRenderer(this);
    wingsUnfolded.setRotationPoint(-1, -1, -3);
    setRotation(wingsFolded, 0, 0, 0);
    
    //floof wings
    makeFloofWings();
    
    //rotations and positions set by animation
    frontRightLeg = new ModelRenderer(this, 16, 16);
    frontRightLeg.setTextureSize(texWidth, texHeight);
  	frontRightLeg.addBox(-2F, 2, -2F, 4, 12, 4, scale);
  	//frontRightLeg.setRotationPoint(-2F, 12, -5F);
  	//setRotation(frontRightLeg, 0F, 0F, 0F);
  	frontLeftLeg = new ModelRenderer(this, 0, 16);
  	frontLeftLeg.setTextureSize(texWidth, texHeight);
  	frontLeftLeg.addBox(-2F, 2, -2F, 4, 12, 4, scale);
  	//frontLeftLeg.setRotationPoint(2F, 12, -5F);
  	//setRotation(frontLeftLeg, 0F, 0F, 0F);
  	backLeftLeg = new ModelRenderer(this, 0, 32);
  	backLeftLeg.setTextureSize(texWidth, texHeight);
  	backLeftLeg.addBox(-2F, 2, -2F, 4, 12, 4, scale); 
  	//backLeftLeg.setRotationPoint(2F, 10, 5F);
  	//setRotation(backLeftLeg, 0F, 0F, 0F);
  	backRightLeg = new ModelRenderer(this, 16, 32);
  	backRightLeg.setTextureSize(texWidth, texHeight);
  	backRightLeg.addBox(-2F, 2, -2F, 4, 12, 4, scale);
  	//backRightLeg.setRotationPoint(-2F, 10, 5F);
  	//setRotation(backRightLeg, 0F, 0F, 0F);
  	
  	phantomLimb = new ModelRenderer(this, 0, 0);
  	phantomLimb.setTextureSize(1, 1);
  	phantomLimb.addBox(-2F, 2, -2F, 4, 20, 4, scale);
  
  	tailBase = new ModelRenderer(this, 48, 28);
    tailBase.setTextureSize(texWidth, texHeight);
    tailBase.addBox(0, 0, 0F, 2, 2, 3, scale);
    tailBase.setRotationPoint(-1F, -4, 7F);
    setRotation(tailBase, degToRad(30), 0F, 0F);
  	
  	tail = new ModelRenderer(this, 32, 28);
  	tail.setTextureSize(texWidth, texHeight);
  	//tail.addBox(-2F, -3F, 2F, 4, 16, 4, scale);
  	tail.setRotationPoint(-1, -1.5f,4);
  	setRotation(tail, degToRad(-30), 0F, 0F);
  	//tail is composed of smaller tails
  	
  	//tails go from shortest(4) to longest(16)
  	for (int i = 0; i< 4; i++){
  	  workRenderer = new ModelRenderer(this, 32, 28);
  	  workRenderer.setTextureSize(texWidth, texHeight);
  	  workRenderer.addBox(-2, -1, -2, 4, 4+(4*i), 4, scale);
  	  tail.addChild(workRenderer);
  	}
  	
  	
  	head.addChild(horn);
  	tailBase.addChild(tail);
  	body.addChild(tailBase);
  	body.addChild(wingsFolded);
  	body.addChild(wingsUnfolded);
  	
  	
  }
  
  private void setRotation(ModelHornRenderer model, float x, float y, float z) {
    model.rotateAngleX = x;
    model.rotateAngleY = y;
    model.rotateAngleZ = z;
    
  }

  private void makeFloofWings() {
    ModelRenderer parentRenderer = new ModelRenderer(this, 0, 0);
    parentRenderer.setRotationPoint(0, 0, 0);
    //left wing
    ModelRenderer workRenderer = new ModelRenderer(this,88,0);
    workRenderer.setTextureSize(texWidth, texHeight);
    workRenderer.setRotationPoint(5f, 0, 0);
    setRotation(wingsFolded, 0, 0, 0);
    workRenderer.addBox(-2, 0, 0, 2, 6, 2);
    workRenderer.addBox(0, 0, 0, 2, 8, 2);
    workRenderer.addBox(2, 0, 0, 2, 6, 2);
    setRotation(workRenderer,degToRad(90),0, degToRad(90));
    parentRenderer.addChild(workRenderer);
    //right wing
    workRenderer = new ModelRenderer(this,80,0);
    workRenderer.setTextureSize(texWidth, texHeight);
    workRenderer.setRotationPoint(-5f, 0, 0);
    setRotation(wingsFolded, 0, 0, 0);
    workRenderer.addBox(-2, 0, 0, 2, 6, 2);
    workRenderer.addBox(0, 0, 0, 2, 8, 2);
    workRenderer.addBox(2, 0, 0, 2, 6, 2);
    setRotation(workRenderer,degToRad(90),0, degToRad(90));
    parentRenderer.addChild(workRenderer);
    
    wingsFolded.addChild(parentRenderer);
    
    parentRenderer =  new ModelRenderer(this, 0, 0);
    parentRenderer.setRotationPoint(0, 0, 0);
    
    //left unfurled wing
    workRenderer = new ModelRenderer(this,80,0);
    workRenderer.setTextureSize(texWidth, texHeight);
    workRenderer.setRotationPoint(5, 0, 1);
    setRotation(workRenderer,0,0,degToRad(90));
    /*boxes:
     * x y z 
     * 3x2x1 - baza
     * 6x2x1 - baza2
     */
    float offset = 1;
    //base short digit
    ModelRenderer childWorkRenderer = new ModelRenderer(this,80,4);
    childWorkRenderer.setTextureSize(texWidth, texHeight);
    childWorkRenderer.addBox(-1, 0, 0.5f, 2, 3, 1, 0.25f);
    childWorkRenderer.setRotationPoint(offset,offset,-0.5f);
    setRotation(childWorkRenderer, degToRad(90), degToRad(15) ,0);
    convertToChild(workRenderer, childWorkRenderer);
    //base longer digit
    childWorkRenderer = new ModelRenderer(this,80,4);
    childWorkRenderer.setTextureSize(texWidth, texHeight);
    childWorkRenderer.addBox(-1, 0, 0.5f, 2, 6, 1, 0.3f);
    childWorkRenderer.setRotationPoint(offset-1,offset,0);
    setRotation(childWorkRenderer, degToRad(90), degToRad(90) ,0);
    convertToChild(workRenderer, childWorkRenderer);
    //lowest long digit
    childWorkRenderer = new ModelRenderer(this,80,6);
    childWorkRenderer.setTextureSize(texWidth, texHeight);
    childWorkRenderer.addBox(-1, 0, 0.5f, 2, 8, 1);
    childWorkRenderer.setRotationPoint(offset-0.75f,offset,-1f);
    setRotation(childWorkRenderer, degToRad(90), degToRad(15) ,0);
    convertToChild(workRenderer, childWorkRenderer);
    //second lowest long digit
    childWorkRenderer = new ModelRenderer(this,80,6);
    childWorkRenderer.setTextureSize(texWidth, texHeight);
    childWorkRenderer.addBox(-1, 0, 0.5f, 2, 8, 1);
    childWorkRenderer.setRotationPoint(offset+1.5f,offset,0.5f);
    setRotation(childWorkRenderer, degToRad(90), degToRad(35) ,0);
    convertToChild(workRenderer, childWorkRenderer);
    //third lowest long digit
    childWorkRenderer = new ModelRenderer(this,80,5);
    childWorkRenderer.setTextureSize(texWidth, texHeight);
    childWorkRenderer.addBox(-1, 0, 0.5f, 2, 9, 1);
    childWorkRenderer.setRotationPoint(offset+3f,offset,0);
    setRotation(childWorkRenderer, degToRad(90), degToRad(55) ,0);
    convertToChild(workRenderer, childWorkRenderer);
    //fourth lowest long digit
    childWorkRenderer = new ModelRenderer(this,80,4);
    childWorkRenderer.setTextureSize(texWidth, texHeight);
    childWorkRenderer.addBox(-1, 0, 0.5f, 2, 8, 1,0.15f);
    childWorkRenderer.setRotationPoint(offset+5.40f,offset,-0.175f);
    setRotation(childWorkRenderer, degToRad(90), degToRad(90) ,0);
    convertToChild(workRenderer, childWorkRenderer);
    
    convertToChild( parentRenderer,workRenderer);
    
    //right wing
    workRenderer = new ModelRenderer(this,80,0);
    workRenderer.setTextureSize(texWidth, texHeight);
    workRenderer.setRotationPoint(-3, 0, 1);
    setRotation(workRenderer,0,0,degToRad(90));
    
    childWorkRenderer = new ModelRenderer(this,80,4);
    childWorkRenderer.setTextureSize(texWidth, texHeight);
    childWorkRenderer.addBox(-1, 0, 0.5f, 2, 3, 1, 0.25f);
    childWorkRenderer.setRotationPoint(offset,offset,-0.5f);
    setRotation(childWorkRenderer, degToRad(90), degToRad(15) ,0);
    convertToChild(workRenderer, childWorkRenderer);
    //base longer digit
    childWorkRenderer = new ModelRenderer(this,80,4);
    childWorkRenderer.setTextureSize(texWidth, texHeight);
    childWorkRenderer.addBox(-1, 0, 0.5f, 2, 6, 1, 0.3f);
    childWorkRenderer.setRotationPoint(offset-1,offset,0);
    setRotation(childWorkRenderer, degToRad(90), degToRad(90) ,0);
    convertToChild(workRenderer, childWorkRenderer);
    //lowest long digit
    childWorkRenderer = new ModelRenderer(this,80,6);
    childWorkRenderer.setTextureSize(texWidth, texHeight);
    childWorkRenderer.addBox(-1, 0, 0.5f, 2, 8, 1);
    childWorkRenderer.setRotationPoint(offset-0.75f,offset,-1f);
    setRotation(childWorkRenderer, degToRad(90), degToRad(15) ,0);
    convertToChild(workRenderer, childWorkRenderer);
    //second lowest long digit
    childWorkRenderer = new ModelRenderer(this,80,6);
    childWorkRenderer.setTextureSize(texWidth, texHeight);
    childWorkRenderer.addBox(-1, 0, 0.5f, 2, 8, 1);
    childWorkRenderer.setRotationPoint(offset+1.5f,offset,0.5f);
    setRotation(childWorkRenderer, degToRad(90), degToRad(35) ,0);
    convertToChild(workRenderer, childWorkRenderer);
    //third lowest long digit
    childWorkRenderer = new ModelRenderer(this,80,5);
    childWorkRenderer.setTextureSize(texWidth, texHeight);
    childWorkRenderer.addBox(-1, 0, 0.5f, 2, 9, 1);
    childWorkRenderer.setRotationPoint(offset+3f,offset,0);
    setRotation(childWorkRenderer, degToRad(90), degToRad(55) ,0);
    convertToChild(workRenderer, childWorkRenderer);
    //fourth lowest long digit
    childWorkRenderer = new ModelRenderer(this,80,4);
    childWorkRenderer.setTextureSize(texWidth, texHeight);
    childWorkRenderer.addBox(-1, 0, 0.5f, 2, 8, 1,0.15f);
    childWorkRenderer.setRotationPoint(offset+5.40f,offset,-0.175f);
    setRotation(childWorkRenderer, degToRad(90), degToRad(90) ,0);
    convertToChild(workRenderer, childWorkRenderer);
    
    convertToChild( parentRenderer, workRenderer);
    
    convertToChild (wingsUnfolded, parentRenderer);
    
    
   
    
  }
  
  protected void convertToChild(ModelRenderer parParent, ModelRenderer parChild)
  {
     // move child rotation point to be relative to parent
    /* parChild.rotationPointX -= parParent.rotationPointX;
     parChild.rotationPointY -= parParent.rotationPointY;
     parChild.rotationPointZ -= parParent.rotationPointZ;
     // make rotations relative to parent
     parChild.rotateAngleX -= parParent.rotateAngleX;
     parChild.rotateAngleY -= parParent.rotateAngleY;
     parChild.rotateAngleZ -= parParent.rotateAngleZ;*/
     // create relationship
     parParent.addChild(parChild);
  }

  protected void render( float f, float f1, float f2, float f3, float f4, float f5)
  {

    
    if (currentInfo.size == 0)
    {
        GlStateManager.pushMatrix();
        float f11 = 2.0F;
        GlStateManager.scale(1.5F / f11, 1.5F / f11, 1.5F / f11);
        GlStateManager.translate(0.0F, 16.0F * f5, 4 *f5);
        this.head.render(f5);
        headClothes.render(f5);
        
        GlStateManager.popMatrix();
        GlStateManager.pushMatrix();
        GlStateManager.scale(1.0F / f11, 1.0F / f11, 1.0F / f11);
        GlStateManager.translate(0.0F, 24.0F * f5, 0.0F);
        neck.render(f5);
        body.render(f5);
        frontLeftLeg.render(f5);
        frontRightLeg.render(f5);
        backLeftLeg.render(f5);
        backRightLeg.render(f5);
          
        
        GlStateManager.popMatrix();
    }else
    if (currentInfo.size == 1){
    
      headClothes.render(f5);
      head.render(f5);
      
      neck.render(f5);
      body.render(f5);
      frontLeftLeg.render(f5);
      frontRightLeg.render(f5);
      backLeftLeg.render(f5);
      backRightLeg.render(f5);

    }else
    if (currentInfo.size == 2){
      GlStateManager.pushMatrix();
      GlStateManager.translate(0.0F, -2.1*f5, 0);
      headClothes.render(f5);
      head.render(f5);
      
      neck.render(f5);
      body.render(f5);
      GlStateManager.translate(0.0F, -2.4*f5, 0);
      GlStateManager.scale(1, 1.2, 1);
      frontLeftLeg.render(f5);
      frontRightLeg.render(f5);
      backLeftLeg.render(f5);
      backRightLeg.render(f5);
      GlStateManager.popMatrix();
    }else
    if (currentInfo.size == 3){
      GlStateManager.pushMatrix();
      GlStateManager.translate(0, -6*f5, 0);
      
      
      
      GlStateManager.scale(1.25, 1.25, 1.25);
      headClothes.render(f5);
      head.render(f5);
      
      neck.render(f5);
      body.render(f5);
      frontLeftLeg.render(f5);
      frontRightLeg.render(f5);
      backLeftLeg.render(f5);
      backRightLeg.render(f5);
      GlStateManager.popMatrix();
    }


  }
  
  public void render(Entity p_78088_1_, float p_78088_2_, float p_78088_3_, float timer, float p_78088_5_, float p_78088_6_, float p_78088_7_){
    
  this.setRotationAngles(p_78088_2_, p_78088_3_, timer, p_78088_5_, p_78088_6_, p_78088_7_, p_78088_1_);
  this.applyPony(p_78088_1_, timer);
    
  this.render(p_78088_2_, p_78088_3_, timer, p_78088_5_, p_78088_6_, p_78088_7_);
  
  }
  
  
  private void applyPony(Entity entity, float currentTimer) {
  
    //tail shenanigans
    for (int i = 0; i < 4; i++){
      ((ModelRenderer)(tail.childModels.get(i))).showModel = (i == currentInfo.tailLength-1);
    }
    
    
    //horn
    horn.showModel = (currentInfo.hornType > 0);
    hornMagic.showModel = heldItemRight > 0; 
    
    //if (heldItemRight > 0){
      
      
    //}
   
    
    //wing mess
    //System.out.println(entity.onGround);
    if (currentInfo.wingType > 0){
      if (entity  == null){
        wingsUnfolded.showModel = false;
        wingsFolded.showModel = true;
        tmp = wingsFolded;
      }else
      if (!isFlying && !isSneak){
        
        wingsUnfolded.showModel = false;
        wingsFolded.showModel = true;
        currentInfo.wingAnimationTimer = 0;
        tmp = wingsFolded;
      }else{
         if (!isFlying && isSneak)
           currentInfo.wingAnimationTimer = 0;
        wingsFolded.showModel = false;
        wingsUnfolded.showModel = true;
        tmp = wingsUnfolded;
      }
      //currently only 1 pair of wings
      for (int i = 0; i < 1; i++){
        ((ModelRenderer)(tmp.childModels.get(i))).showModel = (i == currentInfo.wingType-1);
      }
    }else{
      wingsFolded.showModel = false;
      wingsUnfolded.showModel = false;
    }
    
    //size mess      
    //done during rendering, eye height done during info update
    
    //muzzle
    //will show or hide different types
    
  }

  private void copyModelAngles(ModelRenderer source, ModelHornRenderer dest) {
    dest.rotateAngleX = source.rotateAngleX;
    dest.rotateAngleY = source.rotateAngleY;
    dest.rotateAngleZ = source.rotateAngleZ;
    dest.rotationPointX = source.rotationPointX;
    dest.rotationPointY = source.rotationPointY;
    dest.rotationPointZ = source.rotationPointZ;
    
  }

  public void setVisibility(boolean invisible)
  {
  head.showModel = invisible;
  neck.showModel = invisible;
  body.showModel = invisible;
  frontRightLeg.showModel = invisible;
  frontLeftLeg.showModel = invisible;
  backLeftLeg.showModel = invisible;
  backRightLeg.showModel = invisible;
  tail.showModel = invisible;
  tailBase.showModel = invisible;
  
  headClothes.showModel = invisible;
  }
  
  protected void setRotation(ModelRenderer model, float x, float y, float z)
  {
	model.rotateAngleX = x;
	model.rotateAngleY = y;
	model.rotateAngleZ = z;
  }
  
  //p_2 represents movement speed
  //p_3 represents FLOWING TIME
  public void setRotationAngles(float p_78087_1_, float p_78087_2_, float timer, float p_78087_4_, float p_78087_5_, float partialTicks, Entity entity)
  {

    
      float f6 = (180F / (float)Math.PI);
      
      //the head doesn't look good at 90*. Clamp it
      this.head.rotateAngleY = p_78087_4_ / f6;
       
      this.head.rotateAngleX = PonyMath.clamp(p_78087_5_ / f6,  degToRad(-60), degToRad(60));
      
      //prepare the maximum leg rotation angle
      float legRotation = degToRad(17) * p_78087_2_;
      float cycleSpeed = 0.7f;
      float cycleOffset = (float)Math.PI;
      
      //set the base pose
      if (isSneak && !isFlying){
        currentInfo.wingAnimationTimer = degToRad(30);
        this.wingsUnfolded.rotateAngleX = degToRad(-20);
        cycleSpeed /= 1.5f;
    	  SneakingStandingPose();
      }
      else
        NormalStandingPose();
      
      //copy into phantom limb
      copyModelAngles(frontRightLeg, phantomLimb);
      phantomLimb.rotationPointY -= 10;
      phantomLimb.rotationPointX -= 8;
      
      //set which limb will be doing the work
      //in the future set it to the dominant one!!
      if (useMagic && this.heldItemRight > 0 )
        tmp = phantomLimb;
      else
        tmp = frontRightLeg;
      
      //apply changes for sprinting
      if (isSprinting){
        cycleOffset = degToRad(90);
        legRotation *= 1.90f;
      }
      
      //aply changes for carrying an item
      
      switch (this.heldItemRight)
      {
          case 0:
          case 2:
          default:
              break;
          case 1:
              this.tmp.rotateAngleX += degToRad(-23);
              break;
          case 3:
              break;
      }
      
      //idle item held animation
      if (this.heldItemRight > 0 ){
        this.tmp.rotateAngleX += MathHelper.sin(timer * 0.067F) * 0.05F;
        this.tmp.rotateAngleZ += MathHelper.cos(timer * 0.09F) * 0.05F + 0.05F;
      }

      //do ground animation
      if (!isFlying || currentInfo.wingType == 0){
        float animationTime1 = MathHelper.cos(p_78087_1_ * cycleSpeed);
        float animationTime2 = MathHelper.cos(p_78087_1_ * cycleSpeed + cycleOffset);
        
      //Legs swinging back and forth

        this.frontLeftLeg.rotateAngleX += animationTime1 * legRotation;    
        this.backRightLeg.rotateAngleX += animationTime1 * legRotation;
        
        this.frontRightLeg.rotateAngleX += animationTime2 * legRotation;
        this.backLeftLeg.rotateAngleX += animationTime2 * legRotation;
      }   
      
      if (currentInfo.wingType > 0){
        //if wings, flap them
        DoWingCycle(timer,cycleSpeed + p_78087_2_/3 + (isSprinting ? 0.5f : 0),currentInfo.wingType -1);
        if (isFlying){
          //zero out the sneak rotation for wings
          this.wingsUnfolded.rotateAngleX = degToRad(0);
          
          //set the leg spread rotation
          float angle1 = 0, angle2 =0;
          if (isSprinting){
            angle1 = degToRad(90);
            angle2 = degToRad(15);
          }else{
            angle1 = 1.5f * legRotation*1.25f;
            angle2 = 1.5f * legRotation+0.2f;
          }
          
          addRotation(frontLeftLeg, - angle1, - angle2, 0);
          setRotation(frontRightLeg, (frontRightLeg.rotateAngleX)*(1-p_78087_2_) - angle1, angle2,frontRightLeg.rotateAngleZ);
          
          addRotation(backLeftLeg,  angle1,  angle2, 0);
          addRotation(backRightLeg,  angle1,- angle2, 0);
        }
      }
  
        
     
      if (isSprinting){
        tail.rotateAngleX = degToRad(60);
        tail.rotateAngleX += MathHelper.cos(p_78087_1_) * degToRad(5);
      }else{
        tail.rotateAngleZ = MathHelper.cos(p_78087_1_ * cycleSpeed) * degToRad(15) * p_78087_2_ ;
        tail.rotateAngleX = legRotation*1.5f+degToRad(-30);
      }
      
    /*  if (this.heldItemLeft != 0)
      {
          this.frontLeftLeg.rotateAngleX = this.frontLeftLeg.rotateAngleX * 0.5F - ((float)Math.PI / 10F) * (float)this.heldItemLeft;
      }*/

      
      
      
    if (this.swingProgress > -9990.0F)
    {
      float f7 = MathHelper.sin(swingProgress * (float)Math.PI);
      float f8 = MathHelper.sin(this.swingProgress * (float)Math.PI) * -(this.head.rotateAngleX - 0.7F) * 0.75F;
      
      if (useMagic){
        
        this.tmp.rotateAngleY += MathHelper.sin(MathHelper.sqrt_float(swingProgress) * (float)Math.PI * 2.0F) * 0.2F;
        this.tmp.rotateAngleX = (float)((double)this.tmp.rotateAngleX - ((double)f7 * 1.2D + (double)f8));
        this.tmp.rotateAngleZ += MathHelper.sin(this.swingProgress * (float)Math.PI) * -0.4F;
      }else{
        this.body.rotateAngleY = MathHelper.sin(MathHelper.sqrt_float(swingProgress) * (float)Math.PI * 2.0F) * 0.2F;
        this.tmp.rotateAngleY += this.body.rotateAngleY;
        this.frontLeftLeg.rotateAngleY += this.body.rotateAngleY;
        this.frontLeftLeg.rotateAngleX += this.body.rotateAngleY;
        
        this.tmp.rotateAngleX = (float)((double)this.tmp.rotateAngleX - ((double)f7 * 1.2D + (double)f8));
        this.tmp.rotateAngleY += this.body.rotateAngleY;
        this.tmp.rotateAngleZ += MathHelper.sin(this.swingProgress * (float)Math.PI) * -0.4F;
      }
    }

      /*if (this.aimedBow)
      {
          f6 = 0.0F;
          f7 = 0.0F;
          this.frontRightLeg.rotateAngleZ = 0.0F;
          this.frontLeftLeg.rotateAngleZ = 0.0F;
          this.frontRightLeg.rotateAngleY = -(0.1F - f6 * 0.6F) + this.head.rotateAngleY;
          this.frontLeftLeg.rotateAngleY = 0.1F - f6 * 0.6F + this.head.rotateAngleY + 0.4F;
          this.frontRightLeg.rotateAngleX = -((float)Math.PI / 2F) + this.head.rotateAngleX;
          this.frontLeftLeg.rotateAngleX = -((float)Math.PI / 2F) + this.head.rotateAngleX;
          this.frontRightLeg.rotateAngleX -= f6 * 1.2F - f7 * 0.4F;
          this.frontLeftLeg.rotateAngleX -= f6 * 1.2F - f7 * 0.4F;
          this.frontRightLeg.rotateAngleZ += MathHelper.cos(p_78087_3_ * 0.09F) * 0.05F + 0.05F;
          this.frontLeftLeg.rotateAngleZ -= MathHelper.cos(p_78087_3_ * 0.09F) * 0.05F + 0.05F;
          this.frontRightLeg.rotateAngleX += MathHelper.sin(p_78087_3_ * 0.067F) * 0.05F;
          this.frontLeftLeg.rotateAngleX -= MathHelper.sin(p_78087_3_ * 0.067F) * 0.05F;
      }*/

      
    copyModelAngles(head, headClothes);
      
      
  }  
  


  private void addRotation(ModelRenderer model, float x, float y, int z) {
    model.rotateAngleX += x;
    model.rotateAngleY += y;
    model.rotateAngleZ += z;
    
  }

  private void DoWingCycle(float time, float cycleSpeed, int wingIndex) {
    
    ModelRenderer wings = (ModelRenderer) ((ModelRenderer) (this.wingsUnfolded.childModels.get(wingIndex))).childModels.get(0);
    currentInfo.wingAnimationTimer += (time - currentInfo.wingTimer) * cycleSpeed;
    currentInfo.wingTimer = time;
    float wingCycle = (float) Math.cos(currentInfo.wingAnimationTimer + degToRad(180));
    
    wings.rotateAngleZ = wingCycle * degToRad(90);
    //System.out.println(wings.rotateAngleZ);
    wings = (ModelRenderer) ((ModelRenderer) (this.wingsUnfolded.childModels.get(wingIndex))).childModels.get(1);
    wings.rotateAngleZ = -wingCycle* degToRad(90) + degToRad(180);
    
  }

  public void postRenderArm(float f5)
  {
    
    
    if (currentInfo.size == 0)
    {
        float f11 = 2.0F;
        GlStateManager.scale(1.0F / f11, 1.0F / f11, 1.0F / f11);
        GlStateManager.translate(0.0F, 24.0F * f5, 0.0F);
    }else
    if (currentInfo.size == 1){
    

    }else
    if (currentInfo.size == 2){
      
      GlStateManager.translate(0.0F, -2.1*f5, 0);
      GlStateManager.translate(0.0F, -2.4*f5, 0);
      GlStateManager.scale(1, 1.2, 1);
    }else
    if (currentInfo.size == 3){
      
      GlStateManager.translate(0, -6*f5, 0);
      GlStateManager.scale(1.25, 1.25, 1.25);
    }
    
    if (currentInfo.hornType == 0)
      this.frontRightLeg.postRender(f5);
    else
      this.phantomLimb.postRender(f5);
    
  }
  

  protected float degToRad(float degrees)
  {
    return degrees * (float)Math.PI / 180 ;
  }
  
  protected void NormalStandingPose(){
    float delta = -2;
    head.setRotationPoint(0, 1, -9F);
    
    neck.setRotationPoint(0F, 1, -9F);
    setRotation(neck, degToRad(15), 0F, 0F);
  
    body.setRotationPoint(0F, 8F, -2F);
    setRotation(body, 0F, 0F, 0F);
    
    frontRightLeg.setRotationPoint(-2F, 10, -7F);
    setRotation(frontRightLeg, 0F, 0F, 0F);
  
    frontLeftLeg.setRotationPoint(2F,10, -7F);
    setRotation(frontLeftLeg, 0F, 0F, 0F);
   
    backLeftLeg.setRotationPoint(2F, 10, 3F);
    setRotation(backLeftLeg, 0F, 0F, 0F);
  
    backRightLeg.setRotationPoint(-2F, 10, 3F);
    setRotation(backRightLeg, 0F, 0F, 0F);
    
    tail.setRotationPoint(1, 1,4);    
    setRotation(tail, degToRad(-30), 0F, 0F);
    
    

    //tailBase.setRotationPoint(0F, 5, 7F);
    //setRotation(tailBase, degToRad(30), 0F, 0F);
    
  }
  
  protected void SneakingStandingPose(){
    
    this.head.setRotationPoint(0F, 10.5f, -9F);
    
    this.neck.setRotationPoint(0F, 10, -9);
    setRotation(neck, degToRad(36), 0, 0);
    
    this.body.setRotationPoint(0, 14, 0);
    setRotation(body, degToRad(20), 0, 0);
    
    this.frontLeftLeg.setRotationPoint(6, 15, -3);
    setRotation(frontLeftLeg,degToRad(-50),0,0);
    
    
    this.frontRightLeg.setRotationPoint(-6, 15, -3);
    setRotation(frontRightLeg,degToRad(-50),0,0);
    
    this.backRightLeg.setRotationPoint(-6, 10, 5);
    setRotation(backRightLeg,0,0,0);
    
    this.backLeftLeg.setRotationPoint(6, 10, 5);
    setRotation(backLeftLeg,0,0,0);

    //this.tailBase.setRotationPoint(0, 9, 5.5f);
    //this.tailBase.rotateAngleX = degToRad(70);
    
    //this.tail.setRotationPoint(0, 9, 5.5f);
    //this.tail.rotateAngleX = degToRad(40);
  }
  
@Override
public void setModelAttributes(ModelBase p_178686_1_) {
   super.setModelAttributes(p_178686_1_);
   ModelPony m = (ModelPony)p_178686_1_;
    
   this.isSprinting = m.isSprinting;
   this.isSneak = m.isSneak;
   this.aimedBow = m.aimedBow;
   this.heldItemLeft = m.heldItemLeft;
   this.heldItemRight = m.heldItemRight;
   this.currentInfo = m.currentInfo;
   this.useMagic = m.currentInfo.hornType > 0;
  }
   
public void setPonyAttributes(PonySkinInfo info) {
   this.currentInfo = info;
   useMagic = info.hornType > 0;
   isChild = info.size == 0;
}



}

 

Special ModelHornRenderer:

package com.gmail.zethariel.client.model;

import java.util.List;

import org.lwjgl.opengl.GL11;

import com.google.common.collect.Lists;

import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelBox;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.client.model.TextureOffset;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

public class ModelHornRenderer extends ModelRenderer {
  
    /** The size of the texture file's width in pixels. */
    public float textureWidth;
    /** The size of the texture file's height in pixels. */
    public float textureHeight;
    /** The X offset into the texture used for displaying this model */
    private int textureOffsetX;
    /** The Y offset into the texture used for displaying this model */
    private int textureOffsetY;
    public float rotationPointX;
    public float rotationPointY;
    public float rotationPointZ;
    public float rotateAngleX;
    public float rotateAngleY;
    public float rotateAngleZ;
    private boolean compiled;
    /** The GL display list rendered by the Tessellator for this model */
    private int displayList;
    public boolean mirror;
    public boolean showModel;
    /** Hides the model. */
    public boolean isHidden;
    public HornModel hornModel;
    
    
    public float offsetX;
    public float offsetY;
    public float offsetZ;
    
    
    private ModelHornRenderer(ModelBase model)
    {
        super(model);
        this.textureWidth = 96.0F;
        this.textureHeight = 96.0F;
        this.showModel = true;
    }

    public ModelHornRenderer(ModelBase model,int texOffX, int texOffY)
    {
        this(model);
        this.setTextureOffset(texOffX, texOffY);
    }

    public ModelHornRenderer setTextureOffset(int x, int y)
    {
        this.textureOffsetX = x;
        this.textureOffsetY = y;
        return this;
    }


    /**
     * Creates a textured box. Args: originX, originY, originZ, width, height, depth, scaleFactor.
     */
    public void addHorn(float originX, float originY, float originZ, int width, int height, int depth, float scaleFactor, int hornType)
    {
       hornModel = new HornModel(this, this.textureOffsetX, this.textureOffsetY, originX, originY, originZ, width, height, depth, scaleFactor, hornType);
    }

    public void setRotationPoint(float rotationPointXIn, float rotationPointYIn, float rotationPointZIn)
    {
        this.rotationPointX = rotationPointXIn;
        this.rotationPointY = rotationPointYIn;
        this.rotationPointZ = rotationPointZIn;
    }
    
    @Override
    @SideOnly(Side.CLIENT)
    public void render(float p_78785_1_){
      GlStateManager.disableLighting();      
      GlStateManager.enableBlend();
      GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
      GlStateManager.color(1, 1, 1, 0.6f);
      properRender(p_78785_1_);
      GlStateManager.blendFunc(770, 771);
      GlStateManager.disableBlend();
      GlStateManager.color(1, 1, 1, 1);
     // GlStateManager.depthMask(true);
      GlStateManager.enableLighting();
    }
    
    @Override
    @SideOnly(Side.CLIENT)
    public void renderWithRotation(float p_78785_1_){
      GlStateManager.disableLighting();      
      GlStateManager.enableBlend();
      GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
      GlStateManager.color(1, 1, 1, 0.6f);
      properRenderWithRotation(p_78785_1_);
      GlStateManager.blendFunc(770, 771);
      GlStateManager.disableBlend();
      GlStateManager.color(1, 1, 1, 1);

      GlStateManager.enableLighting();
    }
    
    
    
    @SideOnly(Side.CLIENT)
    private void properRenderWithRotation(float p_78791_1_)
    {
        if (!this.isHidden)
        {
            if (this.showModel)
            {
                if (!this.compiled)
                {
                    this.compileDisplayList(p_78791_1_);
                }

                GlStateManager.pushMatrix();
                GlStateManager.translate(this.rotationPointX * p_78791_1_, this.rotationPointY * p_78791_1_, this.rotationPointZ * p_78791_1_);

                if (this.rotateAngleY != 0.0F)
                {
                    GlStateManager.rotate(this.rotateAngleY * (180F / (float)Math.PI), 0.0F, 1.0F, 0.0F);
                }

                if (this.rotateAngleX != 0.0F)
                {
                    GlStateManager.rotate(this.rotateAngleX * (180F / (float)Math.PI), 1.0F, 0.0F, 0.0F);
                }

                if (this.rotateAngleZ != 0.0F)
                {
                    GlStateManager.rotate(this.rotateAngleZ * (180F / (float)Math.PI), 0.0F, 0.0F, 1.0F);
                }

                GlStateManager.callList(this.displayList);
                GlStateManager.popMatrix();
            }
        }
    }

    @SideOnly(Side.CLIENT)
    private void properRender(float p_78785_1_)
    {
        if (!this.isHidden)
        {
            if (this.showModel)
            {
                if (!this.compiled)
                {
                    this.compileDisplayList(p_78785_1_);
                }

                GlStateManager.translate(this.offsetX, this.offsetY, this.offsetZ);

                if (this.rotateAngleX == 0.0F && this.rotateAngleY == 0.0F && this.rotateAngleZ == 0.0F)
                {
                    if (this.rotationPointX == 0.0F && this.rotationPointY == 0.0F && this.rotationPointZ == 0.0F)
                    {
                        GlStateManager.callList(this.displayList);
                    }
                    else
                    {
                        GlStateManager.translate(this.rotationPointX * p_78785_1_, this.rotationPointY * p_78785_1_, this.rotationPointZ * p_78785_1_);
                        GlStateManager.callList(this.displayList);

                        GlStateManager.translate(-this.rotationPointX * p_78785_1_, -this.rotationPointY * p_78785_1_, -this.rotationPointZ * p_78785_1_);
                    }
                }
                else
                {
                    GlStateManager.pushMatrix();
                    GlStateManager.translate(this.rotationPointX * p_78785_1_, this.rotationPointY * p_78785_1_, this.rotationPointZ * p_78785_1_);

                    if (this.rotateAngleZ != 0.0F)
                    {
                        GlStateManager.rotate(this.rotateAngleZ * (180F / (float)Math.PI), 0.0F, 0.0F, 1.0F);
                    }

                    if (this.rotateAngleY != 0.0F)
                    {
                        GlStateManager.rotate(this.rotateAngleY * (180F / (float)Math.PI), 0.0F, 1.0F, 0.0F);
                    }

                    if (this.rotateAngleX != 0.0F)
                    {
                        GlStateManager.rotate(this.rotateAngleX * (180F / (float)Math.PI), 1.0F, 0.0F, 0.0F);
                    }

                    GlStateManager.callList(this.displayList);

                   

                    GlStateManager.popMatrix();
                }

                GlStateManager.translate(-this.offsetX, -this.offsetY, -this.offsetZ);
            }
        }
    }

    

    /**
     * Allows the changing of Angles after a box has been rendered
     */
    @SideOnly(Side.CLIENT)
    public void postRender(float scale)
    {
        if (!this.isHidden)
        {
            if (this.showModel)
            {
                if (!this.compiled)
                {
                    this.compileDisplayList(scale);
                }

                if (this.rotateAngleX == 0.0F && this.rotateAngleY == 0.0F && this.rotateAngleZ == 0.0F)
                {
                    if (this.rotationPointX != 0.0F || this.rotationPointY != 0.0F || this.rotationPointZ != 0.0F)
                    {
                        GlStateManager.translate(this.rotationPointX * scale, this.rotationPointY * scale, this.rotationPointZ * scale);
                    }
                }
                else
                {
                    GlStateManager.translate(this.rotationPointX * scale, this.rotationPointY * scale, this.rotationPointZ * scale);

                    if (this.rotateAngleZ != 0.0F)
                    {
                        GlStateManager.rotate(this.rotateAngleZ * (180F / (float)Math.PI), 0.0F, 0.0F, 1.0F);
                    }

                    if (this.rotateAngleY != 0.0F)
                    {
                        GlStateManager.rotate(this.rotateAngleY * (180F / (float)Math.PI), 0.0F, 1.0F, 0.0F);
                    }

                    if (this.rotateAngleX != 0.0F)
                    {
                        GlStateManager.rotate(this.rotateAngleX * (180F / (float)Math.PI), 1.0F, 0.0F, 0.0F);
                    }
                }
            }
        }
    }

    /**
     * Compiles a GL display list for this model
     */
    @SideOnly(Side.CLIENT)
    private void compileDisplayList(float scale)
    {
        this.displayList = GLAllocation.generateDisplayLists(1);
        GL11.glNewList(this.displayList, GL11.GL_COMPILE);
        WorldRenderer worldrenderer = Tessellator.getInstance().getWorldRenderer();

        
        hornModel.render(worldrenderer, scale);
        

        GL11.glEndList();
        this.compiled = true;
    }

    /**
     * Returns the model renderer with the new texture parameters.
     */
    public ModelHornRenderer setTextureSize(int textureWidthIn, int textureHeightIn)
    {
        this.textureWidth = (float)textureWidthIn;
        this.textureHeight = (float)textureHeightIn;
        return this;
    }
}

 

And HornModel:

package com.gmail.zethariel.client.model;

import net.minecraft.client.model.ModelBox;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.client.model.PositionTextureVertex;
import net.minecraft.client.model.TexturedQuad;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

public class HornModel {
  
  /** The (x,y,z) vertex positions and (u,v) texture coordinates for each of the 8 points on a cube */
  private PositionTextureVertex[] vertexPositions;
  /** An array of 6 TexturedQuads, one for each face of a cube */
  private TexturedQuad[] quadList;
  /** X vertex coordinate of lower box corner */
  public final float posX1;
  /** Y vertex coordinate of lower box corner */
  public final float posY1;
  /** Z vertex coordinate of lower box corner */
  public final float posZ1;
  /** X vertex coordinate of upper box corner */
  public final float posX2;
  /** Y vertex coordinate of upper box corner */
  public final float posY2;
  /** Z vertex coordinate of upper box corner */
  public final float posZ2;
  


  public HornModel(ModelHornRenderer modelHornRenderer, int textureOffsetX,
      int textureOffsetY, float originX, float originY, float originZ,
      int width, int height, int depth, float scaleFactor, int hornType) {
    
      this.posX1 = originX;
      this.posY1 = originY;
      this.posZ1 = originZ;
      this.posX2 = originX + (float)width;
      this.posY2 = originY + (float)height;
      this.posZ2 = originZ + (float)depth;
      this.vertexPositions = new PositionTextureVertex[8];
      this.quadList = new TexturedQuad[6];
      float f = originX + (float)width;
      float f1 = originY + (float)height;
      float f2 = originZ + (float)depth;
      originX = originX - scaleFactor;
      originY = originY - scaleFactor;
      originZ = originZ - scaleFactor;
      f = f + scaleFactor;
      f1 = f1 + scaleFactor;
      f2 = f2 + scaleFactor;
  
      PositionTextureVertex positiontexturevertex7 = new PositionTextureVertex(originX, originY, originZ, 0.0F, 0.0F);
      PositionTextureVertex positiontexturevertex = new PositionTextureVertex(f, originY, originZ, 0.0F, 8.0F);
      PositionTextureVertex positiontexturevertex1 = new PositionTextureVertex(f, f1, originZ, 8.0F, 8.0F);
      PositionTextureVertex positiontexturevertex2 = new PositionTextureVertex(originX, f1, originZ, 8.0F, 0.0F);
      PositionTextureVertex positiontexturevertex3 = new PositionTextureVertex(originX, originY, f2, 0.0F, 0.0F);
      PositionTextureVertex positiontexturevertex4 = new PositionTextureVertex(f, originY, f2, 0.0F, 8.0F);
      PositionTextureVertex positiontexturevertex5 = new PositionTextureVertex(f, f1, f2, 8.0F, 8.0F);
      PositionTextureVertex positiontexturevertex6 = new PositionTextureVertex(originX, f1, f2, 8.0F, 0.0F);
      this.vertexPositions[0] = positiontexturevertex7;
      this.vertexPositions[1] = positiontexturevertex;
      this.vertexPositions[2] = positiontexturevertex1;
      this.vertexPositions[3] = positiontexturevertex2;
      this.vertexPositions[4] = positiontexturevertex3;
      this.vertexPositions[5] = positiontexturevertex4;
      this.vertexPositions[6] = positiontexturevertex5;
      this.vertexPositions[7] = positiontexturevertex6;
      this.quadList[0] = new TexturedQuad(new PositionTextureVertex[] {positiontexturevertex4, positiontexturevertex, positiontexturevertex1, positiontexturevertex5}, textureOffsetX, textureOffsetY, textureOffsetX + 1, textureOffsetY + 1, modelHornRenderer.textureWidth, modelHornRenderer.textureHeight);
      this.quadList[1] = new TexturedQuad(new PositionTextureVertex[] {positiontexturevertex7, positiontexturevertex3, positiontexturevertex6, positiontexturevertex2}, textureOffsetX, textureOffsetY, textureOffsetX + 1, textureOffsetY + 1, modelHornRenderer.textureWidth, modelHornRenderer.textureHeight);
      this.quadList[2] = new TexturedQuad(new PositionTextureVertex[] {positiontexturevertex4, positiontexturevertex3, positiontexturevertex7, positiontexturevertex}, textureOffsetX, textureOffsetY, textureOffsetX + 1, textureOffsetY + 1, modelHornRenderer.textureWidth, modelHornRenderer.textureHeight);
      this.quadList[3] = new TexturedQuad(new PositionTextureVertex[] {positiontexturevertex1, positiontexturevertex2, positiontexturevertex6, positiontexturevertex5}, textureOffsetX, textureOffsetY, textureOffsetX + 1, textureOffsetY + 1, modelHornRenderer.textureWidth, modelHornRenderer.textureHeight);
      this.quadList[4] = new TexturedQuad(new PositionTextureVertex[] {positiontexturevertex, positiontexturevertex7, positiontexturevertex2, positiontexturevertex1}, textureOffsetX, textureOffsetY, textureOffsetX + 1, textureOffsetY + 1, modelHornRenderer.textureWidth, modelHornRenderer.textureHeight);
      this.quadList[5] = new TexturedQuad(new PositionTextureVertex[] {positiontexturevertex3, positiontexturevertex4, positiontexturevertex5, positiontexturevertex6}, textureOffsetX, textureOffsetY, textureOffsetX + 1, textureOffsetY + 1, modelHornRenderer.textureWidth, modelHornRenderer.textureHeight);
    
  }

  public void render(WorldRenderer renderer, float scale) {
    for (int i = 0; i < this.quadList.length; ++i)
    {
        this.quadList[i].draw(renderer, scale);
    }
    
  }



}

I do pony stuff :3

Link to comment
Share on other sites

Fixed it.

 

Note to future self - on some systems, this.drawGradientRect(-25,-25,25,50, 1996488704, 1996488704) (drawing the black box on the background of the pony) does NOT reset the draw color to white when it finishes. Needed to add:

this.drawGradientRect(-25,-25,25,50, 1996488704, 1996488704);
GlStateManager.color(1, 1, 1, 1);

 

 

Case closed

I do pony stuff :3

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.

Announcements



×
×
  • Create New...

Important Information

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