checkpoint
[anneal.git] / src / Main.java
1 import java.awt.*;
2 import java.awt.event.*;
3 import javax.swing.*;
4 import javax.media.opengl.*;
5 import javax.media.opengl.glu.*;
6 import java.util.*;
7
8 // FEATURE: check google's 3D warehouse for sample shapes
9
10 public class Main implements GLEventListener, MouseListener, MouseMotionListener, KeyListener, MouseWheelListener {
11     
12     boolean alt = false;
13     boolean shift = false;
14     boolean control = false;
15
16     public void mouseWheelMoved(MouseWheelEvent e) {
17         tz -= e.getWheelRotation() ;
18     }
19
20     public void keyTyped(KeyEvent e)  { }
21     public void keyPressed(KeyEvent e)  {
22         switch(e.getKeyCode()) {
23             case KeyEvent.VK_CONTROL: control = true; break;
24             case KeyEvent.VK_ALT: alt = true; break;
25             case KeyEvent.VK_SHIFT: shift = true; break;
26         }
27     }
28     public void keyReleased(KeyEvent e) {
29         switch(e.getKeyCode()) {
30             case KeyEvent.VK_CONTROL: control = false; break;
31             case KeyEvent.VK_ALT: alt = false; break;
32             case KeyEvent.VK_SHIFT: shift = false; break;
33         }
34     }
35
36     public void mouseClicked(MouseEvent e) { }
37     public void mouseEntered(MouseEvent e) { }
38     public void mouseExited(MouseEvent e) { }
39     public void mousePressed(MouseEvent e) { }
40     public void mouseReleased(MouseEvent e) { }
41
42     int mousex;
43     int mousey;
44     public void mouseMoved(MouseEvent e) {
45         mousex = e.getX();
46         mousey = e.getY();
47     }
48
49     float tx = 0;
50     float ty = 0;
51     float tz = 0;
52     float anglex = 0;
53     float angley = 0;
54     public void mouseDragged(MouseEvent e) {
55         if (shift) {
56             tx += (mousex - e.getX())/(float)20;
57             ty += (mousey - e.getY())/(float)20;
58         } else {
59             anglex -= mousex - e.getX();
60             angley += mousey - e.getY();
61         }
62         mousex = e.getX();
63         mousey = e.getY();
64     }
65
66     private Geom geom = new Geom();
67
68     /** magnification factor */
69     private static final float MAG = 1;
70
71     Geom.V[] translations;
72     Geom.P[] points;
73
74     public Main(StlFile stlf) {
75
76         Geom.P ltf = geom.newP(-0.2,  0.1,  0.1);
77         Geom.P mtf = geom.newP( 0.0,  0.1,  0.1);
78         Geom.P rtf = geom.newP( 0.2,  0.1,  0.1);
79         Geom.P ltn = geom.newP(-0.2,  0.1, -0.1);
80         Geom.P mtn = geom.newP( 0.0,  0.1, -0.1);
81         Geom.P rtn = geom.newP( 0.2,  0.1, -0.1);
82         Geom.P lbf = geom.newP(-0.2, -0.1,  0.1);
83         Geom.P mbf = geom.newP( 0.0, -0.1,  0.1);
84         Geom.P rbf = geom.newP( 0.2, -0.1,  0.1);
85         Geom.P lbn = geom.newP(-0.2, -0.1, -0.1);
86         Geom.P mbn = geom.newP( 0.0, -0.1, -0.1);
87         Geom.P rbn = geom.newP( 0.2, -0.1, -0.1);
88         
89         points = new Geom.P[] {
90             ltf,
91             mtf,
92             rtf,
93             ltn,
94             mtn,
95             rtn,
96             lbf,
97             mbf,
98             rbf,
99             lbn,
100             mbn,
101             rbn
102         };
103
104         translations = new Geom.V[] {
105             geom.new V(-0.2,  0.2,    0),
106             geom.new V( 0.2,  0.2,    0),
107             geom.new V(-0.2, -0.2,    0),
108             geom.new V( 0.2, -0.2,    0),
109             geom.new V( 0.4,    0,    0),
110             geom.new V(-0.4,    0,    0),
111             geom.new V(   0,    0,  0.2),
112             geom.new V(   0,    0, -0.2),
113         };
114
115         // top
116         geom.newT(ltf, mtf, mtn);
117         geom.newT(mtn, ltn, ltf);
118         geom.newT(mtf, rtf, rtn);
119         geom.newT(rtn, mtn, mtf);
120
121         // bottom (swap normals)
122         geom.newT(mbf, lbf, mbn);
123         geom.newT(lbn, mbn, lbf);
124         geom.newT(rbf, mbf, rbn);
125         geom.newT(mbn, rbn, mbf);
126         
127         // left
128         geom.newT(ltf, ltn, lbn);
129         geom.newT(lbn, lbf, ltf);
130
131         // right (swap normals)
132         geom.newT(rtn, rtf, rbn);
133         geom.newT(rbf, rbn, rtf);
134
135         // front
136         geom.newT(ltn, mtn, mbn);
137         geom.newT(ltn, mbn, lbn);
138         geom.newT(mtn, rtn, rbn);
139         geom.newT(mtn, rbn, mbn);
140
141         // back
142         geom.newT(mtf, ltf, mbf);
143         geom.newT(mbf, ltf, lbf);
144         geom.newT(rtf, mtf, rbf);
145         geom.newT(rbf, mtf, mbf);
146
147         for(Geom.V v : translations) {
148             for(Geom.T t1 : geom) {
149                 for(Geom.T t2 : geom) {
150                     if (t1==t2) continue;
151
152                     if ((t1.p1().plus(v).minus(t2.p1()).mag() < Geom.EPSILON) &&
153                         (t1.p2().plus(v).minus(t2.p3()).mag() < Geom.EPSILON) &&
154                         (t1.p3().plus(v).minus(t2.p2()).mag() < Geom.EPSILON)) {
155                         t1.e1().bind(t2.e3().pair);
156                         t1.e2().bind(t2.e2().pair);
157                         t1.e3().bind(t2.e1().pair);
158                     }
159                     if ((t1.p2().plus(v).minus(t2.p1()).mag() < Geom.EPSILON) &&
160                         (t1.p3().plus(v).minus(t2.p3()).mag() < Geom.EPSILON) &&
161                         (t1.p1().plus(v).minus(t2.p2()).mag() < Geom.EPSILON)) {
162                         t1.e2().bind(t2.e3().pair);
163                         t1.e3().bind(t2.e2().pair);
164                         t1.e1().bind(t2.e1().pair);
165                     }
166                     if ((t1.p3().plus(v).minus(t2.p1()).mag() < Geom.EPSILON) &&
167                         (t1.p1().plus(v).minus(t2.p3()).mag() < Geom.EPSILON) &&
168                         (t1.p2().plus(v).minus(t2.p2()).mag() < Geom.EPSILON)) {
169                         t1.e3().bind(t2.e3().pair);
170                         t1.e1().bind(t2.e2().pair);
171                         t1.e2().bind(t2.e1().pair);
172                     }
173                 }
174             }
175         }
176
177         Geom.P mid = ltn.getE(mbn).shatter();
178
179         //tx.e2.shatter();
180         //tx.e3.shatter();
181
182
183         geom.bind();
184
185         mid.move(geom.new V((float)0,0,(float)-0.05));
186         //ltn.move(geom.new V((float)0,0,(float)-0.05));
187
188         //mtf.move(geom.new V(0, (float)-0.05, (float)0.05));
189         /*
190         for(int i=0; i<100; i++) {
191             rand();
192         }
193         */
194
195
196         /*
197         for(int i=0; i<stlf.coordArray.length; i+=3) {
198             Geom.P p0 = geom.newP(stlf.coordArray[i+0].x * MAG, stlf.coordArray[i+0].y * MAG, stlf.coordArray[i+0].z * MAG);
199             Geom.P p1 = geom.newP(stlf.coordArray[i+1].x * MAG, stlf.coordArray[i+1].y * MAG, stlf.coordArray[i+1].z * MAG);
200             Geom.P p2 = geom.newP(stlf.coordArray[i+2].x * MAG, stlf.coordArray[i+2].y * MAG, stlf.coordArray[i+2].z * MAG);
201             Geom.V n  = geom.new V(stlf.normArray[i/3].x * MAG, stlf.normArray[i/3].y  * MAG, stlf.normArray[i/3].z * MAG);
202             Geom.T t  = geom.newT(p0, p1, p2, n);
203         }
204         */
205
206
207     }
208         Random random = new Random();
209
210     public synchronized void breakit() {
211         int i = Math.abs(random.nextInt()) % geom.es.size();
212         Geom.E e = geom.es.poll();
213         System.out.println("shatter " + e);
214         e.shatter();
215         geom.unbind();
216         geom.bind();
217     }
218     public synchronized void rand() {
219         for(int i=0; i<10; i++) {
220             Geom.P p = geom.ts.get(Math.abs(random.nextInt()) % geom.ts.size()).e1().p1;
221             float r1 = Math.abs(random.nextFloat());
222             r1 = r1 - (float)Math.floor(r1);
223             r1 = r1 * (float)0.01;
224             r1 = r1 - (float)0.005;
225             switch(Math.abs(random.nextInt()) % 3) {
226                 case 0: p.move(geom.new V((float)0,  (float)r1, (float)0)); break;
227                 case 1: p.move(geom.new V((float)r1, (float)0,  (float)0)); break;
228                 case 2: p.move(geom.new V((float)0,  (float)0, (float)r1)); break;
229             }
230         }
231     }
232
233     /**
234      * Take care of initialization here.
235      */
236     public void init(GLAutoDrawable gld) {
237         GL gl = gld.getGL();
238         gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
239         gl.glViewport(0, 0, 500, 300);
240         gl.glMatrixMode(GL.GL_PROJECTION);
241         gl.glEnable(GL.GL_DEPTH_TEST);
242         gl.glClearDepth(1.0);
243         gl.glDepthFunc(GL.GL_LEQUAL);
244         gl.glLoadIdentity();
245         //glu.gluOrtho2D(0.0, 500.0, 0.0, 300.0);
246         display(gld);
247     }
248
249     public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
250     public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { }
251     public synchronized void display(GLAutoDrawable drawable) {
252         GL gl = drawable.getGL();
253         GLU glu = new GLU();
254         gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
255         gl.glPointSize(5.0f);
256         gl.glLoadIdentity();
257         glu.gluPerspective(50-tz, ((float)drawable.getWidth())/drawable.getHeight(), 0.5, 10);
258         glu.gluLookAt(0, 0, -1, 0, 0, 0, 0, 1, 0);
259         gl.glTranslatef(tx/(float)20, ty/(float)20, 0);
260         gl.glRotatef(anglex/3, 0, 1, 0);
261         gl.glRotatef(angley/3, 1, 0, 0);
262
263         gl.glBegin(GL.GL_TRIANGLES);
264         draw(gl, true);
265         gl.glEnd();
266
267         for(Geom.V v1 : translations) {
268             if (v1.z==0 && v1.y==0) continue;
269             Geom.V v = v1.times((float)1.1);
270             gl.glTranslatef(v.x, v.y, v.z);
271             draw(gl, false);
272             gl.glTranslatef(-v.x, -v.y, -v.z);
273             break;
274         }
275
276     }
277
278     private synchronized void draw(GL gl, boolean triangles) {
279         float red = 0.0f;
280         float green = 0.0f;
281         float blue = 0.0f;
282         for(Geom.T t : geom) {
283             if (red < 0.15) red = 1.0f;
284             if (green < 0.15) green = 1.0f;
285             if (blue < 0.15) blue = 1.0f;
286             red -= .09f;
287             green -= .12f;
288             blue -= .15f;
289             gl.glColor3f(red, green, blue);
290             switch(t.color) {
291                 case 0: gl.glColor3f((float)0.25, (float)0.25, (float)0.75); break;
292                 case 1: gl.glColor3f((float)0.25, (float)0.75, (float)0.25); break;
293                 case 2: gl.glColor3f((float)0.75, (float)0.25, (float)0.25); break;
294                 case 3: gl.glColor3f((float)0.50, (float)0.50, (float)0.50); break;
295             }
296             //gl.glBegin(GL.GL_LINES);
297             if (triangles) {
298                 gl.glBegin(GL.GL_TRIANGLES);
299                 t.glVertices(gl);
300                 gl.glEnd();
301             } else {
302                 gl.glBegin(GL.GL_LINES);
303                 t.e1().p1.glVertex(gl);
304                 t.e1().p2.glVertex(gl);
305                 t.e2().p1.glVertex(gl);
306                 t.e2().p2.glVertex(gl);
307                 t.e3().p1.glVertex(gl);
308                 t.e3().p2.glVertex(gl);
309                 gl.glEnd();
310             }
311
312             Geom.P centroid = t.centroid();
313             gl.glBegin(GL.GL_LINES);
314             gl.glColor3f(1, 1, 1);
315             /*
316             centroid.glVertex(gl);
317             centroid.plus(t.norm().times(t.diameter())).glVertex(gl);
318             */
319             /*
320             t.p1().glVertex(gl);
321             t.p1().plus(t.p1().norm().times(t.diameter())).glVertex(gl);
322             t.p2().glVertex(gl);
323             t.p2().plus(t.p2().norm().times(t.diameter())).glVertex(gl);
324             t.p3().glVertex(gl);
325             t.p3().plus(t.p3().norm().times(t.diameter())).glVertex(gl);
326             */
327             gl.glEnd();
328
329         }
330     }
331
332     public static void main(String[] s) throws Exception {
333         StlFile stlf = new StlFile();
334         stlf.load("teapot.stl");
335         Main main = new Main(stlf);
336         Frame f = new Frame();
337         GLCapabilities glcaps = new GLCapabilities();
338         GLCanvas glcanvas = new GLCanvas();
339         glcanvas.addGLEventListener(main);
340         f.add(glcanvas, BorderLayout.CENTER);
341         f.pack();
342         f.show();
343         f.setSize(900, 900);
344         f.doLayout();
345
346         glcanvas.addMouseListener(main);
347         glcanvas.addMouseMotionListener(main);
348         glcanvas.addMouseWheelListener(main);
349         glcanvas.addKeyListener(main);
350
351         int i = 0;
352         while(true) {
353             Thread.sleep(10);
354             glcanvas.repaint();
355             main.rand();
356             if (i++>10) { main.breakit(); i = 0; }
357        }
358
359     }
360
361 }