// List of modelview01.java

import java.awt.*;
import java.applet.*;

/* modelview applet
 * 
 * @author  Satoshi Kitade
 */
public class modelview01 extends Applet implements Runnable, GeomDefs {

	Thread m_threader = null;
	Image m_imageOffScreen;	// オフスクリーンイメージ

	Model3D m_testModel;
	Camera3D m_testCamera;
	int m_nTimer;
	float m_fR = 800.0f;

	/** アプレット開始前の準備 */
	public void init() {
		// 適当に８面体のＸＹＺ座標を作る
		float fVert[] = new float[8*9];
		for ( int i = 0; i < 8; i++ ) {
			// 0
			fVert[9*i + 0] = 0.0f;
			fVert[9*i + 1] = (i/4)*180.0f - 90.0f;
			fVert[9*i + 2] = 0.0f;
			// 1
			fVert[9*i + 3] = 60.0f*(float)(Math.sin( 6.28f*((float)i)/4.0f ));
			fVert[9*i + 4] = 0.0f;
			fVert[9*i + 5] = 60.0f*(float)(Math.cos( 6.28f*((float)i)/4.0f ));
			// 2
			fVert[9*i + 6] = 60.0f*(float)(Math.sin( 6.28f*((float)i + 1.0f)/4.0f ));
			fVert[9*i + 7] = 0.0f;
			fVert[9*i + 8] = 60.0f*(float)(Math.cos( 6.28f*((float)i + 1.0f)/4.0f ));
		}
		// モデル生成
		m_testModel = new Model3D(new Vector3D(), 8, fVert);
		// カメラ生成
		m_testCamera = new Camera3D(new Vector3D(m_fR, 350.0f, m_fR), new Vector3D(0.0f, 0.0f, 0.0f));
		m_testModel.calcPos(m_testCamera);
		m_nTimer = 0;
		m_imageOffScreen = createImage(getWidth(), getHeight()); // オフスクリーン用意
	}

	/** システムの描画要求に応える必要がある場合、ここが呼ばれる */
	public void paint(Graphics g) {
		Graphics offGraph = m_imageOffScreen.getGraphics(); // オフスクリーン用Graphics
		offGraph.setColor(Color.black);
		offGraph.fillRect(0, 0, getWidth(), getHeight()); // 画面クリア
		// モデルの描画
		offGraph.setColor(Color.cyan);
		m_testModel.draw(offGraph);
		// オフスクリーンの内容を実画面に描画
		g.drawImage(m_imageOffScreen, 0, 0, this);
	}

	/** update()メソッドをオーバーライドして、画面消去によるチラツキを防ぐ */
	public void update(Graphics g) {
		paint(g);
	}

	/** アプレットの実行開始の際にここが呼ばれる */
	public void start() {
		if ( m_threader == null ) {
			m_threader = new Thread(this);
			// スレッドを開始する
			m_threader.start();
		}
	}

	/** アプレット終了の際に呼ばれる */
	public void stop() {
		m_threader = null;
	}

	/** スレッド処理本体 */
	public void run() {
		Thread thisThread = Thread.currentThread();
		while ( m_threader == thisThread ) { // メインループ
			try {
				m_threader.sleep(50); // ５０ミリ秒待つ
			}
			catch (InterruptedException e) {
				break; // ループを抜ける
			}
			// カメラを回転させる
			Vector3D vec3D = m_testCamera.getVecPos();
			vec3D.m_fX = m_fR*(float)(Math.sin( (Math.PI*(float)m_nTimer)/100.0f ));
			vec3D.m_fZ = m_fR*(float)(Math.cos( (Math.PI*(float)m_nTimer)/100.0f ));
			m_testCamera.setPos(vec3D);
			// モデルの位置を計算
			m_testModel.calcPos(m_testCamera);
			// 画面を描画
			repaint();
			m_nTimer++;
		} // メインループここまで
	}

} // End of modelview01.java