package BrickControlGuide; import java.nio.FloatBuffer; import javax.media.opengl.GL2; import javax.media.opengl.glu.GLU; import javax.media.opengl.glu.GLUquadric; import Builder.MainCamera; import Common.Matrix4; import Common.Ray3; import Common.Vector3f; import LDraw.Support.MatrixMath; import com.jogamp.opengl.util.gl2.GLUT; public class RotationGuide extends DefaultGuideRenderer { private GLUT glut; public RotationGuide(GLU glu, GLUT glut) { super.glu = glu; this.glut = glut; } public void drawSphere(GL2 gl2, MainCamera camera, Vector3f orientation) { Vector3f[] vertices = getSphereForTorusVertices(camera, orientation); final float cylinderRadius = camera.getDistanceBetweenObjectToCamera() / 20 / 4f; GLUquadric body = glu.gluNewQuadric(); int slices = 20; int stacks = 10; glu.gluQuadricTexture(body, false); glu.gluQuadricDrawStyle(body, GLU.GLU_FILL); glu.gluQuadricNormals(body, GLU.GLU_FLAT); glu.gluQuadricOrientation(body, GLU.GLU_OUTSIDE); for (int i = 0; i < vertices.length; i++) { gl2.glLoadMatrixf(camera.getModelView(), 0); gl2.glTranslatef(vertices[i].x, vertices[i].y, vertices[i].z); glu.gluSphere(body, cylinderRadius, slices, stacks); } } @Override public void draw(GL2 gl2, MainCamera camera, Vector3f orientation) { if (centerConnector != null) orientation = getCenterPos(); // drawSphere(gl2, camera, orientation); // if (orientation != null) // return; float line_length = camera.getDistanceBetweenObjectToCamera() / 4; gl2.glLoadMatrixf(camera.getModelView(), 0); // draw guide line for the axis gl2.glBegin(GL2.GL_LINES); // draw using triangles gl2.glColor3d(r, g, b); gl2.glVertex3f(orientation.getX(), orientation.getY(), orientation.getZ()); Vector3f endPos = getAxisDirectionVector().scale(line_length).add( orientation); gl2.glVertex3f(endPos.x, endPos.y, endPos.z); gl2.glEnd(); final float cylinderRadius = camera.getDistanceBetweenObjectToCamera() / 40f; int slices = 20; int stacks = 10; gl2.glLoadMatrixf(camera.getModelView(), 0); endPos = getAxisDirectionVector().scale( line_length - cylinderRadius * 2).add(orientation); gl2.glTranslatef(endPos.x, endPos.y, endPos.z); Vector3f unitZVector = new Vector3f(0, 0, 1); Vector3f rotationVector = MatrixMath.V3Cross(unitZVector, getAxisDirectionVector()); float angle = (float) Math.acos(getAxisDirectionVector().dot( unitZVector) / (getAxisDirectionVector().length() * unitZVector.length())); int angleInDegree = Math.round(angle / (float) (Math.PI * 2) * 360); if (rotationVector.length() > 0.1f && Float.isNaN(angle) == false && MatrixMath.compareFloat(angle, 0) != 0) gl2.glRotatef(angleInDegree, rotationVector.x, rotationVector.y, rotationVector.z); else if (rotationVector.length() < 0.1f && angleInDegree == 180) gl2.glRotatef(angleInDegree, 1, 0, 0); glut.glutSolidTorus(cylinderRadius / 2, cylinderRadius, slices, stacks); } private Vector3f[] getSphereForTorusVertices(MainCamera camera, Vector3f orientation) { Vector3f[] vertices = new Vector3f[20]; final float cylinderRadius = camera.getDistanceBetweenObjectToCamera() / 20f; float centerOfTorus = camera.getDistanceBetweenObjectToCamera() / 4f - cylinderRadius; Vector3f endPos = getAxisDirectionVector().scale(centerOfTorus).add( orientation); for (int i = 0; i < vertices.length; i++) vertices[i] = new Vector3f((float) (cylinderRadius / 2 * Math.cos(i * Math.PI * 2 / (vertices.length))), (float) (cylinderRadius / 2 * Math.sin(i * Math.PI * 2 / (vertices.length))), 0); Vector3f unitZVector = new Vector3f(0, 0, 1); Vector3f rotationVector = MatrixMath.V3Cross(unitZVector, getAxisDirectionVector()); float angle = (float) Math.acos(getAxisDirectionVector().dot( unitZVector) / (getAxisDirectionVector().length() * unitZVector.length())); int angleInDegree = Math.round(angle / (float) (Math.PI * 2) * 360); Matrix4 rotationMatrix = Matrix4.getIdentityMatrix4(); if (rotationVector.length() > 0.1f && Float.isNaN(angle) == false && MatrixMath.compareFloat(angle, 0) != 0) rotationMatrix.rotate(-angle, rotationVector); else if (rotationVector.length() < 0.1f && angleInDegree == 180) rotationMatrix.rotate(angle, new Vector3f(1, 0, 0)); for (int i = 0; i < vertices.length; i++) vertices[i] = MatrixMath.V3RotateByTransformMatrix(vertices[i], rotationMatrix).add(endPos); return vertices; } @Override public boolean isHitted(MainCamera camera, Vector3f orientation, float screenX, float screenY, FloatBuffer distance) { if (centerConnector != null) orientation = getCenterPos(); final float cylinderRadius = camera.getDistanceBetweenObjectToCamera() / 20f; Ray3 ray = camera.getRay(screenX, screenY); FloatBuffer distanceTemp = FloatBuffer.allocate(1); boolean isHitted=false; for (Vector3f vertex : getSphereForTorusVertices(camera, orientation)) if (MatrixMath.V3RayIntersectsSphere(ray, vertex, cylinderRadius / 4, distanceTemp)) { if (distanceTemp.get(0) < distance.get(0)) distance.put(0, distanceTemp.get(0)); isHitted=true; } lastHittedDistance = distance.get(0); return isHitted; } @Override public float getLastHittedDistance() { return lastHittedDistance; } }