1. Trang chủ
  2. » Giáo Dục - Đào Tạo

3 advanced topics in animation presented with JOGL2 tủ tài liệu bách khoa

32 57 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 32
Dung lượng 1,87 MB

Nội dung

Dr Manuel Carcenac - European University of Lefke Advanced topics in animation - presented with JOGL kinematic animation: time interpolation of degrees of freedom dynamic animation: time integration of degrees of freedom dynamic animation: all-pairs n-body problem and gravitation References: http://jogamp.org/ (for JOGL 2.0) http://download.java.net/media/jogl/jogl-2.x-docs/ http://www.glprogramming.com/red/ http://eng.eul.edu.tr/manuel/Course_on_Graphics_in_Java/Course_on_Graphics_in_Java.htm (for practical introduction to JOGL 2.0) Advanced Animation and Rendering Techniques – Theory and Practice Alan Watt, Mark Watt; Addison-Wesley, ACM press Michael Thomas Flanagan's Java Scientific and Numerical Library http://www.ee.ucl.ac.uk/~mflanaga/java/index.html http://www.ee.ucl.ac.uk/~mflanaga/java/CubicSpline.html (for cubic spline interpolation) http://farside.ph.utexas.edu/teaching/329/lectures/node35.html for Runge-Kutta method http://www.ast.cam.ac.uk/~sverre/web/pages/nbody.htm for n-body problem http://www.scholarpedia.org/article/N-body_simulations_(gravitational) Dr Manuel Carcenac - European University of Lefke kinematic animation: time interpolation of degrees of freedom cubic spline interpolation: install Flanagan's scientific library: ♦ put flanagan.jar into folder C:\Program Files\Java\jdk1.6.0_23\jre\lib\ext ♦ add to system variable CLASSPATH (already exists, was created for JOGL) ♦ Computer  Properties  Advanced system settings  Environment Variables ♦ edit system variable CLASSPATH (already exists, was created for JOGL)  add at the end of it: ;C:\Program Files\Java\jdk1.6.0_23\jre\lib\ext\flanagan.jar import statement: import flanagan.interpolation.*; cubic spline with Nk control points ( tk , xk ) : double[] xk = new double[Nk]; double[] tk = new double[Nk]; CubicSpline csx = new CubicSpline(tk , xk); interpolation of function x(t) : double x = csx.interpolate(t); for every control point k , csx.interpolate(tk[k]) yields value xk[k] Dr Manuel Carcenac - European University of Lefke example: interpolated curve with interactive selection and modification of control points import flanagan.interpolation.*; public class P { public static void main(String[] arg) { Gui gui = new Gui(); } } class Gui { JFrame f; DrawingPanel p; JPanel ps; JSlider skx , sky , skz , skt; JLabel lkx , lky , lkz , lkt; int Nk = 8; int ks = 0; // ks = k of selected key double[] xk = new double[Nk] , yk = new double[Nk] , zk = new double[Nk] , tk = new double[Nk]; int N = 60; double L = 100.0 , T = 100.0; { for (int k = ; k < Nk ; k++) { xk[k] = 0.0; yk[k] = - L / + L * k / (Nk - 1); zk[k] = 0.0; tk[k] = T * k / (Nk - 1); } } class DrawingPanel extends GLJPanel { GLU glu; GLUquadric quad; float[] RED = new float[] { 1.0f , 0.0f , 0.0f , 1.0f } , GREEN = new float[] { 0.0f , 1.0f , 0.0f , 1.0f } , WHITE = new float[] { 1.0f , 1.0f , 1.0f , 1.0f }; DrawingPanel() { super(new GLCapabilities(GLProfile.getDefault())); this.addGLEventListener(new GLEventListener() { public void display(GLAutoDrawable drawable) { //**** DISPLAY //// - KEY POINTS for (int k = ; k < Nk ; k++) { gl.glMaterialfv(GL.GL_FRONT_AND_BACK , GLLightingFunc.GL_AMBIENT_AND_DIFFUSE , (k == ks ? RED : GREEN) , 0); gl.glPushMatrix(); gl.glTranslatef((float)xk[k] , (float)yk[k] , (float)zk[k]); glu.gluSphere(quad , 2.0f , 10 , 10); gl.glPopMatrix(); } Dr Manuel Carcenac - European University of Lefke //// - INTERPOLATED POINTS gl.glMaterialfv(GL.GL_FRONT_AND_BACK , GLLightingFunc.GL_AMBIENT_AND_DIFFUSE , WHITE , 0); CubicSpline csx = new CubicSpline(tk , xk) , csy = new CubicSpline(tk , yk) , csz = new CubicSpline(tk , zk); for (int k = ; k < N ; k++) { double t = T * k / (N - 1); double x = csx.interpolate(t) , y = csy.interpolate(t) , z = csz.interpolate(t); gl.glPushMatrix(); gl.glTranslatef((float)x , (float)y , (float)z); glu.gluSphere(quad , 1.0f , 10 , 10); gl.glPopMatrix(); } gl.glFlush(); } } ); } } Dr Manuel Carcenac - European University of Lefke Gui() { f = new JFrame(); f.setFocusable(true); f.setVisible(true); p = new DrawingPanel(); f.getContentPane().add(p , BorderLayout.CENTER); f.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { int bt = e.getButton(); switch (bt) { case MouseEvent.BUTTON1: ks ; if (ks == -1) ks = Nk - 1; case MouseEvent.BUTTON3: ks++; if (ks == Nk) ks = 0; break; break; } skx.setValue((int)(1000 * (0.5 + xk[ks] / L))); sky.setValue((int)(1000 * (0.5 + yk[ks] / L))); skz.setValue((int)(1000 * (0.5 + zk[ks] / L))); skt.setValue((int)(1000 * tk[ks] / T)); f.repaint(); } } ); ps = new JPanel(); ps.setLayout(new GridLayout(0 , 2)); f.getContentPane().add(ps , BorderLayout.EAST); skx = new JSlider(JSlider.HORIZONTAL , , 1000 , 0); ps.add(skx); lkx = new JLabel(" x of selected key"); ps.add(lkx); sky = new JSlider(JSlider.HORIZONTAL , , 1000 , 0); ps.add(sky); lky = new JLabel(" y of selected key"); ps.add(lky); skz = new JSlider(JSlider.HORIZONTAL , , 1000 , 0); ps.add(skz); lkz = new JLabel(" z of selected key"); ps.add(lkz); skt = new JSlider(JSlider.HORIZONTAL , , 1000 , 0); ps.add(skt); lkt = new JLabel(" t of selected key"); ps.add(lkt); skx.addChangeListener( { xk[ks] = -L/2+L*skx.getValue()/1000; f.repaint(); } } ); sky.addChangeListener( { yk[ks] = -L/2+L*sky.getValue()/1000; f.repaint(); } } ); skz.addChangeListener( { zk[ks] = -L/2+L*skz.getValue()/1000; f.repaint(); } } ); skt.addChangeListener( { if (ks != && ks != Nk - 1) tk[ks] = T*skt.getValue()/1000; if (ks > && tk[ks - 1] + T / 100 > tk[ks]) { tk[ks] = tk[ks - 1] + T / 100; } if (ks < Nk - && tk[ks] > tk[ks + 1] - T / 100) { tk[ks] = tk[ks + 1] - T / 100; } f.repaint(); } } ); f.setSize(new Dimension(900 + 16 , 600 + 38)); } } Dr Manuel Carcenac - European University of Lefke Dr Manuel Carcenac - European University of Lefke example: interpolated trajectory of a ball: interactive creation of key frames over time followed by spline driven animation import flanagan.interpolation.*; public class P { public static void main(String[] arg) { Gui gui = new Gui(); while (true) { if (gui.read_perform_anim()) { gui.animation(); gui.write_perform_anim(false); } Thread.yield(); } } } class Gui { JFrame f; DrawingPanel p; JPanel ps; JSlider skx , sky , skz; JLabel lkx , lky , lkz; JButton b_new_key , b_perform_anim; int Nk , nk; double[] xk , yk , zk , tk; double L = 100.0 , T = 20.0; double time; boolean perform_anim = false; synchronized void write_perform_anim(boolean value) { perform_anim = value; } synchronized boolean read_perform_anim() { return perform_anim; } void animation() { time = 0; long dt = 50; // 0.05s while (time + dt * 0.001 < T) { long t_start = System.currentTimeMillis(); f.repaint(); time += dt * 0.001; long dt_real = System.currentTimeMillis() - t_start; if (dt_real < dt) try {Thread.sleep(dt - dt_real);} catch(InterruptedException ee){} else System.out.println("PC too slow; please increase dt"); } } Dr Manuel Carcenac - European University of Lefke class DrawingPanel extends GLJPanel { GLU glu; GLUquadric quad; float[] RED = new float[] { 1.0f , 0.0f , 0.0f , 1.0f } , GREEN = new float[] { 0.0f , 1.0f , 0.0f , 1.0f } , WHITE = new float[] { 1.0f , 1.0f , 1.0f , 1.0f }; DrawingPanel() { super(new GLCapabilities(GLProfile.getDefault())); this.addGLEventListener(new GLEventListener() { public void display(GLAutoDrawable drawable) { //**** DISPLAY //// - KEY POINTS for (int k = ; k < nk ; k++) { gl.glMaterialfv(GL.GL_FRONT_AND_BACK , GLLightingFunc.GL_AMBIENT_AND_DIFFUSE , (k == nk - ? RED : GREEN) , 0); gl.glPushMatrix(); gl.glTranslatef((float)xk[k] , (float)yk[k] , (float)zk[k]); glu.gluSphere(quad , 4.0f , 10 , 10); gl.glPopMatrix(); } //// - ANIMATED POINT if (read_perform_anim()) { gl.glMaterialfv(GL.GL_FRONT_AND_BACK , GLLightingFunc.GL_AMBIENT_AND_DIFFUSE , WHITE , 0); CubicSpline csx = new CubicSpline(tk , xk) , csy = new CubicSpline(tk , yk) , csz = new CubicSpline(tk , zk); double x = csx.interpolate(time) , y = csy.interpolate(time) , z = csz.interpolate(time); gl.glPushMatrix(); gl.glTranslatef((float)x , (float)y , (float)z); glu.gluSphere(quad , 4.0f , 10 , 10); gl.glPopMatrix(); } gl.glFlush(); } } ); } } Dr Manuel Carcenac - European University of Lefke Gui() { f = new JFrame(); f.setFocusable(true); f.setVisible(true); p = new DrawingPanel(); f.getContentPane().add(p , BorderLayout.CENTER); String s = JOptionPane.showInputDialog(f , "number of ctrl pts over " + T + "s ; at least 3"); Nk = Integer.valueOf(s).intValue(); if (Nk 0) { xk[nk - 1] = L * skx.getValue() / 1000; f.repaint(); } } } ); sky.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { if (nk > 0) { yk[nk - 1] = L * sky.getValue() / 1000; f.repaint(); } } } ); skz.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { if (nk > 0) { zk[nk - 1] = L * skz.getValue() / 1000; f.repaint(); } } } ); b_new_key = new JButton(); b_new_key.setText("record new key"); b_new_key.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (nk + Para.H / 2); dpv[i] = new PositionVelocity(); pv_[i] = new PositionVelocity(); } } 26 Dr Manuel Carcenac - European University of Lefke time integration with Runge-Kutta: void evolve_over_time_step(double dt) { derivatives_positions_velocities(pv); increment_positions_velocities(pv_ , pv , dpv , dt / 2); D1 s(t) + D1 × ∆ t / derivatives_positions_velocities(pv_); D2 increment_positions_velocities(pv , pv , dpv , dt); s(t) + D2 × ∆ t t += dt; } void increment_positions_velocities( PositionVelocity[] pv1 , PositionVelocity[] pv0 , PositionVelocity[] dpv , double k) { for (int i = ; i < n ; i++) { pv1[i].x = pv0[i].x + dpv[i].x * k; pv1[i].y = pv0[i].y + dpv[i].y * k; pv1[i].z = pv0[i].z + dpv[i].z * k; pv1[i].vx = pv0[i].vx + dpv[i].vx * k; pv1[i].vy = pv0[i].vy + dpv[i].vy * k; pv1[i].vz = pv0[i].vz + dpv[i].vz * k; } } 27 Dr Manuel Carcenac - European University of Lefke time derivatives of positions and velocities: //// calculate dpv for pv = state.pv or state.pv_ void derivatives_positions_velocities(PositionVelocity[] pv) { double pipjx , pipjy , pipjz , d2 , q; for (int i = ; i < n ; i++) { dpv[i].x = pv[i].vx; dpv[i].y = pv[i].vy; dpv[i].z = pv[i].vz; dpv[i].vx = 0.0; dpv[i].vy = 0.0; dpv[i].vz = 0.0; for (int j = ; j < n ; j++) if (j != i) { pipjx = pv[j].x - pv[i].x; pipjy = pv[j].y - pv[i].y; pipjz = pv[j].z - pv[i].z; d2 = pipjx * pipjx + pipjy * pipjy + pipjz * pipjz + Para.EPS * Para.EPS; q = m[j] / d2 / Math.sqrt(d2); dpv[i].vx += q * pipjx; dpv[i].vy += q * pipjy; dpv[i].vz += q * pipjz; } dpv[i].vx *= Para.G; dpv[i].vy *= Para.G; dpv[i].vz *= Para.G; } } 28 Dr Manuel Carcenac - European University of Lefke displaying the state: void display(GL2 gl , GLU glu , GLUquadric quad) { for (int i = ; i < n ; i++) { if (i < n / 2) gl.glMaterialfv( GL.GL_FRONT_AND_BACK , GLLightingFunc.GL_AMBIENT_AND_DIFFUSE , Gui.COLOR1 , 0); else gl.glMaterialfv( GL.GL_FRONT_AND_BACK , GLLightingFunc.GL_AMBIENT_AND_DIFFUSE , Gui.COLOR2 , 0); gl.glPushMatrix(); gl.glTranslatef( (float)(pv[i].x / Para.H) , (float)(pv[i].y / Para.H) , (float)(pv[i].z / Para.H)); glu.gluSphere(quad , 0.01f , 10 , 10); gl.glPopMatrix(); } } 29 Dr Manuel Carcenac - European University of Lefke main class and Gui class: public class P { public static void main(String[] arg) { Gui gui = new Gui(); gui.animation(); } } class Gui { JFrame f; DrawingPanel p; State state; void animation() { while (true) { state.evolve_over_time_step(Para.DT); f.repaint(); } } class DrawingPanel extends GLJPanel { public void display(GLAutoDrawable drawable) { state.display(gl , glu , quad); } } Gui() { state = new State(n); } } 30 Dr Manuel Carcenac - European University of Lefke example: simulation with n = 4000 31 Dr Manuel Carcenac - European University of Lefke 32

Ngày đăng: 09/11/2019, 07:20

w