diff options
author | Peter Wu <lekensteyn@gmail.com> | 2013-11-29 00:33:48 +0100 |
---|---|---|
committer | Peter Wu <lekensteyn@gmail.com> | 2013-11-29 00:33:48 +0100 |
commit | a94168139e5ce62db34ee7ed49dd72e2dd7fb1de (patch) | |
tree | e9ef0c60515588ec2d51ddaf6b84c93acd92f9f7 | |
parent | 7ed27ca34095447fa570c84e41c25e295f54dd31 (diff) | |
download | 2iv60-robots-a94168139e5ce62db34ee7ed49dd72e2dd7fb1de.tar.gz |
Refactor: move Robot outside RobotRace class
setColor is unused now as it is moved to BaseContext.
-rw-r--r-- | src/Robot.java | 285 | ||||
-rw-r--r-- | src/RobotRace.java | 282 |
2 files changed, 285 insertions, 282 deletions
diff --git a/src/Robot.java b/src/Robot.java new file mode 100644 index 0000000..ca2622b --- /dev/null +++ b/src/Robot.java @@ -0,0 +1,285 @@ + +import java.awt.Color; +import javax.media.opengl.GL; +import static javax.media.opengl.GL2.*; +import javax.media.opengl.fixedfunc.GLLightingFunc; + +/** + * Represents a Robot, to be implemented according to the Assignments. + */ +class Robot extends BetterBase { + private final Color boneColor = Colors.CHOCOLATE; + + /** The material from which this robot is built. */ + private final Material material; + + /** Relative lengths, widths and heights of robot model. */ + private final float torsoHeight; + private final float torsoWidth; + private final float shoulderRadius; + private final float armLength; + private final float legLength; + private final float armWidth; + private final float legWidth; + private final float neckHeight; + private final float headRadius; + private final float depth; + private final float footWidth; + private final float footHeight; + private final float footLength; + /** Size of the bone for stick figures. */ + private final float boneSize; + + /** + * True if a skeleton should be drawn instead of a full body. + */ + private boolean asStickFigure; + + /** + * Constructs the robot with initial parameters. + */ + public Robot(Material material) { + /* Set all parameters of the robot */ + this.material = material; + this.torsoHeight = 0.6f; + this.torsoWidth = 0.48f; + this.shoulderRadius = 0.09f; + this.armLength = 0.6f; + this.armWidth = 0.06f; + this.legLength = 0.78f; + this.legWidth = 0.06f; + this.neckHeight = 0.15f; + this.headRadius = 0.12f; + this.footWidth = legWidth; + this.footHeight = legWidth; + this.footLength = 2 * legWidth; + this.boneSize = 0.02f; + this.depth = 0.24f; + } + + /** + * Draws this robot (as a {@code stickfigure} if specified). + */ + public void draw(boolean stickFigure) { + this.asStickFigure = stickFigure; + // as the components are drawn with the torso as center, move it up + gl.glPushMatrix(); + gl.glTranslatef(0, 0, torsoHeight / 2 + legLength); + + // These materials control the reflected light + gl.glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material.diffuse, 0); + gl.glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material.specular, 0); + + gl.glTranslatef(0, 0, footHeight); + + // Draw the robot, everything is relative to the center of torso. + // Static parts: + drawTorso(); + drawHead(); + // only draw the circles in normal, full body mode + if (!asStickFigure) { + drawShoulderTop(); + } + + // Parts that should be animated: + // draw left and right legs + drawLeg(false); + drawLeg(true); + // draw left and right arms + drawArm(false); + drawArm(true); + + // restore position + gl.glPopMatrix(); + } + + /** + * Draws a 3d figure with given dimensions and color. If a stick figure + * must be drawn, then the figure will become a thin line in the X, Y + * or Z direction depending on the direction parameter. + * @param dir Direction of the line segment, relevant for stick figures. + * @param color If non-null, it becomes the color for this beam. Ignored + * when drawing a stick figure, in that case the boneColor constant will + * be used. + */ + private void drawBeam(float x, float y, float z, Direction dir, Color color) { + if (asStickFigure) { + // for a stick figure, draw a thin figure without colors + switch (dir) { + case X: + assert x != 0; + y = z = boneSize; + break; + case Y: + assert y != 0; + x = z = boneSize; + break; + case Z: + assert z != 0; + x = y = boneSize; + break; + default: + throw new AssertionError(dir.name()); + } + // stick figures always get a "bone" color + setColor(boneColor); + } else { + assert x != 0; + assert y != 0; + assert z != 0; + if (color != null) { + setColor(color); + } + } + gl.glScalef(x, y, z); + glut.glutSolidCube(1); + // return to previous scales + gl.glScalef(1 / x, 1 / y, 1 / z); + } + + /** + * Draws a joint for stick figure model. + */ + private void drawJoint() { + if (asStickFigure) { + glut.glutSolidSphere(boneSize * 1.5, 10, 10); + } + } + + /** + * Draws the torso of the robot. + */ + private void drawTorso() { + // Scale the torso to specified values + drawBeam(torsoWidth, depth, torsoHeight, Direction.Z, Color.LIGHT_GRAY); + + if (asStickFigure) { + // draw the bone connecting the arms (visible for stick figure) + gl.glTranslatef(0, 0, torsoHeight / 2); + drawBeam(torsoWidth + armWidth * 3, boneSize, boneSize, Direction.X, null); + + gl.glTranslatef(0, 0, -torsoHeight); + // draw the bone connecting the legs (visible for stick figure) + drawBeam(.5f * torsoWidth + legWidth / 2, boneSize, boneSize, Direction.X, null); + + // return to torso center + gl.glTranslatef(0, 0, torsoHeight / 2); + } + } + + /** + * Draws both shoulders of the robot. + */ + private void drawShoulderTop() { + // save position + gl.glPushMatrix(); + + float shoulder_x = torsoWidth / 2 + shoulderRadius / 1.5f; + // Translate to the left of the robot for left shoulder + gl.glTranslatef(shoulder_x, 0f, torsoHeight / 2); + + setColor(Colors.BLUEISH); + + // Set the drawing color and draw right shoulder + glut.glutSolidSphere(shoulderRadius, 10, 10); + // left shoulder + gl.glTranslatef(-2 * shoulder_x, 0, 0); + glut.glutSolidSphere(shoulderRadius, 10, 10); + + // restore position + gl.glPopMatrix(); + } + + /** + * Draws the upper and lower legs and feet of the robot. + * @param isRight True if at the robot's right (from the robot POV). + */ + private void drawLeg(boolean isRight) { + // save center position + gl.glPushMatrix(); + + // The legs are located on the first and third quarter + float leg_top_x = -torsoWidth / 4; + if (!isRight) { + leg_top_x += torsoWidth / 2; + } + gl.glTranslatef(leg_top_x, 0f, -torsoHeight / 2); + drawJoint(); + + // upper leg half + gl.glTranslatef(0, 0, -legLength / 4); + drawBeam(legWidth, legWidth, legLength / 2, Direction.Z, Color.DARK_GRAY); + + // knee + gl.glTranslatef(0, 0, -legLength / 4); + drawJoint(); + + // lower leg half + gl.glTranslatef(0, 0, -legLength / 4); + drawBeam(legWidth, legWidth, legLength / 2, Direction.Z, Color.DARK_GRAY); + + // draw feet! + if (!asStickFigure) { + gl.glTranslatef(0, legWidth / 2, -legLength / 4 - footHeight / 2); + drawBeam(footWidth, footLength, footHeight, Direction.Y, Colors.GRAYISH); + } + + // Restore position + gl.glPopMatrix(); + } + + /** + * Draw both arms and both hands of the robot. + * @param isRight True if at the robot's right (from the robot POV). + */ + private void drawArm(boolean isRight) { + // Push the translation matrix so we can return to the origin + gl.glPushMatrix(); + + // the arm is located outside the torso + float arm_x = torsoWidth / 2 + armWidth * 1.5f; + if (isRight) { + arm_x *= -1; + } + // arm starts next to the shoulder let's add a joint there... + gl.glTranslatef(arm_x, 0, torsoHeight / 2); + drawJoint(); + + // here is your arm (start drawing from the elbow) + gl.glTranslatef(0, 0, -armLength / 2); + drawBeam(armWidth, armWidth, armLength, Direction.Z, Colors.ARM_GRAY_COLOR); + + if (!asStickFigure) { + // Give me a big hand! + setColor(Colors.DIRTY_BLUE); + gl.glTranslatef(0f, 0f, -armLength / 2); + glut.glutSolidSphere(armWidth * 1.25f, 10, 10); + } + + gl.glPopMatrix(); + } + + /** + * Draw the head and the neck of the robot. + */ + private void drawHead() { + // Push matrix so we can go to the origin afterwards + gl.glPushMatrix(); + + // position centered above the torso for the neck + gl.glTranslatef(0f, 0f, torsoHeight / 2 + neckHeight / 2); + float neckRadius = headRadius / 2.5f; + drawBeam(neckRadius, neckRadius, neckHeight, Direction.Z, Colors.LAVENDER); + + // continue moving to the center of the head + gl.glTranslatef(0f, 0f, neckHeight / 2 + headRadius / 2); + + // Set color and draw head + setColor(asStickFigure ? boneColor : Colors.PALE_TURQOISE); + glut.glutSolidSphere(headRadius, 10, 10); + + // Pop so we are at the origin again + gl.glPopMatrix(); + } + +} diff --git a/src/RobotRace.java b/src/RobotRace.java index 9575c56..f064de8 100644 --- a/src/RobotRace.java +++ b/src/RobotRace.java @@ -337,288 +337,6 @@ public class RobotRace extends Base { } } - /** - * Utility method to set color. - * @param color An AWT color. - */ - private void setColor(Color color) { - // contains four RGBA color components (floats in range 0 to 1) - float[] rgba = color.getRGBComponents(null); - gl.glColor3fv(rgba, 0); - } - - /** - * Represents a Robot, to be implemented according to the Assignments. - */ - private class Robot { - private final Color boneColor = Colors.CHOCOLATE; - - /** The material from which this robot is built. */ - private final Material material; - - /** Relative lengths, widths and heights of robot model. */ - private final float torsoHeight, torsoWidth, shoulderRadius, armLength, - legLength, armWidth, legWidth, neckHeight, headRadius, depth, - footWidth, footHeight, footLength; - - /** Size of the bone for stick figures. */ - private final float boneSize; - - /** - * True if a skeleton should be drawn instead of a full body. - */ - private boolean asStickFigure; - - /** - * Constructs the robot with initial parameters. - */ - public Robot(Material material) { - /* Set all parameters of the robot */ - this.material = material; - this.torsoHeight = 0.6f; - this.torsoWidth = 0.48f; - this.shoulderRadius = 0.09f; - this.armLength = 0.6f; - this.armWidth = 0.06f; - this.legLength = 0.78f; - this.legWidth = 0.06f; - this.neckHeight = 0.15f; - this.headRadius = 0.12f; - this.footWidth = legWidth; - this.footHeight = legWidth; - this.footLength = 2 * legWidth; - this.boneSize = 0.02f; - this.depth = 0.24f; - } - - /** - * Draws this robot (as a {@code stickfigure} if specified). - */ - public void draw(boolean stickFigure) { - this.asStickFigure = stickFigure; - // as the components are drawn with the torso as center, move it up - gl.glPushMatrix(); - gl.glTranslatef(0, 0, torsoHeight / 2 + legLength); - - // These materials control the reflected light - gl.glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material.diffuse, 0); - gl.glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material.specular, 0); - - gl.glTranslatef(0, 0, footHeight); - - // Draw the robot, everything is relative to the center of torso. - // Static parts: - drawTorso(); - drawHead(); - // only draw the circles in normal, full body mode - if (!asStickFigure) { - drawShoulderTop(); - } - - // Parts that should be animated: - // draw left and right legs - drawLeg(false); - drawLeg(true); - // draw left and right arms - drawArm(false); - drawArm(true); - - // restore position - gl.glPopMatrix(); - } - - /** - * Draws a 3d figure with given dimensions and color. If a stick figure - * must be drawn, then the figure will become a thin line in the X, Y - * or Z direction depending on the direction parameter. - * @param dir Direction of the line segment, relevant for stick figures. - * @param color If non-null, it becomes the color for this beam. Ignored - * when drawing a stick figure, in that case the boneColor constant will - * be used. - */ - private void drawBeam(float x, float y, float z, Direction dir, Color color) { - if (asStickFigure) { - // for a stick figure, draw a thin figure without colors - switch (dir) { - case X: - assert x != 0; - y = z = boneSize; - break; - case Y: - assert y != 0; - x = z = boneSize; - break; - case Z: - assert z != 0; - x = y = boneSize; - break; - default: - throw new AssertionError(dir.name()); - } - // stick figures always get a "bone" color - setColor(boneColor); - } else { - assert x != 0; - assert y != 0; - assert z != 0; - if (color != null) { - setColor(color); - } - } - gl.glScalef(x, y, z); - glut.glutSolidCube(1); - // return to previous scales - gl.glScalef(1 / x, 1 / y, 1 / z); - } - - /** - * Draws a joint for stick figure model. - */ - private void drawJoint() { - if (asStickFigure) { - glut.glutSolidSphere(boneSize * 1.5, 10, 10); - } - } - - /** - * Draws the torso of the robot. - */ - private void drawTorso() { - // Scale the torso to specified values - drawBeam(torsoWidth, depth, torsoHeight, Direction.Z, Color.LIGHT_GRAY); - - if (asStickFigure) { - // draw the bone connecting the arms (visible for stick figure) - gl.glTranslatef(0, 0, torsoHeight / 2); - drawBeam(torsoWidth + armWidth * 3, boneSize, boneSize, Direction.X, null); - - gl.glTranslatef(0, 0, -torsoHeight); - // draw the bone connecting the legs (visible for stick figure) - drawBeam(.5f * torsoWidth + legWidth / 2, boneSize, boneSize, Direction.X, null); - - // return to torso center - gl.glTranslatef(0, 0, torsoHeight / 2); - } - } - - /** - * Draws both shoulders of the robot. - */ - private void drawShoulderTop() { - // save position - gl.glPushMatrix(); - - float shoulder_x = torsoWidth / 2 + shoulderRadius / 1.5f; - // Translate to the left of the robot for left shoulder - gl.glTranslatef(shoulder_x, 0f, torsoHeight / 2); - - setColor(Colors.BLUEISH); - - // Set the drawing color and draw right shoulder - glut.glutSolidSphere(shoulderRadius, 10, 10); - // left shoulder - gl.glTranslatef(-2 * shoulder_x, 0, 0); - glut.glutSolidSphere(shoulderRadius, 10, 10); - - // restore position - gl.glPopMatrix(); - } - - /** - * Draws the upper and lower legs and feet of the robot. - * @param isRight True if at the robot's right (from the robot POV). - */ - private void drawLeg(boolean isRight) { - // save center position - gl.glPushMatrix(); - - // The legs are located on the first and third quarter - float leg_top_x = -torsoWidth / 4; - if (!isRight) { - leg_top_x += torsoWidth / 2; - } - gl.glTranslatef(leg_top_x, 0f, -torsoHeight / 2); - drawJoint(); - - // upper leg half - gl.glTranslatef(0, 0, -legLength / 4); - drawBeam(legWidth, legWidth, legLength / 2, Direction.Z, Color.DARK_GRAY); - - // knee - gl.glTranslatef(0, 0, -legLength / 4); - drawJoint(); - - // lower leg half - gl.glTranslatef(0, 0, -legLength / 4); - drawBeam(legWidth, legWidth, legLength / 2, Direction.Z, Color.DARK_GRAY); - - // draw feet! - if (!asStickFigure) { - gl.glTranslatef(0, legWidth / 2, -legLength / 4 - footHeight / 2); - drawBeam(footWidth, footLength, footHeight, Direction.Y, Colors.GRAYISH); - } - - // Restore position - gl.glPopMatrix(); - } - - /** - * Draw both arms and both hands of the robot. - * @param isRight True if at the robot's right (from the robot POV). - */ - private void drawArm(boolean isRight) { - // Push the translation matrix so we can return to the origin - gl.glPushMatrix(); - - // the arm is located outside the torso - float arm_x = torsoWidth / 2 + armWidth * 1.5f; - if (isRight) { - arm_x *= -1; - } - // arm starts next to the shoulder let's add a joint there... - gl.glTranslatef(arm_x, 0, torsoHeight / 2); - drawJoint(); - - // here is your arm (start drawing from the elbow) - gl.glTranslatef(0, 0, - armLength / 2); - drawBeam(armWidth, armWidth, armLength, Direction.Z, Colors.ARM_GRAY_COLOR); - - if (!asStickFigure) { - // Give me a big hand! - setColor(Colors.DIRTY_BLUE); - gl.glTranslatef(0f, 0f, - armLength / 2); - glut.glutSolidSphere(armWidth * 1.25f, 10, 10); - } - - gl.glPopMatrix(); - } - - /** - * Draw the head and the neck of the robot. - */ - private void drawHead() { - // Push matrix so we can go to the origin afterwards - gl.glPushMatrix(); - - // position centered above the torso for the neck - gl.glTranslatef(0f, 0f, torsoHeight / 2 + neckHeight / 2); - float neckRadius = headRadius / 2.5f; - drawBeam(neckRadius, neckRadius, neckHeight, Direction.Z, Colors.LAVENDER); - - // continue moving to the center of the head - gl.glTranslatef(0f, 0f, neckHeight / 2 + headRadius / 2); - - // Set color and draw head - setColor(asStickFigure ? boneColor : Colors.PALE_TURQOISE); - glut.glutSolidSphere(headRadius, 10, 10); - - // Pop so we are at the origin again - gl.glPopMatrix(); - } - - } - - /** * Implementation of a camera with a position and orientation. */ private class Camera { |