/*---------------------------------------------------------------------------
  Shinobi Sample
  COPYRIGHT (C) SEGA ENTERPRISES, LTD.
---------------------------------------------------------------------------*/

#include	<shinobi.h>
#include	<Ninja.h>
#include	"Nj.h"
#include	<NjDef.h>

#define OBJ  object_t_Teapot01_Teapot01

extern NJS_CNK_OBJECT OBJ[];
extern Uint16 Header[];

/* ミラーのサイズ定義 */
#define MIRROR_W	(6.4f)
#define MIRROR_H	(4.8f)
#define MIRROR_Z	(-10.f)
/* ミラーカラー定義 */
#define MIRROR_COLOR		(0xFFC0C0C0)
#define MIRROR_BACKCOLOR	(0xFF300808)

/* レンダテクスチャのサイズ */
#define RENDER_W	(512)
#define RENDER_H	(256)
#define RENDERING_W	(320.f)
#define RENDERING_H	(240.f)
#define RENDERING_CENTER_X	(RENDERING_W/2.f)
#define RENDERING_CENTER_Y	(RENDERING_H/2.f)

NJS_VECTOR sl,dl;

NJS_TEXINFO texinfo;
NJS_TEXNAME texname[2];
NJS_TEXLIST texlist = { texname, 2 };

#define TEXLIST texlist

NJS_TEXTURE_VTX p[4];
NJS_POLYGON_VTX p0[4];

