001    package rendering;
002    
003    import java.util.ArrayList;
004    import java.util.Iterator;
005    import java.util.List;
006    
007    import javax.media.opengl.GL;
008    import javax.media.opengl.GLAutoDrawable;
009    import javax.media.opengl.glu.GLU;
010    import javax.media.opengl.glu.GLUquadric;
011    
012    import com.sun.opengl.util.texture.Texture;
013    
014    import physics3d.Angle;
015    import physics3d.GameConstants;
016    import physics3d.LateralCylinder;
017    import physics3d.PhysicsShape;
018    import physics3d.PlaneCircle;
019    import physics3d.PlanePolygon;
020    import physics3d.Sphere;
021    import physics3d.Vect3;
022    
023    public abstract class ShapeRenderer {
024            
025            protected GLU glu;
026            
027            //constants
028            protected final int SLICES = 20;        
029            protected final int STACKS = 20;        
030            protected final int LOOPS = 20;
031            
032            public ShapeRenderer() {
033                    glu = new GLU();
034            }
035            
036            /**
037             * @requires ps (instance of LateralCylinder)
038             */
039            protected void drawLateralCylinder(GLAutoDrawable drawable, Vect3 center, Vect3 orientVect, Angle orientAngle, PhysicsShape ps, Texture t) {
040                    // castes ps into a Lateral Cylinder 
041                    LateralCylinder lc = (LateralCylinder) ps;
042                    
043                    //if it's of zero radius, don't even draw it
044                    if (lc.getRadius() == 0) {
045                            return;
046                    }
047                    //gets data from it
048                    double height = Math.sqrt(lc.getBottomCenter().times(GameConstants.L).distanceSquared(lc.getTopCenter().times(GameConstants.L)));
049                    double radius = lc.getRadius() * GameConstants.L;
050                    Vect3 cylCenter = lc.getBottomCenter().times(GameConstants.L);
051                    Vect3 normal = lc.getDirection();
052                    Vect3 cylOrientVect;
053                    Angle cylOrientAngle;
054                    
055                    if (normal.equals(Vect3.Z_HAT.neg())) {
056                            cylOrientVect = Vect3.X_HAT;
057                            cylOrientAngle = Angle.DEG_180;
058                    } else {
059                            cylOrientVect = Vect3.Z_HAT.cross(normal);
060                            cylOrientAngle = normal.theta();        
061                    }
062                                    
063                    //gets gl and draws
064                    GL gl = drawable.getGL();
065                    GLUquadric quadric = glu.gluNewQuadric(); 
066            
067                    //gl.glEnable(GL.GL_TEXTURE_2D);
068                    //t.bind();
069                    enableTexture(t, gl);
070                    
071                    gl.glPushMatrix();
072                    
073                    //go to origin of object coordinates
074                    gl.glTranslated(center.x(), center.y(), center.z());
075                    gl.glRotated(orientAngle.degrees(), orientVect.x(), orientVect.y(), orientVect.z());
076                    
077                    //go to origin of cylinder itself
078                    gl.glTranslated(cylCenter.x(), cylCenter.y(), cylCenter.z());
079                    gl.glRotated(cylOrientAngle.degrees(), cylOrientVect.x(), cylOrientVect.y(), cylOrientVect.z());
080                    
081                    glu.gluQuadricOrientation(quadric, GLU.GLU_OUTSIDE);
082                    glu.gluCylinder(quadric, radius, radius, height, SLICES, STACKS);
083                    
084                    gl.glPopMatrix();
085                    
086                    glu.gluDeleteQuadric(quadric);
087                    gl.glDisable(GL.GL_TEXTURE_2D);
088            }
089            
090            /**
091             * @requires ps (instance of PlaneCircle)
092             */
093            protected void drawPlaneCircle(GLAutoDrawable drawable, Vect3 center, Vect3 orientVect, Angle orientAngle, PhysicsShape ps, Texture t) {
094                    //castes ps into a PlaneCircle
095                    PlaneCircle pc = (PlaneCircle) ps;
096                    
097                    //gets PlaneCircle info
098                    double radius = pc.getRadius() * GameConstants.L;
099                    Vect3 cirCenter = pc.getCenter().times(GameConstants.L);
100                    Vect3 normal = pc.getNormal();
101                    Vect3 cirOrientVect = Vect3.Z_HAT.cross(normal);
102                    Angle cirOrientAngle = normal.theta();
103                    
104                    //gets gl and draws
105                    GL gl = drawable.getGL();
106                    GLUquadric quadric = glu.gluNewQuadric();
107                    
108                    //gl.glEnable(GL.GL_TEXTURE_2D);
109                    //t.bind();
110                    enableTexture(t, gl);
111                    
112                    gl.glPushMatrix();
113                    
114                    //go to object space origin
115                    gl.glTranslated(center.x(), center.y(), center.z());
116                    gl.glRotated(orientAngle.degrees(), orientVect.x(), orientVect.y(), orientVect.z());
117                    
118                    //go to center of circle
119                    gl.glTranslated(cirCenter.x(), cirCenter.y(), cirCenter.z());
120                    gl.glRotated(cirOrientAngle.degrees(), cirOrientVect.x(), cirOrientVect.y(), cirOrientVect.z());
121    
122                    //draws circle
123                    glu.gluQuadricOrientation(quadric, GLU.GLU_OUTSIDE);
124                    glu.gluDisk(quadric, 0, radius, SLICES, LOOPS);
125                    
126                    gl.glPopMatrix();               
127                    glu.gluDeleteQuadric(quadric);
128                    gl.glDisable(GL.GL_TEXTURE_2D);
129            }
130            
131            
132            /**
133             * @requires ps (instance of PlanePolygon)
134             */
135            protected void drawPlanePolygon(GLAutoDrawable drawable, Vect3 center, Vect3 orientVect, Angle orientAngle, PhysicsShape ps, Texture t) {
136                    //castes ps into a PlanePolygon
137                    PlanePolygon pp = (PlanePolygon) ps;
138                    Vect3 normal = pp.getNormal();
139            
140                    //gets gl and draws it
141                    GL gl = drawable.getGL();
142            
143                    enableTexture(t, gl);
144                    
145                    
146                    gl.glPushMatrix();
147                    
148                    gl.glTranslated(center.x(), center.y(), center.z());
149                    gl.glRotated(orientAngle.degrees(), orientVect.x(), orientVect.y(), orientVect.z());
150    
151                    gl.glBegin(GL.GL_POLYGON);
152                    gl.glNormal3d(normal.x(), normal.y(), normal.z());
153                    
154                    Iterator<Vect3> vertices = pp.getVertices();
155                    List<Vect3> vList = new ArrayList<Vect3>();
156                    while(vertices.hasNext()) {
157                            vList.add(vertices.next().times(GameConstants.L));
158                    }
159                    
160                    //arranged this way for texture mapping
161                    if (vList.size() == 3) {
162                            Vect3 v1 = vList.get(0);
163                            gl.glTexCoord2d(0, 0);
164                            gl.glVertex3d(v1.x(), v1.y(), v1.z());
165                            
166                            Vect3 v2 = vList.get(1);
167                            gl.glTexCoord2d(0, 1);
168                            gl.glVertex3d(v2.x(), v2.y(), v2.z());
169                            
170                            Vect3 v3 = vList.get(2);
171                            gl.glTexCoord2d(1, 1);
172                            gl.glVertex3d(v3.x(), v3.y(), v3.z());
173                    }
174                    
175                    else if (vList.size() == 4) {
176                            Vect3 v1 = vList.get(0);
177                            gl.glTexCoord2d(0, 0);
178                            gl.glVertex3d(v1.x(), v1.y(), v1.z());
179                            
180                            Vect3 v2 = vList.get(1);
181                            gl.glTexCoord2d(0, 1);
182                            gl.glVertex3d(v2.x(), v2.y(), v2.z());
183                            
184                            Vect3 v3 = vList.get(2);
185                            gl.glTexCoord2d(1, 1);
186                            gl.glVertex3d(v3.x(), v3.y(), v3.z());
187                            
188                            Vect3 v4 = vList.get(3);
189                            gl.glTexCoord2d(1, 0);
190                            gl.glVertex3d(v4.x(), v4.y(), v4.z());
191                    }
192                    
193                    gl.glEnd();
194                    gl.glPopMatrix();
195                    gl.glDisable(GL.GL_TEXTURE_2D);
196            }
197            
198            /**
199             * @requires ps (instance of Sphere)
200             */
201            protected void drawSphere(GLAutoDrawable drawable, Vect3 center, Vect3 orientVect, Angle orientAngle, PhysicsShape ps, Texture t) {
202                    //castes ps into a Sphere
203                    Sphere s = (Sphere) ps;
204    
205                    //if radius is 0, don't even draw it
206                    if (s.getRadius() == 0) {
207                            return;
208                    }
209                    
210                    double radius = s.getRadius() * GameConstants.L;
211                    Vect3 sphereCenter = s.getCenter().times(GameConstants.L);
212                    
213                    //gets gl and draws it
214                    GL gl = drawable.getGL();
215                    GLUquadric quadric = glu.gluNewQuadric();
216                    
217                    enableTexture(t, gl);
218    
219                    gl.glPushMatrix();
220                    
221                    //new origin in object coordinates
222                    gl.glTranslated(center.x(), center.y(), center.z());
223                    gl.glRotated(orientAngle.degrees(), orientVect.x(), orientVect.y(), orientVect.z());
224                    
225                    //find center of sphere in object coordinates
226                    gl.glTranslated(sphereCenter.x(), sphereCenter.y(), sphereCenter.z());
227    
228                    //draws it
229                    glu.gluQuadricOrientation(quadric, GLU.GLU_OUTSIDE);
230                    glu.gluSphere(quadric, radius, SLICES, STACKS);
231                    
232                    gl.glPopMatrix();
233                    glu.gluDeleteQuadric(quadric);
234                     
235                    gl.glDisable(GL.GL_TEXTURE_2D); 
236            }       
237            private void enableTexture(Texture t, GL gl) {
238                    if (t != null) {
239                            gl.glEnable(GL.GL_TEXTURE_2D);
240                            t.bind();
241                    }
242            }
243    }