    001package net.minecraft.client.model;
    002
    003import cpw.mods.fml.relauncher.Side;
    004import cpw.mods.fml.relauncher.SideOnly;
    005import java.util.ArrayList;
    006import java.util.List;
    007import net.minecraft.client.renderer.GLAllocation;
    008import net.minecraft.client.renderer.Tessellator;
    009import org.lwjgl.opengl.GL11;
    010
    011public class ModelRenderer
    012{
    013    /** The size of the texture file's width in pixels. */
    014    public float textureWidth;
    015
    016    /** The size of the texture file's height in pixels. */
    017    public float textureHeight;
    018
    019    /** The X offset into the texture used for displaying this model */
    020    private int textureOffsetX;
    021
    022    /** The Y offset into the texture used for displaying this model */
    023    private int textureOffsetY;
    024    public float rotationPointX;
    025    public float rotationPointY;
    026    public float rotationPointZ;
    027    public float rotateAngleX;
    028    public float rotateAngleY;
    029    public float rotateAngleZ;
    030    private boolean compiled;
    031
    032    /** The GL display list rendered by the Tessellator for this model */
    033    private int displayList;
    034    public boolean mirror;
    035    public boolean showModel;
    036
    037    /** Hides the model. */
    038    public boolean isHidden;
    039    public List cubeList;
    040    public List childModels;
    041    public final String boxName;
    042    private ModelBase baseModel;
    043    public float field_82906_o;
    044    public float field_82908_p;
    045    public float field_82907_q;
    046
    047    public ModelRenderer(ModelBase par1ModelBase, String par2Str)
    048    {
    049        this.textureWidth = 64.0F;
    050        this.textureHeight = 32.0F;
    051        this.compiled = false;
    052        this.displayList = 0;
    053        this.mirror = false;
    054        this.showModel = true;
    055        this.isHidden = false;
    056        this.cubeList = new ArrayList();
    057        this.baseModel = par1ModelBase;
    058        par1ModelBase.boxList.add(this);
    059        this.boxName = par2Str;
    060        this.setTextureSize(par1ModelBase.textureWidth, par1ModelBase.textureHeight);
    061    }
    062
    063    public ModelRenderer(ModelBase par1ModelBase)
    064    {
    065        this(par1ModelBase, (String)null);
    066    }
    067
    068    public ModelRenderer(ModelBase par1ModelBase, int par2, int par3)
    069    {
    070        this(par1ModelBase);
    071        this.setTextureOffset(par2, par3);
    072    }
    073
    074    /**
    075     * Sets the current box's rotation points and rotation angles to another box.
    076     */
    077    public void addChild(ModelRenderer par1ModelRenderer)
    078    {
    079        if (this.childModels == null)
    080        {
    081            this.childModels = new ArrayList();
    082        }
    083
    084        this.childModels.add(par1ModelRenderer);
    085    }
    086
    087    public ModelRenderer setTextureOffset(int par1, int par2)
    088    {
    089        this.textureOffsetX = par1;
    090        this.textureOffsetY = par2;
    091        return this;
    092    }
    093
    094    public ModelRenderer addBox(String par1Str, float par2, float par3, float par4, int par5, int par6, int par7)
    095    {
    096        par1Str = this.boxName + "." + par1Str;
    097        TextureOffset textureoffset = this.baseModel.getTextureOffset(par1Str);
    098        this.setTextureOffset(textureoffset.textureOffsetX, textureoffset.textureOffsetY);
    099        this.cubeList.add((new ModelBox(this, this.textureOffsetX, this.textureOffsetY, par2, par3, par4, par5, par6, par7, 0.0F)).func_78244_a(par1Str));
    100        return this;
    101    }
    102
    103    public ModelRenderer addBox(float par1, float par2, float par3, int par4, int par5, int par6)
    104    {
    105        this.cubeList.add(new ModelBox(this, this.textureOffsetX, this.textureOffsetY, par1, par2, par3, par4, par5, par6, 0.0F));
    106        return this;
    107    }
    108
    109    /**
    110     * Creates a textured box. Args: originX, originY, originZ, width, height, depth, scaleFactor.
    111     */
    112    public void addBox(float par1, float par2, float par3, int par4, int par5, int par6, float par7)
    113    {
    114        this.cubeList.add(new ModelBox(this, this.textureOffsetX, this.textureOffsetY, par1, par2, par3, par4, par5, par6, par7));
    115    }
    116
    117    public void setRotationPoint(float par1, float par2, float par3)
    118    {
    119        this.rotationPointX = par1;
    120        this.rotationPointY = par2;
    121        this.rotationPointZ = par3;
    122    }
    123
    124    @SideOnly(Side.CLIENT)
    125    public void render(float par1)
    126    {
    127        if (!this.isHidden)
    128        {
    129            if (this.showModel)
    130            {
    131                if (!this.compiled)
    132                {
    133                    this.compileDisplayList(par1);
    134                }
    135
    136                GL11.glTranslatef(this.field_82906_o, this.field_82908_p, this.field_82907_q);
    137                int i;
    138
    139                if (this.rotateAngleX == 0.0F && this.rotateAngleY == 0.0F && this.rotateAngleZ == 0.0F)
    140                {
    141                    if (this.rotationPointX == 0.0F && this.rotationPointY == 0.0F && this.rotationPointZ == 0.0F)
    142                    {
    143                        GL11.glCallList(this.displayList);
    144
    145                        if (this.childModels != null)
    146                        {
    147                            for (i = 0; i < this.childModels.size(); ++i)
    148                            {
    149                                ((ModelRenderer)this.childModels.get(i)).render(par1);
    150                            }
    151                        }
    152                    }
    153                    else
    154                    {
    155                        GL11.glTranslatef(this.rotationPointX * par1, this.rotationPointY * par1, this.rotationPointZ * par1);
    156                        GL11.glCallList(this.displayList);
    157
    158                        if (this.childModels != null)
    159                        {
    160                            for (i = 0; i < this.childModels.size(); ++i)
    161                            {
    162                                ((ModelRenderer)this.childModels.get(i)).render(par1);
    163                            }
    164                        }
    165
    166                        GL11.glTranslatef(-this.rotationPointX * par1, -this.rotationPointY * par1, -this.rotationPointZ * par1);
    167                    }
    168                }
    169                else
    170                {
    171                    GL11.glPushMatrix();
    172                    GL11.glTranslatef(this.rotationPointX * par1, this.rotationPointY * par1, this.rotationPointZ * par1);
    173
    174                    if (this.rotateAngleZ != 0.0F)
    175                    {
    176                        GL11.glRotatef(this.rotateAngleZ * (180F / (float)Math.PI), 0.0F, 0.0F, 1.0F);
    177                    }
    178
    179                    if (this.rotateAngleY != 0.0F)
    180                    {
    181                        GL11.glRotatef(this.rotateAngleY * (180F / (float)Math.PI), 0.0F, 1.0F, 0.0F);
    182                    }
    183
    184                    if (this.rotateAngleX != 0.0F)
    185                    {
    186                        GL11.glRotatef(this.rotateAngleX * (180F / (float)Math.PI), 1.0F, 0.0F, 0.0F);
    187                    }
    188
    189                    GL11.glCallList(this.displayList);
    190
    191                    if (this.childModels != null)
    192                    {
    193                        for (i = 0; i < this.childModels.size(); ++i)
    194                        {
    195                            ((ModelRenderer)this.childModels.get(i)).render(par1);
    196                        }
    197                    }
    198
    199                    GL11.glPopMatrix();
    200                }
    201
    202                GL11.glTranslatef(-this.field_82906_o, -this.field_82908_p, -this.field_82907_q);
    203            }
    204        }
    205    }
    206
    207    @SideOnly(Side.CLIENT)
    208    public void renderWithRotation(float par1)
    209    {
    210        if (!this.isHidden)
    211        {
    212            if (this.showModel)
    213            {
    214                if (!this.compiled)
    215                {
    216                    this.compileDisplayList(par1);
    217                }
    218
    219                GL11.glPushMatrix();
    220                GL11.glTranslatef(this.rotationPointX * par1, this.rotationPointY * par1, this.rotationPointZ * par1);
    221
    222                if (this.rotateAngleY != 0.0F)
    223                {
    224                    GL11.glRotatef(this.rotateAngleY * (180F / (float)Math.PI), 0.0F, 1.0F, 0.0F);
    225                }
    226
    227                if (this.rotateAngleX != 0.0F)
    228                {
    229                    GL11.glRotatef(this.rotateAngleX * (180F / (float)Math.PI), 1.0F, 0.0F, 0.0F);
    230                }
    231
    232                if (this.rotateAngleZ != 0.0F)
    233                {
    234                    GL11.glRotatef(this.rotateAngleZ * (180F / (float)Math.PI), 0.0F, 0.0F, 1.0F);
    235                }
    236
    237                GL11.glCallList(this.displayList);
    238                GL11.glPopMatrix();
    239            }
    240        }
    241    }
    242
    243    /**
    244     * Allows the changing of Angles after a box has been rendered
    245     */
    246    @SideOnly(Side.CLIENT)
    247    public void postRender(float par1)
    248    {
    249        if (!this.isHidden)
    250        {
    251            if (this.showModel)
    252            {
    253                if (!this.compiled)
    254                {
    255                    this.compileDisplayList(par1);
    256                }
    257
    258                if (this.rotateAngleX == 0.0F && this.rotateAngleY == 0.0F && this.rotateAngleZ == 0.0F)
    259                {
    260                    if (this.rotationPointX != 0.0F || this.rotationPointY != 0.0F || this.rotationPointZ != 0.0F)
    261                    {
    262                        GL11.glTranslatef(this.rotationPointX * par1, this.rotationPointY * par1, this.rotationPointZ * par1);
    263                    }
    264                }
    265                else
    266                {
    267                    GL11.glTranslatef(this.rotationPointX * par1, this.rotationPointY * par1, this.rotationPointZ * par1);
    268
    269                    if (this.rotateAngleZ != 0.0F)
    270                    {
    271                        GL11.glRotatef(this.rotateAngleZ * (180F / (float)Math.PI), 0.0F, 0.0F, 1.0F);
    272                    }
    273
    274                    if (this.rotateAngleY != 0.0F)
    275                    {
    276                        GL11.glRotatef(this.rotateAngleY * (180F / (float)Math.PI), 0.0F, 1.0F, 0.0F);
    277                    }
    278
    279                    if (this.rotateAngleX != 0.0F)
    280                    {
    281                        GL11.glRotatef(this.rotateAngleX * (180F / (float)Math.PI), 1.0F, 0.0F, 0.0F);
    282                    }
    283                }
    284            }
    285        }
    286    }
    287
    288    /**
    289     * Compiles a GL display list for this model
    290     */
    291    @SideOnly(Side.CLIENT)
    292    private void compileDisplayList(float par1)
    293    {
    294        this.displayList = GLAllocation.generateDisplayLists(1);
    295        GL11.glNewList(this.displayList, GL11.GL_COMPILE);
    296        Tessellator tessellator = Tessellator.instance;
    297
    298        for (int i = 0; i < this.cubeList.size(); ++i)
    299        {
    300            ((ModelBox)this.cubeList.get(i)).render(tessellator, par1);
    301        }
    302
    303        GL11.glEndList();
    304        this.compiled = true;
    305    }
    306
    307    /**
    308     * Returns the model renderer with the new texture parameters.
    309     */
    310    public ModelRenderer setTextureSize(int par1, int par2)
    311    {
    312        this.textureWidth = (float)par1;
    313        this.textureHeight = (float)par2;
    314        return this;
    315    }
    316}