NJS_POINT3 cam,cam2;
/*---------------------------------------------------------------------------
		初期化
		initialize
---------------------------------------------------------------------------*/
Sint32	UserInit(void)
{
	/* テクスチャの設定 */
    njSetTextureName(&texname[0],Header,0,NJD_TEXATTR_TYPE_MEMORY|NJD_TEXATTR_GLOBALINDEX);
	njSetTextureInfo( &texinfo, NULL, NJD_TEXFMT_RGB_565|NJD_TEXFMT_RECTANGLE,RENDER_W,RENDER_H);
	njSetTextureName( &texname[1], &texinfo, 100, NJD_TEXATTR_TYPE_SURFACE | NJD_TEXATTR_GLOBALINDEX);

	if(nuLoadTexture( &TEXLIST ) < 0){
		return USER_EXIT;
	}
	njSetTexture( &TEXLIST );
	
	/* バックカラーを再設定する */
	njSetBackColor(ARGB(0, 50, 50, 50), ARGB(0, 50, 50, 50), ARGB(0, 50, 50, 50));

	/* ライト設定 */
	njCnkSetSimpleLightIntensity( 1.f , 0.f );
	njCnkSetSimpleLightColor( 1.f , 1.f , 1.f);
	
	/* ライトベクトル設定 */
	sl.x = 1.f;
	sl.y = 0.f;
	sl.z = 0.f;
	
   	/* カメラ位置を設定する */
	cam.x =  0.f;
	cam.z = 30.f;
	cam.y = 10.f;

   	/* カメラ位置を設定する */
	cam2.x =  0.f;
	cam2.z = 30.f;
	cam2.y = 10.f;

	/* ミラーのUV値、頂点カラーの設定 */
	p[0].x =  - MIRROR_W;
	p[0].y =  + MIRROR_H;
	p[0].z = 0;

	p[1].x =  - MIRROR_W;
	p[1].y =  - MIRROR_H;
	p[1].z = 0;

	p[2].x =  + MIRROR_W;
	p[2].y =  + MIRROR_H;
	p[2].z = 0;

	p[3].x =  + MIRROR_W;
	p[3].y =  - MIRROR_H;
	p[3].z = 0;

	p0[0].x =  - MIRROR_W;
	p0[0].y =  + MIRROR_H;
	p0[0].z = -0.1f;

	p0[1].x =  - MIRROR_W;
	p0[1].y =  - MIRROR_H;
	p0[1].z = -0.1f;

	p0[2].x =  + MIRROR_W;
	p0[2].y =  + MIRROR_H;
	p0[2].z = -0.1f;

	p0[3].x =  + MIRROR_W;
	p0[3].y =  - MIRROR_H;
	p0[3].z = -0.1f;

	p[0].u = 0.f;
	p[0].v = 0.f;
	p[1].u = 0.f;
	p[1].v = RENDERING_H/(Float)RENDER_H;
	p[2].u = RENDERING_W/(Float)RENDER_W;
	p[2].v = 0.f;
	p[3].u = RENDERING_W/(Float)RENDER_W;
	p[3].v = RENDERING_H/(Float)RENDER_H;

	p[0].col = MIRROR_COLOR;
	p[1].col = MIRROR_COLOR;
	p[2].col = MIRROR_COLOR;
	p[3].col = MIRROR_COLOR;

	p0[0].col = MIRROR_BACKCOLOR;
	p0[1].col = MIRROR_BACKCOLOR;
	p0[2].col = MIRROR_BACKCOLOR;
	p0[3].col = MIRROR_BACKCOLOR;

	return USER_CONTINUE;
}
/*---------------------------------------------------------------------------
		終了処理
		exit
---------------------------------------------------------------------------*/
Sint32	UserExit(void)
{
	return USER_CONTINUE;
}
/*---------------------------------------------------------------------------
		メイン
		main
---------------------------------------------------------------------------*/
Sint32	UserMain(void)
{
    static Angle rotateAng = NJM_DEG_ANG(0.0F);/* 回転角度用変数 */
	NJS_PLANE	mpl;
	NJS_PLANE	nmpl;
	static float MX = 0.f;
	static float MY = 0.f;
	static float MZ = MIRROR_Z;
	static Angle RY = 0;
	NJS_VECTOR ivd;
	Int flag;
	NJS_MATRIX	A;
	Float t;
	NJS_POINT3 np,npd,mpd;
	NJS_POINT3 center = {0.f,0.f,0.f};
	static Int cnt = 0;
	NJS_VECTOR up = {0.f,1.f,0.f};
	NJS_POINT3 ts,tsd;
	

	if(Per->on & PDD_DGT_KU) MY += 0.1f;
	if(Per->on & PDD_DGT_KD) MY -= 0.1f;
	if(Per->on & PDD_DGT_KL) MX -= 0.1f;
	if(Per->on & PDD_DGT_KR) MX += 0.1f;
	if(Per->on & PDD_DGT_TL) MZ += 0.1f;
	if(Per->on & PDD_DGT_TR) MZ -= 0.1f;
	
	RY += Per->x1;
	/* mpl.v Mirrorの法線ベクトル */
	mpl.vx	= -njSin(RY);
	mpl.vy	= 0.f;
	mpl.vz	= -njCos(RY);
	/* mpl.p Mirrorの位置 */
	mpl.px	= MX;
	mpl.py	= MY;
	mpl.pz	= MZ;

	ivd.x = mpl.px - cam.x;
	ivd.y = mpl.py - cam.y;
	ivd.z = mpl.pz - cam.z;
	/* カメラからミラー面に垂線を下ろした座標 */
	t = (mpl.vx*(mpl.px- cam2.x) + mpl.vy*(mpl.py - cam2.y) + mpl.vz*(mpl.pz - cam2.z))/(mpl.vx*mpl.vx + mpl.vy*mpl.vy + mpl.vz*mpl.vz);
	np.x = mpl.vx*t + cam2.x;
	np.y = mpl.vy*t + cam2.y;
	np.z = mpl.vz*t + cam2.z;

	/* レンダーテクスチャの設定 */
	flag = 0;
	if(((ivd.x*mpl.vx + ivd.y*mpl.vy + ivd.z*mpl.vz) > 0)){
		flag = 1;
		if(((mpl.px*mpl.vx + mpl.py*mpl.vy + mpl.pz*mpl.vz) > 0))	{

			/* ミラーの中心をnpにする*/
			nmpl.vx	= mpl.vx;
			nmpl.vy	= mpl.vy;
			nmpl.vz	= mpl.vz;
			nmpl.px	= np.x;
			nmpl.py	= np.y;
			nmpl.pz	= np.z;
			/* スクリーンサイズの変更 */
			_nj_screen_.w = RENDERING_W;
			_nj_screen_.h = RENDERING_H;
			njPushMatrixEx();
			njCameraExLookAt( &cam2, &np, &up );
			njSetScreenDist((_nj_screen_.w/(2.f*MIRROR_W))*njSqrt(((np.x - cam2.x)*(np.x - cam2.x) + (np.y - cam2.y)*(np.y - cam2.y) + (np.z - cam2.z)*(np.z - cam2.z))));
  
			njCalcPoint(NULL,&np,&npd);
			njCalcPoint(NULL,(NJS_POINT3*)&mpl,&mpd);
			njMirror(NULL,&nmpl);
			/* スクリーン中心の移動 */
			_nj_screen_.cx = (npd.x - mpd.x)*(_nj_screen_.w/(2.f*MIRROR_W)) + RENDERING_CENTER_X;
			_nj_screen_.cy = -(npd.y - mpd.y)*(_nj_screen_.h/(2.f*MIRROR_H)) + RENDERING_CENTER_Y;
			njCalcVector(NULL,&sl,&dl);

		    njRotateXYZ(NULL, rotateAng, rotateAng, rotateAng);
			njControl3D( NJD_CONTROL_3D_MIRROR_MODEL  );
			njCnkSetSimpleLight(dl.x,dl.y,dl.z);
		    njCnkSimpleDrawObject( OBJ );
			njPopMatrixEx();
	   	}
	}

	_nj_screen_.w = 640.f;
	_nj_screen_.h = 480.f;
	_nj_screen_.cx = 320.f;
	_nj_screen_.cy = 240.f;
	njSetScreenDist(500.f);

	njPushMatrixEx();
	/* ミラーの表示 */
	njCameraExLookAt( &cam, &center, &up );
	
	njTranslate( NULL, mpl.px, mpl.py, mpl.pz );
	njRotateXYZ( NULL, 0, RY, 0 );
	
	njRenderTextureNum(1);
	njStartDraw();

	if(flag){
		/* 表 */
		njSetTextureNum(1);
		njDrawTexture3DEx( p, 4, FALSE );
	}
	else{
		/* 裏 */
		njDrawPolygon3DEx( p0, 4, FALSE );
	}

	ts.x = 1.f;
	ts.y = 1.f;
	ts.z = 0;
	njPopMatrixEx();
	/* Teapotの表示 */
	njPushMatrixEx();
	njCameraExLookAt( &cam, &center, &up );
	njControl3D( 0 );
	njCalcVector(NULL,&sl,&dl);
	njCnkSetSimpleLight(dl.x,dl.y,dl.z);
    njRotateXYZ(NULL, rotateAng, rotateAng, rotateAng);
    njCnkSimpleDrawObject( OBJ );
	njPopMatrixEx();

    rotateAng += 171;
    /* サンプル名の表示 */
#if DEBUG	
 	njPrint( NJM_LOCATION( 2,2 ), "Ninja2 RenderTexture Sample%d", cnt++ );
#endif
	return USER_CONTINUE;
}


