import java.awt.BorderLayout; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Collections; import javax.media.j3d.Appearance; import javax.media.j3d.BranchGroup; import javax.media.j3d.Canvas3D; import javax.media.j3d.Geometry; import javax.media.j3d.GeometryArray; import javax.media.j3d.GeometryUpdater; import javax.media.j3d.IndexedTriangleArray; import javax.media.j3d.J3DGraphics2D; import javax.media.j3d.Locale; import javax.media.j3d.PolygonAttributes; import javax.media.j3d.RenderingAttributes; import javax.swing.JFrame; import javax.swing.JPanel; import javax.vecmath.Color3f; import org.apache.commons.math3.linear.MatrixUtils; import org.apache.commons.math3.linear.RealMatrix; import org.apache.commons.math3.util.FastMath; import com.sun.j3d.utils.geometry.Text2D; import com.sun.j3d.utils.universe.ConfiguredUniverse; import com.sun.j3d.utils.universe.SimpleUniverse; public class notusingtransform3D { public static void main(String[] args) { System.setProperty("sun.awt.noerasebackground", "true"); new notusingtransform3D(); } float x = 0, y = 0, z = 0, dX = 1, dY = 1, dZ = 1; double rotX = 0, rotY = 0, rotZ = 0, dRotX = 0.05, dRotY = 0.05, dRotZ = 0.05; double zoomScaleX = 1, zoomScaleY = 1; IndexedTriangleArray[] cube_one, cube_two, cube_three; float[] cubePtsRef_one, arrayOfRefs_n_one, cubePtsRef_two, cubePtsRef_three; static int[] cube_idx = { // from // https://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_05 // front 0, 1, 2, 2, 3, 0, // right 1, 5, 6, 6, 2, 1, // back 7, 6, 5, 5, 4, 7, // left 4, 0, 3, 3, 7, 4, // bottom 4, 5, 1, 1, 0, 4, // top 3, 2, 6, 6, 7, 3 }; static float[] cube_colors = { // front colors 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, // back colors 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f }; float[][] cube1_pt = { { -2, +0, -10 }, { -1, +0, -10 }, { -1, +1, -10 }, { -2, +1, -10 }, { -2, +0, -11 }, { -1, +0, -11 }, { -1, +1, -11 }, { -2, +1, -11 } }; float[][] cube2_pt = { { -3, +0, -12 }, { -1, +0, -12 }, { -1, +2, -12 }, { -3, +2, -12 }, { -3, +0, -14 }, { -1, +0, -14 }, { -1, +2, -14 }, { -3, +2, -14 } }; float[][] cube3_pt = { { -2, +0, -15 }, { -1, +0, -15 }, { -1, +3, -15 }, { -2, +3, -15 }, { -2, +0, -17 }, { -1, +0, -17 }, { -1, +3, -17 }, { -2, +3, -17 }, }; static float[][] cube_normals = { { 0, 0, 1 }, { 1, 0, 0 }, { 0, 0, -1 }, { -1, 0, 0 }, { 0, -1, 0 }, { 0, 1, 0 } }; // front, right, back, left, bottom, top int FFTCount = 0; IndexedTriangleArray[] fFT; boolean[] iFF; ArrayList listOfAllFFT; public RealMatrix translationM(double tx, double ty, double tz) { double[][] matrixData = { { 1, 0, 0, tx }, { 0, 1, 0, ty }, { 0, 0, 1, tz }, { 0, 0, 0, 1 } }; RealMatrix mat = MatrixUtils.createRealMatrix(matrixData); return mat; } public RealMatrix rotateX(double fi) { double[][] matrixData = { { 1, 0, 0, 0 }, { 0, FastMath.cos(fi), -FastMath.sin(fi), 0 }, { 0, FastMath.sin(fi), FastMath.cos(fi), 0 }, { 0, 0, 0, 1 } }; RealMatrix mat = MatrixUtils.createRealMatrix(matrixData); return mat; } public RealMatrix rotateY(double fi) { double[][] matrixData = { { FastMath.cos(fi), 0, FastMath.sin(fi), 0 }, { 0, 1, 0, 0 }, { -FastMath.sin(fi), 0, FastMath.cos(fi), 0 }, { 0, 0, 0, 1 } }; RealMatrix mat = MatrixUtils.createRealMatrix(matrixData); return mat; } public RealMatrix rotateZ(double fi) { double[][] matrixData = { { FastMath.cos(fi), -FastMath.sin(fi), 0, 0 }, { FastMath.sin(fi), FastMath.cos(fi), 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } }; RealMatrix mat = MatrixUtils.createRealMatrix(matrixData); return mat; } public RealMatrix scale(double scaleX, double scaleY, double scaleZ) { double[][] matrixData = { { scaleX, 0, 0, 0 }, { 0, scaleY, 0, 0 }, { 0, 0, scaleZ, 0 }, { 0, 0, 0, 1 } }; RealMatrix mat = MatrixUtils.createRealMatrix(matrixData); return mat; } public RealMatrix quaternion(float x, float y, float z, float w) { double[][] quatData = { { x }, { y }, { z }, { w } }; RealMatrix quat = MatrixUtils.createRealMatrix(quatData); return quat; } public void translateArray(float[] cube, float deltaX, float deltaY, float deltaZ) { RealMatrix quat; for (int i = 0; i < 8; i++) { quat = quaternion(cube[i * 3 + 0], cube[i * 3 + 1], cube[i * 3 + 2], 1); quat = quat.preMultiply(translationM(deltaX, deltaY, deltaZ)); cube[i * 3 + 0] = (float) quat.getEntry(0, 0); cube[i * 3 + 1] = (float) quat.getEntry(1, 0); cube[i * 3 + 2] = (float) quat.getEntry(2, 0); } } public void rotateArrayX(float[] cube, double fi) { RealMatrix quat; for (int i = 0; i < 8; i++) { quat = quaternion(cube[i * 3 + 0], cube[i * 3 + 1], cube[i * 3 + 2], 1); quat = quat.preMultiply(rotateX(fi)); cube[i * 3 + 0] = (float) quat.getEntry(0, 0); cube[i * 3 + 1] = (float) quat.getEntry(1, 0); cube[i * 3 + 2] = (float) quat.getEntry(2, 0); } } public void rotateArrayY(float[] cube, double fi) { RealMatrix quat; for (int i = 0; i < 8; i++) { quat = quaternion(cube[i * 3 + 0], cube[i * 3 + 1], cube[i * 3 + 2], 1); quat = quat.preMultiply(rotateY(fi)); cube[i * 3 + 0] = (float) quat.getEntry(0, 0); cube[i * 3 + 1] = (float) quat.getEntry(1, 0); cube[i * 3 + 2] = (float) quat.getEntry(2, 0); } } public void rotateArrayZ(float[] cube, double fi) { RealMatrix quat; for (int i = 0; i < 8; i++) { quat = quaternion(cube[i * 3 + 0], cube[i * 3 + 1], cube[i * 3 + 2], 1); quat = quat.preMultiply(rotateZ(fi)); cube[i * 3 + 0] = (float) quat.getEntry(0, 0); cube[i * 3 + 1] = (float) quat.getEntry(1, 0); cube[i * 3 + 2] = (float) quat.getEntry(2, 0); } } public void zoom(float[] cube, double scaleX, double scaleY, double scaleZ) { RealMatrix quat; for (int i = 0; i < 8; i++) { quat = quaternion(cube[i * 3 + 0], cube[i * 3 + 1], cube[i * 3 + 2], 1); quat = quat.preMultiply(scale(scaleX, scaleY, scaleZ)); cube[i * 3 + 0] = (float) quat.getEntry(0, 0); cube[i * 3 + 1] = (float) quat.getEntry(1, 0); cube[i * 3 + 2] = (float) quat.getEntry(2, 0); } } public static IndexedTriangleArray[] ccr1(float cube_pts[][]) { float[] flat_pts = flatten(cube_pts); float[] flat_normals = flatten(cube_normals); IndexedTriangleArray[] dozenOfSeparateTriangles = new IndexedTriangleArray[12]; for (int i = 0; i < dozenOfSeparateTriangles.length; i++) { IndexedTriangleArray triangleGeometry = new IndexedTriangleArray(3, GeometryArray.COORDINATES | GeometryArray.COLOR_3 | GeometryArray.BY_REFERENCE, 3); triangleGeometry.setCapability(GeometryArray.ALLOW_REF_DATA_WRITE); ccr2(triangleGeometry, flat_pts, flat_normals, i); dozenOfSeparateTriangles[i] = triangleGeometry; } return dozenOfSeparateTriangles; } public static float[] flatten(float cube_pts[][]) { float[] flat_pts = new float[cube_pts.length * 3]; for (int j = 0; j < cube_pts.length; j++) { flat_pts[j * 3 + 0] = cube_pts[j][0]; flat_pts[j * 3 + 1] = cube_pts[j][1]; flat_pts[j * 3 + 2] = cube_pts[j][2]; } return flat_pts; } public static void ccr2(IndexedTriangleArray geom, float flat_pts[], float flat_normals[], int i) { geom.setCoordRefFloat(flat_pts); geom.setCoordinateIndices(0, subsetOf3(cube_idx, i * 3)); geom.setColorRefFloat(cube_colors); geom.setColorIndices(0, subsetOf3(cube_idx, i * 3)); } public static int[] subsetOf3(int[] cubeIndices, int startIndex) { int[] subset = new int[3]; subset[0] = cubeIndices[startIndex]; subset[1] = cubeIndices[startIndex + 1]; subset[2] = cubeIndices[startIndex + 2]; return subset; } public static float[] subsetOf3(float[] points, int startIndex) { float[] subset = new float[3]; subset[0] = points[startIndex]; subset[1] = points[startIndex + 1]; subset[2] = points[startIndex + 2]; return subset; } public float calculateZCenter(float[] p1, float[] p2, float[] p3) { float centerZ = 0; centerZ = (p1[2] + p2[2] + p3[2]) / 3; return centerZ; } public IndexedTriangleArray[] frontFacingTriangles(IndexedTriangleArray[] triangles, boolean[] isFrontFacing) { IndexedTriangleArray[] fFT = new IndexedTriangleArray[FFTCount]; int counter = 0; for (int i = 0; i < triangles.length; i++) { if (isFrontFacing[i]) { fFT[counter] = triangles[i]; counter++; } } return fFT; } public boolean[] isFrontFacing(IndexedTriangleArray[] triangles, float[] ref_to_cube_pts) { FFTCount = 0; boolean[] iFF = new boolean[triangles.length]; float[] normal = new float[3]; for (int i = 0; i < triangles.length; i++) { int[] indices = { 0, 0, 0 }; float[] p1 = { 0, 0, 0 }, p2 = { 0, 0, 0 }, p3 = { 0, 0, 0 }; triangles[i].getCoordinateIndices(0, indices); p1 = subsetOf3(ref_to_cube_pts, indices[0] * 3); p2 = subsetOf3(ref_to_cube_pts, indices[1] * 3); p3 = subsetOf3(ref_to_cube_pts, indices[2] * 3); normal = calculateNormal(p1, p2, p3); if (dotProduct(p1, normal) < 0) { iFF[i] = true; FFTCount++; } else { iFF[i] = false; } } return iFF; } public float[] calculateNormal(float[] p1, float[] p2, float[] p3) { float[] normal = new float[3]; float[] vecA = new float[3]; float[] vecB = new float[3]; for (int i = 0; i < 3; i++) { vecA[i] = p2[i] - p1[i]; vecB[i] = p3[i] - p1[i]; } normal[0] = vecA[1] * vecB[2] - vecA[2] * vecB[1]; normal[1] = vecA[2] * vecB[0] - vecA[0] * vecB[2]; normal[2] = vecA[0] * vecB[1] - vecA[1] * vecB[0]; return normal; } public float dotProduct(float[] p1, float[] n) { float dot = 0; for (int i = 0; i < 3; i++) { dot += p1[i] * n[i]; } return dot; } public void addTTDs(IndexedTriangleArray[] fFT, float[] ref_to_cube_pts) { float zD; for (int i = 0; i < fFT.length; i++) { int[] indices = { 0, 0, 0 }; float[] p1 = { 0, 0, 0 }, p2 = { 0, 0, 0 }, p3 = { 0, 0, 0 }; fFT[i].getCoordinateIndices(0, indices); p1 = subsetOf3(ref_to_cube_pts, indices[0] * 3); p2 = subsetOf3(ref_to_cube_pts, indices[1] * 3); p3 = subsetOf3(ref_to_cube_pts, indices[2] * 3); zD = calculateZCenter(p1, p2, p3); trianglesToDraw TTD = new trianglesToDraw(zD, fFT[i]); listOfAllFFT.add(TTD); } } public void updateDataEmpty(IndexedTriangleArray[] cube, float[] cubePtsRef) { for (int i = 0; i < cube.length; i++) { cube[i].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { } }); } iFF = isFrontFacing(cube, cubePtsRef); fFT = frontFacingTriangles(cube, iFF); addTTDs(fFT, cubePtsRef); } static Appearance app; public notusingtransform3D() { Canvas3D canv = new Canvas3D(ConfiguredUniverse.getPreferredConfiguration()) { // this call is called by the renderer thread and should do a bunch of set // appearance and draw geometry calls public void renderField(int fieldDesc) { getGraphicsContext3D().setAppearance(app); for (trianglesToDraw triangle : listOfAllFFT) { getGraphicsContext3D().draw(triangle.getTriangle()); } // note we might keep using the same appearance, but we could easily swap to // something new; with a texture for example // getGraphicsContext3D().draw(cube_two); // notice that the cube order is now fixed to the order of these draw calls, // nothing in the z order will alter that. } // for fun we can now draw on the rendered image and show details @Override public void postRender() { J3DGraphics2D g = getGraphics2D(); // draw a cross hair g.drawLine((this.getWidth() / 2) - 5, (this.getHeight() / 2), (this.getWidth() / 2) + 5, (this.getHeight() / 2)); g.drawLine((this.getWidth() / 2), (this.getHeight() / 2) - 5, (this.getWidth() / 2), (this.getHeight() / 2) + 5); // Make it show something useful g.drawString("X = " + x + ", Y = " + y + ", Z = " + z, 50, 20); g.drawString("rotX = " + NumberFormat.getNumberInstance().format(rotX) + ", rotY = " + NumberFormat.getNumberInstance().format(rotY) + ", rotZ = " + NumberFormat.getNumberInstance().format(rotZ), 50, 35); g.drawString("zoom = " + NumberFormat.getNumberInstance().format(zoomScaleX), 50, 50); g.flush(false); } }; SimpleUniverse uni = new SimpleUniverse(canv); BranchGroup group = new BranchGroup(); app = new Appearance(); Locale loc = new Locale(uni); listOfAllFFT = new ArrayList(); cube_one = ccr1(cube1_pt); cubePtsRef_one = cube_one[0].getCoordRefFloat(); iFF = isFrontFacing(cube_one, cubePtsRef_one); fFT = frontFacingTriangles(cube_one, iFF); addTTDs(fFT, cubePtsRef_one); cube_two = ccr1(cube2_pt); cubePtsRef_two = cube_two[0].getCoordRefFloat(); iFF = isFrontFacing(cube_two, cubePtsRef_two); fFT = frontFacingTriangles(cube_two, iFF); addTTDs(fFT, cubePtsRef_two); cube_three = ccr1(cube3_pt); cubePtsRef_three = cube_three[0].getCoordRefFloat(); iFF = isFrontFacing(cube_three, cubePtsRef_three); fFT = frontFacingTriangles(cube_three, iFF); addTTDs(fFT, cubePtsRef_three); Collections.sort(listOfAllFFT); // turn off the Z buffer RenderingAttributes ra = new RenderingAttributes(); ra.setDepthBufferEnable(false); app.setRenderingAttributes(ra); // turn off front facing detection (render either side of a triangle) PolygonAttributes pa = new PolygonAttributes(); pa.setCullFace(PolygonAttributes.CULL_NONE); app.setPolygonAttributes(pa); loc.addBranchGraph(group); uni.getCanvas().addKeyListener(new KeyListener() { private void flush() { // https://docs.oracle.com/cd/E17802_01/j2se/javase/technologies/desktop/java3d/forDevelopers/j3dguide/Immediate.doc.html // mixed mode optimizes and waits to be told that the scene has changed, this // call tells it the scene needs to be redrawn, or we could add a behavior canv.getGraphicsContext3D().flush(false); } @Override public void keyTyped(KeyEvent e) { } @Override public void keyReleased(KeyEvent e) { } @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_A) { x -= dX; listOfAllFFT = new ArrayList(); cube_one[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cubePtsRef_one, dX, 0, 0); } }); updateDataEmpty(cube_one, cubePtsRef_one); cube_two[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cubePtsRef_two, dX, 0, 0); } }); updateDataEmpty(cube_two, cubePtsRef_two); cube_three[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cubePtsRef_three, dX, 0, 0); } }); updateDataEmpty(cube_three, cubePtsRef_three); Collections.sort(listOfAllFFT); flush(); } if (e.getKeyCode() == KeyEvent.VK_D) { x += dX; listOfAllFFT = new ArrayList(); cube_one[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cubePtsRef_one, -dX, 0, 0); } }); updateDataEmpty(cube_one, cubePtsRef_one); cube_two[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cubePtsRef_two, -dX, 0, 0); } }); updateDataEmpty(cube_two, cubePtsRef_two); cube_three[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cubePtsRef_three, -dX, 0, 0); } }); updateDataEmpty(cube_three, cubePtsRef_three); Collections.sort(listOfAllFFT); flush(); } if (e.getKeyCode() == KeyEvent.VK_Q) { y -= dY; listOfAllFFT = new ArrayList(); cube_one[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cubePtsRef_one, 0, dY, 0); } }); updateDataEmpty(cube_one, cubePtsRef_one); cube_two[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cubePtsRef_two, 0, dY, 0); } }); updateDataEmpty(cube_two, cubePtsRef_two); cube_three[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cubePtsRef_three, 0, dY, 0); } }); updateDataEmpty(cube_three, cubePtsRef_three); Collections.sort(listOfAllFFT); flush(); } if (e.getKeyCode() == KeyEvent.VK_E) { y += dY; listOfAllFFT = new ArrayList(); cube_one[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cubePtsRef_one, 0, -dY, 0); } }); updateDataEmpty(cube_one, cubePtsRef_one); cube_two[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cubePtsRef_two, 0, -dY, 0); } }); updateDataEmpty(cube_two, cubePtsRef_two); cube_three[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cubePtsRef_three, 0, -dY, 0); } }); updateDataEmpty(cube_three, cubePtsRef_three); Collections.sort(listOfAllFFT); flush(); } if (e.getKeyCode() == KeyEvent.VK_W) { z += dZ; listOfAllFFT = new ArrayList(); cube_one[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cubePtsRef_one, 0, 0, dZ); } }); updateDataEmpty(cube_one, cubePtsRef_one); cube_two[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cubePtsRef_two, 0, 0, dZ); } }); updateDataEmpty(cube_two, cubePtsRef_two); cube_three[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cubePtsRef_three, 0, 0, dZ); } }); updateDataEmpty(cube_three, cubePtsRef_three); Collections.sort(listOfAllFFT); flush(); } if (e.getKeyCode() == KeyEvent.VK_S) { z -= dZ; listOfAllFFT = new ArrayList(); cube_one[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cubePtsRef_one, 0, 0, -dZ); } }); updateDataEmpty(cube_one, cubePtsRef_one); cube_two[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cubePtsRef_two, 0, 0, -dZ); } }); updateDataEmpty(cube_two, cubePtsRef_two); cube_three[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { translateArray(cubePtsRef_three, 0, 0, -dZ); } }); updateDataEmpty(cube_three, cubePtsRef_three); Collections.sort(listOfAllFFT); flush(); } if (e.getKeyCode() == KeyEvent.VK_DOWN) { rotX += dRotX; listOfAllFFT = new ArrayList(); cube_one[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayX(cubePtsRef_one, dRotX); } }); updateDataEmpty(cube_one, cubePtsRef_one); cube_two[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayX(cubePtsRef_two, dRotX); } }); updateDataEmpty(cube_two, cubePtsRef_two); cube_three[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayX(cubePtsRef_three, dRotX); } }); updateDataEmpty(cube_three, cubePtsRef_three); Collections.sort(listOfAllFFT); flush(); } if (e.getKeyCode() == KeyEvent.VK_UP) { rotX -= dRotX; listOfAllFFT = new ArrayList(); cube_one[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayX(cubePtsRef_one, -dRotX); } }); updateDataEmpty(cube_one, cubePtsRef_one); cube_two[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayX(cubePtsRef_two,-dRotX); } }); updateDataEmpty(cube_two, cubePtsRef_two); cube_three[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayX(cubePtsRef_three, -dRotX); } }); updateDataEmpty(cube_three, cubePtsRef_three); Collections.sort(listOfAllFFT); flush(); } if (e.getKeyCode() == KeyEvent.VK_RIGHT) { rotY += dRotY; listOfAllFFT = new ArrayList(); cube_one[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayY(cubePtsRef_one, dRotY); } }); updateDataEmpty(cube_one, cubePtsRef_one); cube_two[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayY(cubePtsRef_two, dRotY); } }); updateDataEmpty(cube_two, cubePtsRef_two); cube_three[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayY(cubePtsRef_three, dRotY); } }); updateDataEmpty(cube_three, cubePtsRef_three); Collections.sort(listOfAllFFT); flush(); } if (e.getKeyCode() == KeyEvent.VK_LEFT) { rotY -= dRotY; listOfAllFFT = new ArrayList(); cube_one[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayY(cubePtsRef_one, -dRotY); } }); updateDataEmpty(cube_one, cubePtsRef_one); cube_two[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayY(cubePtsRef_two, -dRotY); } }); updateDataEmpty(cube_two, cubePtsRef_two); cube_three[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayY(cubePtsRef_three, -dRotY); } }); updateDataEmpty(cube_three, cubePtsRef_three); Collections.sort(listOfAllFFT); flush(); } if (e.getKeyCode() == KeyEvent.VK_C) { rotZ += dRotZ; listOfAllFFT = new ArrayList(); cube_one[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayZ(cubePtsRef_one, dRotZ); } }); updateDataEmpty(cube_one, cubePtsRef_one); cube_two[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayZ(cubePtsRef_two, dRotZ); } }); updateDataEmpty(cube_two, cubePtsRef_two); cube_three[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayZ(cubePtsRef_three, dRotZ); } }); updateDataEmpty(cube_three, cubePtsRef_three); Collections.sort(listOfAllFFT); flush(); } if (e.getKeyCode() == KeyEvent.VK_V) { rotZ -= dRotZ; listOfAllFFT = new ArrayList(); cube_one[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayZ(cubePtsRef_one, -dRotZ); } }); updateDataEmpty(cube_one, cubePtsRef_one); cube_two[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayZ(cubePtsRef_two, -dRotZ); } }); updateDataEmpty(cube_two, cubePtsRef_two); cube_three[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { rotateArrayZ(cubePtsRef_three, -dRotZ); } }); updateDataEmpty(cube_three, cubePtsRef_three); Collections.sort(listOfAllFFT); flush(); } if (e.getKeyCode() == KeyEvent.VK_Z) { zoomScaleX*= 1/1.05; zoomScaleY*= 1/1.05; listOfAllFFT = new ArrayList(); cube_one[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { zoom(cubePtsRef_one, 1/1.05, 1/1.05, 1); } }); updateDataEmpty(cube_one, cubePtsRef_one); cube_two[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { zoom(cubePtsRef_two, 1/1.05, 1/1.05, 1); } }); updateDataEmpty(cube_two, cubePtsRef_two); cube_three[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { zoom(cubePtsRef_three, 1/1.05, 1/1.05, 1); } }); updateDataEmpty(cube_three, cubePtsRef_three); Collections.sort(listOfAllFFT); flush(); } if (e.getKeyCode() == KeyEvent.VK_X) { zoomScaleX*= 1.05; zoomScaleY*= 1.05; listOfAllFFT = new ArrayList(); cube_one[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { zoom(cubePtsRef_one, 1.05, 1.05, 1); } }); updateDataEmpty(cube_one, cubePtsRef_one); cube_two[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { zoom(cubePtsRef_two, 1.05, 1.05, 1); } }); updateDataEmpty(cube_two, cubePtsRef_two); cube_three[0].updateData(new GeometryUpdater() { @Override public void updateData(Geometry geom) { zoom(cubePtsRef_three, 1.05, 1.05, 1); } }); updateDataEmpty(cube_three, cubePtsRef_three); Collections.sort(listOfAllFFT); flush(); } } }); // make it visible, because we hand in a canvas3D we also have to get the canvas // (AWT object) on to the screen now JFrame j3dJFrames = new JFrame(); j3dJFrames.setDefaultCloseOperation(j3dJFrames.EXIT_ON_CLOSE); j3dJFrames.getContentPane().setLayout(new BorderLayout()); j3dJFrames.setSize(256, 256); // Put the Canvas3D into a JPanel. JPanel j3dJPanels = new JPanel(); j3dJPanels.setLayout(new BorderLayout()); j3dJPanels.add("Center", canv); j3dJFrames.getContentPane().add("Center", j3dJPanels); j3dJFrames.setVisible(true); } }