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}