Simple single-color 8x8x8 LED Cube with AVRs
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

Led3D.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. /*
  2. * Led3D.java
  3. *
  4. *
  5. * Copyright 2012 Thomas Buck <xythobuz@me.com>
  6. * Copyright 2012 Max Nuding <max.nuding@gmail.com>
  7. *
  8. * This file is part of LED-Cube.
  9. *
  10. * LED-Cube is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation, either version 3 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * LED-Cube is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with LED-Cube. If not, see <http://www.gnu.org/licenses/>.
  22. */
  23. import com.sun.j3d.utils.universe.*;
  24. import com.sun.j3d.utils.geometry.*;
  25. import javax.media.j3d.*;
  26. import javax.vecmath.*;
  27. import com.sun.j3d.utils.behaviors.mouse.*;
  28. import com.sun.j3d.utils.image.TextureLoader;
  29. import java.awt.Toolkit;
  30. import com.sun.j3d.utils.picking.*;
  31. import java.awt.event.*;
  32. /**
  33. * This class is responsible for displaying the 3D View of our Cube.
  34. *
  35. * @author Thomas Buck
  36. * @author Max Nuding
  37. * @version 1.0
  38. */
  39. public class Led3D extends MouseAdapter {
  40. private Canvas3D canvas = null;
  41. private PickCanvas pickCanvas = null;
  42. private SimpleUniverse universe = null;
  43. private BranchGroup group = null;
  44. private BranchGroup group2 = null;
  45. private Transform3D trans3D = null;
  46. private TransformGroup transGroup = null;
  47. private TransformGroup feetGroup = null;
  48. private Matrix4d mat = null;
  49. private Matrix4d fullScreenMat = null;
  50. private Frame parentFrame = null;
  51. private boolean inFullscreen = false;
  52. private boolean showLegs = true;
  53. private Sphere[][][] leds = new Sphere[8][8][8];
  54. private static ColoringAttributes redColor = new ColoringAttributes(
  55. new Color3f(1.0f, 0.0f, 0.0f), ColoringAttributes.FASTEST);
  56. private static ColoringAttributes whiteColor = new ColoringAttributes(
  57. new Color3f(0.2f, 0.2f, 0.2f), ColoringAttributes.FASTEST);
  58. private static Material whiteMat = new Material(new Color3f(0.2f, 0.2f,
  59. 0.2f), new Color3f(0.0f, 0.0f, 0.0f),
  60. new Color3f(0.2f, 0.2f, 0.2f), new Color3f(0.2f, 0.2f, 0.2f), 64.0f);
  61. private static Material redMat = new Material(
  62. new Color3f(1.0f, 0.0f, 0.0f), new Color3f(1.0f, 0.0f, 0.0f),
  63. new Color3f(1.0f, 0.0f, 0.0f), new Color3f(1.0f, 0.0f, 0.0f), 64.0f);
  64. private Background background;
  65. private Appearance feetApp = new Appearance();
  66. public void toggleLegs(){
  67. if(showLegs){
  68. group2.detach();
  69. } else {
  70. universe.addBranchGraph(group2);
  71. Transform3D t = new Transform3D();
  72. transGroup.getTransform(t);
  73. feetGroup.setTransform(t);
  74. }
  75. showLegs = !showLegs;
  76. }
  77. /**
  78. * @param canv The Canvas3D we render our cube in
  79. */
  80. public Led3D(Canvas3D canv, Frame f) {
  81. canvas = canv;
  82. parentFrame = f;
  83. group = new BranchGroup();
  84. group2 = new BranchGroup();
  85. // Position viewer, so we are looking at object
  86. trans3D = new Transform3D();
  87. mat = new Matrix4d();
  88. mat.setRow(0, 0.7597, -0.0204, 0.64926, 0.56);
  89. mat.setRow(1, -0.08, -0.995, 0.061, 0.02);
  90. mat.setRow(2, 0.64473, -0.09786, -0.758, -14.68);
  91. mat.setRow(3, 0.0, 0.0, 0.0, 1.0);
  92. fullScreenMat = new Matrix4d();
  93. fullScreenMat.setRow(0, 0.7597, -0.0204, 0.64926, 0.68);
  94. fullScreenMat.setRow(1, -0.08, -0.995, 0.061, 0.44);
  95. fullScreenMat.setRow(2, 0.64473, -0.09786, -0.758, -22.88);
  96. fullScreenMat.setRow(3, 0.0, 0.0, 0.0, 1.0);
  97. trans3D.set(mat);
  98. transGroup = new TransformGroup(trans3D);
  99. transGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
  100. transGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
  101. feetGroup = new TransformGroup(trans3D);
  102. feetGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
  103. feetGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
  104. ViewingPlatform viewingPlatform = new ViewingPlatform();
  105. Viewer viewer = new Viewer(canvas);
  106. universe = new SimpleUniverse(viewingPlatform, viewer);
  107. BoundingBox boundBox = new BoundingBox(new Point3d(-5.0, -5.0, -5.0),
  108. new Point3d(13.0, 13.0, 13.0));
  109. // roration with left mouse button
  110. MouseRotate behaviour = new MouseRotate(transGroup);
  111. behaviour.setSchedulingBounds(boundBox);
  112. transGroup.addChild(behaviour);
  113. MouseRotate feetBehaviour = new MouseRotate(feetGroup);
  114. feetBehaviour.setSchedulingBounds(boundBox);
  115. feetGroup.addChild(feetBehaviour);
  116. // zoom with middle mouse button
  117. MouseZoom beh2 = new MouseZoom(transGroup);
  118. beh2.setSchedulingBounds(boundBox);
  119. transGroup.addChild(beh2);
  120. MouseZoom feetBeh2 = new MouseZoom(feetGroup);
  121. feetBeh2.setSchedulingBounds(boundBox);
  122. feetGroup.addChild(feetBeh2);
  123. // move with right mouse button
  124. MouseTranslate beh3 = new MouseTranslate(transGroup);
  125. beh3.setSchedulingBounds(boundBox);
  126. transGroup.addChild(beh3);
  127. MouseTranslate feetBeh3 = new MouseTranslate(feetGroup);
  128. feetBeh3.setSchedulingBounds(boundBox);
  129. feetGroup.addChild(feetBeh3);
  130. group.setCapability(BranchGroup.ALLOW_CHILDREN_READ);
  131. group.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
  132. group.setCapability(BranchGroup.ALLOW_DETACH);
  133. group2.setCapability(BranchGroup.ALLOW_CHILDREN_READ);
  134. group2.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
  135. group2.setCapability(BranchGroup.ALLOW_DETACH);
  136. background = createBackground();
  137. group.addChild(background);
  138. // Add all our led sphares to the universe
  139. for (int x = 0; x < 8; x++) {
  140. for (int y = 0; y < 8; y++) {
  141. for (int z = 0; z < 8; z++) {
  142. Appearance a = new Appearance();
  143. a.setMaterial(whiteMat);
  144. a.setColoringAttributes(whiteColor);
  145. leds[x][y][z] = new Sphere(0.08f,
  146. Sphere.ENABLE_APPEARANCE_MODIFY, a);
  147. TransformGroup tg = new TransformGroup();
  148. Transform3D transform = new Transform3D();
  149. Vector3f vector = new Vector3f(x - 3.5f, y -3.5f, z-3.5f);
  150. transform.setTranslation(vector);
  151. tg.setTransform(transform);
  152. tg.addChild(leds[x][y][z]);
  153. transGroup.addChild(tg);
  154. drawLedFeetVertical((double) x - 3.5, y - 3, (double) z-3.5, 0.9f, 0.01f);
  155. if (x < 7)
  156. drawLedFeetHorizontal(x - 3, (double) y - 3.5, (double) z - 3.5, 0.9f, 0.01f, 0);
  157. }
  158. }
  159. // 8 times, use x as y
  160. for(int i = 0; i > -8; i--){
  161. drawLedFeetHorizontal(i+3.5, (double) x-3.5, 0, 7.0f, 0.02f, 90);
  162. }
  163. }
  164. /*drawLedFeetVertical(5, 5, -5, 50, 0.02f); //
  165. drawLedFeetHorizontal(5, 5, -5, 50, 0.02f, 0); // x, y, and z axis
  166. drawLedFeetHorizontal(5, 5, -5, 50, 0.02f, 90);
  167. Appearance c = new Appearance();
  168. c.setMaterial(redMat);
  169. c.setColoringAttributes(redColor);
  170. Sphere center = new Sphere(0.05f, Sphere.ENABLE_APPEARANCE_MODIFY, c);
  171. TransformGroup tg = new TransformGroup();
  172. Transform3D transform = new Transform3D();
  173. Vector3f vector = new Vector3f(5, 5, -5);
  174. transform.setTranslation(vector);
  175. tg.setTransform(transform);
  176. tg.addChild(center);
  177. feetGroup.addChild(tg);*/
  178. // Add an ambient light
  179. Color3f light2Color = new Color3f(1.0f, 1.0f, 1.0f);
  180. AmbientLight light2 = new AmbientLight(light2Color);
  181. BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
  182. 100.0);
  183. light2.setInfluencingBounds(bounds);
  184. light2.setEnable(true);
  185. transGroup.addChild(light2);
  186. group.addChild(transGroup);
  187. group2.addChild(feetGroup);
  188. universe.addBranchGraph(group); // Add group to universe
  189. universe.addBranchGraph(group2);
  190. // Mouse-Selectable objects
  191. pickCanvas = new PickCanvas(canvas, group);
  192. pickCanvas.setMode(PickCanvas.BOUNDS);
  193. canvas.addMouseListener(this);
  194. }
  195. /**
  196. * Listen for mouse events so the user can click on LEDs.
  197. * @param e MouseEvent generated by the user
  198. */
  199. public void mouseClicked(MouseEvent e) {
  200. pickCanvas.setShapeLocation(e);
  201. PickResult result = pickCanvas.pickClosest();
  202. if (result != null) {
  203. // User clicked near something
  204. Primitive p = (Primitive)result.getNode(PickResult.PRIMITIVE);
  205. if (p != null) {
  206. // p is now a Primitive that the user clicked
  207. if (p.getClass().getName().equals("com.sun.j3d.utils.geometry.Sphere")) {
  208. // p is a Cylinder. Our LEDs are Spheres, so p.equals(led[x][y][z]) does not find anything...
  209. for (int x = 0; x < 8; x++) {
  210. for (int y = 0; y < 8; y++) {
  211. for (int z = 0; z < 8; z++) {
  212. if (p.equals(leds[x][y][z])) {
  213. // Clicked led found!
  214. System.out.println("Clicked LED found: " + x + " " + y + " " + z);
  215. parentFrame.toggleLED(x, y, z);
  216. x = 8;
  217. y = 8;
  218. z = 8;
  219. }
  220. }
  221. }
  222. }
  223. } else {
  224. System.out.println("Clicked, but not a sphere. Clicked object: " + p.getClass().getName());
  225. if(p.getClass().getName().equals("com.sun.j3d.utils.geometry.Cylinder")){
  226. }
  227. }
  228. }
  229. } else {
  230. System.out.println("Clicked, but hit nothing");
  231. }
  232. }
  233. private void drawLedFeetVertical(double x, double y, double z,
  234. float length, float rad) {
  235. // draw Feet going down
  236. feetApp.setMaterial(whiteMat);
  237. feetApp.setColoringAttributes(whiteColor);
  238. Cylinder c = new Cylinder(rad, length, feetApp);
  239. TransformGroup tg = new TransformGroup();
  240. Transform3D transform = new Transform3D();
  241. Vector3d vector = new Vector3d(x, y, z);
  242. transform.setTranslation(vector);
  243. tg.setTransform(transform);
  244. tg.addChild(c);
  245. feetGroup.addChild(tg);
  246. }
  247. private void drawLedFeetHorizontal(double x, double y, double z,
  248. float length, float rad, int deg) {
  249. // draw Feet going down
  250. feetApp.setMaterial(whiteMat);
  251. feetApp.setColoringAttributes(whiteColor);
  252. Cylinder c = new Cylinder(rad, length, feetApp);
  253. TransformGroup tg = new TransformGroup();
  254. Transform3D transform = new Transform3D();
  255. Vector3d vector = new Vector3d(x, y, z);
  256. transform.rotZ(Math.toRadians(90));
  257. if (deg != 0)
  258. transform.rotX(Math.toRadians(deg));
  259. transform.setTranslation(vector);
  260. tg.setTransform(transform);
  261. tg.addChild(c);
  262. feetGroup.addChild(tg);
  263. }
  264. /**
  265. * Rotate the cube back to its initial position.
  266. */
  267. public void resetView() {
  268. Matrix4d mat = new Matrix4d();
  269. if(inFullscreen){
  270. mat.setRow(0, 0.7597, -0.0204, 0.64926, 0.68);
  271. mat.setRow(1, -0.08, -0.995, 0.061, 0.44);
  272. mat.setRow(2, 0.64473, -0.09786, -0.758, -22.88);
  273. mat.setRow(3, 0.0, 0.0, 0.0, 1.0);
  274. } else {
  275. mat.setRow(0, 0.7597, -0.0204, 0.64926, 0.56);
  276. mat.setRow(1, -0.08, -0.995, 0.061, 0.02);
  277. mat.setRow(2, 0.64473, -0.09786, -0.758, -14.68);
  278. mat.setRow(3, 0.0, 0.0, 0.0, 1.0);
  279. }
  280. trans3D.set(mat);
  281. transGroup.setTransform(trans3D);
  282. feetGroup.setTransform(trans3D);
  283. }
  284. /**
  285. * Prints the translation matrix that is changed by moving/rotating the 3D
  286. * Cube with your mouse.
  287. */
  288. public void printTranslationData() {
  289. Matrix4d mat = new Matrix4d();
  290. Transform3D t = new Transform3D();
  291. transGroup.getTransform(t);
  292. t.get(mat);
  293. String s = mat.toString();
  294. System.out.println(s.replaceAll(", ", "\t"));
  295. }
  296. /**
  297. * Sets the data that is displayed by the LEDs
  298. *
  299. * @param data 64 byte array with the data (8 bits/LEDs per byte)
  300. */
  301. public void setData(short[] data) {
  302. for (int y = 0; y < 8; y++) {
  303. for (int z = 0; z < 8; z++) {
  304. for (int x = 0; x < 8; x++) {
  305. Appearance a = new Appearance();
  306. if ((data[y + (z * 8)] & (1 << x)) != 0) {
  307. // Activate led
  308. a.setColoringAttributes(redColor);
  309. a.setMaterial(redMat);
  310. } else {
  311. // Deactivate led
  312. a.setColoringAttributes(whiteColor);
  313. a.setMaterial(whiteMat);
  314. }
  315. leds[x][y][z].setAppearance(a);
  316. }
  317. }
  318. }
  319. }
  320. // create nice background
  321. private Background createBackground() {
  322. Background bg = new Background(1.0f, 1.0f, 1.0f);
  323. int radius = canvas.getWidth();
  324. bg.setApplicationBounds(new BoundingSphere(new Point3d(0.0, 0.0, 0.0), radius));
  325. return bg;
  326. }
  327. /**
  328. * Create new background to reflect changed Canvas size.
  329. */
  330. private void toggleFullscreen() {
  331. group.detach();
  332. if(group.indexOfChild(background) != -1){
  333. group.removeChild(background);
  334. }
  335. background = createBackground();
  336. group.addChild(background);
  337. universe.addBranchGraph(group);
  338. inFullscreen = !inFullscreen;
  339. }
  340. /**
  341. * Create new background and adjust view.
  342. */
  343. public void enterFullscreen() {
  344. toggleFullscreen();
  345. trans3D.set(fullScreenMat);
  346. transGroup.setTransform(trans3D);
  347. feetGroup.setTransform(trans3D);
  348. resetView(); //This is important. For some reason some legs are missing when entering fullscreen mode. Calling this function solves the problem.
  349. }
  350. /**
  351. * Create new background and adjust view.
  352. */
  353. public void leaveFullscreen() {
  354. toggleFullscreen();
  355. trans3D.set(mat);
  356. transGroup.setTransform(trans3D);
  357. feetGroup.setTransform(trans3D);
  358. }
  359. }