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 }