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 }