/*
* This file is part of 3DzzD http://dzzd.net/.
*
* Released under LGPL
*
* 3DzzD is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 3DzzD is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with 3DzzD.  If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2005 - 2009 Bruno Augier
*/
 
import java.awt.*;
import java.applet.*;

import net.dzzd.access.*;
import net.dzzd.*;
import net.dzzd.utils.*;



/**
 * CreateMesh
 * 
 * This sample show how to create a Mesh3D by hand :
 */
public class CreateMesh extends Applet implements Runnable
{
	public static final long serialVersionUID = 0x00000001;
	IRender3D render;
	IScene3D scene;
	boolean run=false;

	public void start()
	{
		//Ask 3DzzD factory for a fresh Scene3D
		this.scene=DzzD.newScene3D();	
		

		
		/**
		 * Set the active camera in the 3d scene
		 * 
		 * We use a camera that is inside the 3ds file
		 *
		 * 3DzzD always provide a default camera that you can set using :
		 *  this.scene.setCurrentCamera3DById(0);
		 */
		//this.scene.setCurrentCamera3DByName("Camera01");
		
		//Ask 3DzzD factory for a software 3D Render
		this.render=DzzD.newRender3D(this.getClass(),"SOFT",null);
		
		//Add the Render3D canvas to the Applet Panel
		this.setLayout(null);
		this.add(this.render.getCanvas());
		
		//Set the Render3D size
		this.render.setSize(this.getSize().width,this.getSize().height,1);
		
		//Set Camera Aspect ratio to 1:1
		this.scene.getCurrentCamera3D().setZoomY(((double)this.render.getWidth())/((double)this.render.getHeight()));	
		
		//Tell the Render3D wich camera it should use to render
		System.out.println(this.scene.getCurrentCamera3D().getName());
		this.render.setCamera3D(this.scene.getCurrentCamera3D());
		
			
		//Create a main Thread
		Thread mainThread=new Thread(this);
		this.run=true;
		mainThread.start();
	}
	
	/**
	 * Tell the main thread that it can stop running when Applet is destroyed
	 */
	public void destroy()
	{
		this.run=false;
	}
	
	private void createScene3D()
	{
		IVertex3D vertices[]=DzzD.newVertex3DArray(4);
		(vertices[0]=DzzD.newVertex3D()).set(-1,0,-1);	//bottom,near-left
		(vertices[1]=DzzD.newVertex3D()).set(-1,0,1); 	//top,far-left
		(vertices[2]=DzzD.newVertex3D()).set(1,0,1);	//top,far-right
		(vertices[3]=DzzD.newVertex3D()).set(1,0,-1);	//bottom,near-left
		
		IFace3D faces[]=DzzD.newFace3DArray(2);
		faces[0]=DzzD.newFace3D(vertices[0],vertices[1],vertices[2]);
		faces[1]=DzzD.newFace3D(vertices[2],vertices[3],vertices[0]);
		
		IMesh3D mesh=DzzD.newMesh3D(vertices,faces);
		mesh.getPosition().set(0,-1,8);
		mesh.getRotation().set(Math.PI*0.25,Math.PI*0.51,0);
		
		IMaterial material=DzzD.newMaterial();
		mesh.getFace3D(0).setMaterial(material);
		mesh.getFace3D(1).setMaterial(this.scene.getMaterialById(0));
		material.setDiffuseColor(0x550000);
		material.setSelfIlluminationLevel(50);
		
		IURLTexture urlTexture=DzzD.newURLTexture();
		urlTexture.setBaseURL(this.getCodeBase().toString()+"3D/");
		urlTexture.setSourceFile("HELLO.JPG");
		
		material.setDiffuseTexture(urlTexture);
		
		IMappingUV mappingUV=DzzD.newMappingUV();
		mappingUV.setVZoom(2);
		mappingUV.setVOffset(0.5f);
		material.setMappingUV(mappingUV);
		
		float mapping[]={0,1,0,0,1,0,1,0,1,1,0,1};
		mesh.setMappingUV(mapping);
		
		this.scene.addMesh3D(mesh);
		this.scene.addMaterial(material);
		this.scene.addTexture(urlTexture);
		
		this.render.setAntialiasLevel(0);
	}
	
	/**
	 * Here is the mainThread run method
	 * called by mainThread.start(); (inded this method is started in a different Thread)
	 */
	public void run()
	{
		this.createScene3D();
		while(this.run)
		{
			//Render a single frame
			this.renderSingleFrame();
			Thread.yield();	
		}
		
	}
	
	
	
	public void renderSingleFrame()
	{
		//Set the scene to world space
		this.scene.setScene3DObjectToWorld();
		
		//Set the scene to active camera space
		this.scene.setScene3DObjectToCamera();
		
		//Tell the 3D render to compute & draw the frame
		this.render.renderScene3D(this.scene);
	}
}
