001    package net.minecraft.client.model;
002    
003    import cpw.mods.fml.relauncher.Side;
004    import cpw.mods.fml.relauncher.SideOnly;
005    import java.util.ArrayList;
006    import java.util.List;
007    import net.minecraft.client.renderer.GLAllocation;
008    import net.minecraft.client.renderer.Tessellator;
009    import org.lwjgl.opengl.GL11;
010    
011    public 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 var8 = this.baseModel.getTextureOffset(par1Str);
098            this.setTextureOffset(var8.textureOffsetX, var8.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 var2;
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 (var2 = 0; var2 < this.childModels.size(); ++var2)
148                                {
149                                    ((ModelRenderer)this.childModels.get(var2)).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 (var2 = 0; var2 < this.childModels.size(); ++var2)
161                                {
162                                    ((ModelRenderer)this.childModels.get(var2)).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 (var2 = 0; var2 < this.childModels.size(); ++var2)
194                            {
195                                ((ModelRenderer)this.childModels.get(var2)).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 var2 = Tessellator.instance;
297    
298            for (int var3 = 0; var3 < this.cubeList.size(); ++var3)
299            {
300                ((ModelBox)this.cubeList.get(var3)).render(var2, 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    }