www.pudn.com > ·ÉÐÐÆ÷Ä£Äâ.rar > 3dTWnd.cpp


// 3dTWnd.cpp : implementation file 
// 
 
 
/*********************************************************** 
***          LOGIX RC FLIGHT SIMULATOR v0.1              *** 
***           Copyright Keir Gordon, 2000                *** 
***    for more information please contact me at         *** 
***                logix@ionet.net                       *** 
***	                  or visit	                         *** 
***	          http://logixdev.cjb.net	                 *** 
***********************************************************/  
 
 
#include "stdafx.h" 
#include "Basic.h" 
#include "3dTWnd.h" 
#include  
#include  
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
#define thr_min = 0 
#define thr_max = 100 
#define PI 3.14159265358 
 
static C3dImage image; 
static C3dVector d(0,0,20); 
int thr=0, speed=0, key=1, fkey=1 ; 
double thrt=0, elvt=0, alrn=0, rudd=0, xdir=1.0, ydir=-3.8, zdir=0, xpos=0, ypos=0, zpos=20, theta=0, phi=0, psi=0, p=0, q=0, r=0, stheta=0, sphi=0, spsi=0, ctheta=0, cphi=0, cpsi=0, dx=0, dy=0, dz=0, ux=0, uy=0, uz=0, pstab=0,  qstab=0, rstab=0; 
 
//There is alot of repetitive stuff in the source, so i dont comment it all, just enough to give you the idea 
 
BOOL C3dTWnd::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)  
{ 
	m_ColorModel = D3DCOLOR_RGB; 
 
	BOOL result = C3dWnd::Create("Logix RC Flight Simulator v0.1", 
									dwStyle,  
									rect.left,  
									rect.top, 
									rect.right,  
									rect.bottom, 
									pParentWnd); 
	 
	pscene = new C3dScene; 
	pscene->Create(); 
 
	// Set ambient light level 
   pscene->SetAmbientLight(0.6, 0.6, 0.6); 
	 
 
		// Add directional light to create highlights 
	static C3dDirLight dl; 
	pfs = new C3dShape;	 
	static C3dShape wing;			//make wing object 
	static C3dShape hstab;			//make the hstab  
	static C3dShape prop1;			//create half the prop 
	static C3dShape prop2;	 
	static C3dShape sphere; 
	static C3dShape land1; 
	static C3dShape land2; 
    static C3dShape runway; 
	static C3dShape w1; 
	static C3dShape w2; 
 
	dl.Create(0.8, 0.8, 0.8);	//creates light 
    pscene->AddChild(&dl);		//add light to scene 
    dl.SetPosition(-2, 2, 5);	//set position 
    dl.SetDirection(1, -2, 1);	//set direction...  
 
	 
	// Create our objects.... 
 
	 
		C3dShape* pfloor = new C3dShape(); 
	D3DVECTOR vlist[] = { 
						{-500.0, -6.0, -500.0}, 
						{-500.0, -6.0,  500.0}, 
						{ 500.0, -6.0,  500.0}, 
						{ 500.0, -6.0, -500.0} 
											}; 
 
	int iVectors = sizeof(vlist)/sizeof(D3DVECTOR); 
	int iFaces[] = {4,0,1,2,3, 4,0,3,2,1,   0}; 
	 
	pfloor->Create(vlist, iVectors, iFaces); 
 
	wing.CreateCuboid(6, 1, 0.2);	//create wing 
	pfs->CreateCuboid(0.9,5,0.9);			//create fus 
	hstab.CreateCuboid(2.3, 0.8, .2);	//create hstab 
	prop1.CreateCuboid(1.6, 0.1, 0.3); 
	prop2.CreateCuboid(1.6, 0.1, 0.3); 
	land1.CreateCuboid(.6, .03, .03); 
	land2.CreateCuboid(.6, .04, .04); 
	runway.CreateCuboid(15, 50, .3); 
	w1.CreateCuboid(.4,.1,.4); 
	w2.CreateCuboid(.4,.1,.4); 
 
	//Add our objects to scene 
	pscene->AddChild(pfs);			 
	pfs->AddChild(&wing);			 
	pfs->AddChild(&hstab);			 
	pfs->AddChild(&prop1); 
	pfs->AddChild(&land1); 
	pfs->AddChild(&land2); 
	prop1.AddChild(&prop2); 
	pscene->AddChild(pfloor); 
	pscene->AddChild(&runway); 
	land1.AddChild(&w1); 
	land2.AddChild(&w2); 
 
	//set the position of objects 
	prop1.SetPosition(0, 2.6, 0); 
	wing.SetPosition(0, 1, .3); 
	pfs->SetPosition(0, -5.5, 40); 
	hstab.SetPosition(0, -2.5, -0.6); 
	land1.SetPosition(1.5,1,.6); 
	land2.SetPosition(-1.5,1,.6); 
	runway.SetPosition(0, -2, 40); 
	land1.SetDirection(0,1,0); 
	land2.SetDirection(0,1,0); 
	runway.SetDirection(0,3,0,0.5,0,0.5); 
	w1.SetPosition(.3,0,0); 
	w2.SetPosition(.3,0,0); 
	 
	//Set some colors.... 
	wing.SetColor(255,0,0); 
	pfs->SetColor(0, 255, 0); 
	hstab.SetColor(255, 0, 0); 
	prop1.SetColor(100, 50, 0); 
	prop2.SetColor(100, 50, 0); 
	pscene->SetBackground(0.8 ,0.8, 1); 
	pfloor->SetFaceColor(1,0,0,1); 
	runway.SetColor(.5, .5, .5); 
	land1.SetColor(1,0,0); 
	land2.SetColor(1,0,0); 
 
//  Load a texture for the ground 
	C3dTexture* pTex = new C3dTexture; 
	pTex->Load("c:/windows/desktop/terrain.bmp"); 
 
	pscene->m_ImgList.Append(pTex); 
	pfloor->SetFaceTexture(0, pTex); 
 
	C3dWrap wrap; 
	wrap.Create(D3DRMWRAP_FLAT, NULL, -500.0, -2.0, -500.0, 5, -1, 0, 0, 0, 1, 0, pTex->GetHeight()-1, 0.5, -0.5); 
	wrap.Apply(pfloor, 0); 
 
	pfloor->SetName("Ground"); 
	pscene->AddChild(pfloor); 
	pscene->m_ShapeList.Append(pfloor); 
//	MakeCurrent(pfloor); 
	 
//	sphere.SetColor(50,100,40); 
	//ROTATION AND DIRECTION OF OBJECTS 
//	pfs->SetDirection(1, -3.8, 0); 
	prop2.SetDirection(3, 0, 0); 
	prop1.SetRotation(0, -7, 0, 0.12); 
//	pscene->SetRotation( 0,7,0,0.02); 
	//horizontal spin -->	fs.SetRotation(0, 7, 0, 0.01); 
	//vertical spin --> 		fs.SetRotation(7, 0, 0, 0.015); 
	 
		 
	// Attach entire scene to the stage 
	SetScene(pscene); 
//	pscene->SetBackground(&image); 
	D3DVECTOR CamPos = {0.0,0.0,0.0}; 
	pscene->SetCameraPosition(CamPos); 
	pscene->SetCameraDirection(d); 
	 
 
	// Create a background 
//	BckgrdTexture.Load(IDB_BITMAP2); 
//	BckgrdTexture.Load("c:/windows/desktop/scratch.bmp"); 
 
//	pscene->m_ImgList.Append(&BckgrdTexture); 
//	pBckgrdFace = new C3dShape(); 
//	 
//	 
//	pBckgrdFace->Create( vlist, nVectors, iFaces ); 
//	pBckgrdFace->GetMeshBuilder()->SetPerspective(TRUE); 
 
//	pBckgrdFace->SetFaceColor(1,0,0,1); 
//	pBckgrdFace->SetFaceTexture( 0, &BckgrdTexture); 
//	BckgrdWrap.Create( D3DRMWRAP_FLAT, NULL, 
//							-512.,-256.,0., //origin 
//							0.,0.,1.,  //direction 
//							0.,1.,0.,  //up 
//							0.,BckgrdTexture.GetHeight()-1, //texture origin 
//							0.5/BckgrdTexture.GetWidth(),-0.5/BckgrdTexture.GetHeight()); //texture scale 
//	BckgrdWrap.Apply( pBckgrdFace, 0 ); 
 
//	pscene->AddChild( pBckgrdFace ); 
//	pscene->m_ShapeList.Append( pBckgrdFace ); 
 //  pBckgrdFace->SetPosition( 0,-0,500); 
//   pBckgrdFace->SetRotation( 1,0,0,.04); 
 
	 
	return result; 
	 
	 
	return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// C3dTWnd 
 
C3dTWnd::C3dTWnd() 
{ 
} 
 
C3dTWnd::~C3dTWnd() 
{ 
} 
 
 
BEGIN_MESSAGE_MAP(C3dTWnd, C3dWnd) 
	//{{AFX_MSG_MAP(C3dTWnd) 
	ON_WM_TIMER() 
	ON_WM_KEYDOWN() 
	ON_WM_KEYUP() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
 
///////////////////////////////////////////////////////////////////////////// 
// C3dTWnd message handlers 
 
 
void C3dTWnd::OnTimer(UINT nIDEvent)  
{ 
	control(); 
	Motion(); 
	SetScreen(); 
	Update(1); 
	C3dWnd::OnTimer(nIDEvent); 
} 
 
 
void C3dTWnd::OnStartTimer(int interval)  
{ 
	m_nTimer = SetTimer(1, interval, 0); 
} 
 
 
void C3dTWnd::OnStopTimer()  
{ 
	KillTimer(m_nTimer);    
} 
 
 
void C3dTWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)  
{ 
	if (key==1) key = nChar; 
	C3dWnd::OnKeyDown(nChar, nRepCnt, nFlags); 
} 
 
 
void C3dTWnd::control() 
{ 
	switch (key) 
	{ 
		case VK_LEFT: alrn = -0.15; 
			break; 
		case VK_RIGHT: alrn = 0.15; 
			break; 
		case VK_UP: elvt = -0.15; 
			break; 
		case VK_DOWN: elvt = 0.15; 
			break; 
		case 0x39: thrt = thrt + 0.04; 
			break; 
		case 0x38: thrt = thrt - 0.04; 
			break; 
		case 0x31: rudd = -0.15; 
			break; 
		case 0x32: rudd = 0.15; 
			break; 
	} 
} 
 
void C3dTWnd::Motion() 
{  
	//Alot of complex trig, takes place here, i dont think its worth explaining, if you would like 
	// an explanation, please email me and i'll give you all the details. 
 
	stheta = sin(theta); 
	sphi = sin(phi); 
	spsi = sin(psi); 
	ctheta = cos(theta); 
	cphi = cos(phi); 
	cpsi = cos(psi); 
	 
	if (cphi < 0)  
		pstab = 0.0;  
	else  
		pstab = -0.0008*phi; 
	if (pstab > 0.00035) pstab = 0.00035; 
	if (pstab < -0.00035) pstab = -0.00035; 
 
	 
	p = alrn*0.01 + pstab; 
	q = elvt*0.01*cphi - theta * 0.0004 - fabs(sphi)*0.0003; 
	r = rudd*0.002 + elvt *0.01 * sphi; 
 
	theta = theta + q * 50; 
	phi = phi + p * 50; 
	psi = psi + r * 50; 
	 
	if (phi >  3.14159) phi -= 2*3.14159;  
	if (phi < -3.14159) phi += 2*3.14159; 
	//TRACE("%f %f %f\n",theta*(3.14/180.),phi*(3.14/180.),psi*(3.14/180.)); 
 
	double m[3][3]; 
	m[0][0] = ctheta * cpsi; 
//	m[0][1] = sphi * stheta * cpsi - cphi * spsi; 
	m[0][2] = cphi * stheta * cpsi + sphi * spsi; 
	m[1][0] = ctheta * spsi; 
//	m[1][1] = sphi * stheta * spsi + cphi * cpsi; 
	m[1][2] = cphi * stheta * spsi - sphi * cpsi; 
	m[2][0] = -stheta; 
//	m[2][1] = sphi * ctheta; 
	m[2][2] = cphi * ctheta; 
 
	int i = 2; 
	int j = 0; 
 
	dz =  m[0][i]; 
	dx =  m[1][i]; 
	dy = -m[2][i]; 
 
	uz =  m[0][j]; 
	ux =  m[1][j]; 
	uy = -m[2][j]; 
 
	alrn = 0; 
	elvt = 0; 
	rudd = 0;	 
} 
 
static double vx,vy,vz; 
static double xe = -5.0; 
static double ye = 0.0; 
static double ze = 20.0; 
static double airx=0, airy=0, camx=0, camy=0, offsetx=0, offsety=0, camlenx=0, camleny=0; 
 
void C3dTWnd::SetScreen() 
{ 
 
	vx = ux * thrt*5; 
	vy = uy * thrt*5; 
	vz = uz * thrt*5; 
	xe += vx*0.05; 
	ye += vy*0.05; 
	ze += vz*0.05; 
 
	pfs->SetPosition(xe,ye,ze); 
 
	pfs->SetDirection(dx, dy, dz, ux, uy, uz); 
	pfs->GetPosition(xpos, ypos, zpos); 
	if (ypos <-1.5) KillTimer(m_nTimer); 
 
	//d.x = xpos;//xpos; 
	//d.y = ypos;//ypos; 
	//d.z = zpos;//zpos; 
	 
	 
	airx = atan2(xe,ze); 
	double dHorz = sqrt( xe*xe+ze*ze ); 
	airy = atan2(dHorz,ye); 
	camx = atan2(d.x,d.z); 
	dHorz = sqrt( d.x*d.x+d.z*d.z); 
	if ( dHorz != 0.0 ) camy = atan2(dHorz,d.y); 
	if ( airx < 0.0 && camx > 0.0 ) camx -= 2*PI; 
	if ( airx > 0.0 && camx < 0.0 ) camx += 2*PI; 
 
	offsetx = airx-camx; 
	if ( offsetx < PI ) offsetx += 2*PI; 
	if ( offsetx > PI ) offsetx -= 2*PI; 
 
	offsety = airy-camy; 
 
	double airxd = airx * 180./ PI; 
	double airyd = airy * 180./ PI; 
 
	if (offsetx > 0.3)  
	{ 
		camx = airx - 0.3; 
		camlenx = sqrt(d.x*d.x+d.z*d.z); 
		d.x = camlenx*sin(camx); 
		d.z = camlenx*cos(camx); 
 
	} 
 
	if (offsetx < -0.3)  
	{ 
		camx = airx + 0.3; 
		camlenx = sqrt(d.x*d.x+d.z*d.z); 
		d.x = camlenx*sin(camx); 
		d.z = camlenx*cos(camx); 
	} 
	 
	if (offsety > 0.1) 
	{ 
		camy = airy - 0.1; 
		camleny = sqrt(d.y*d.y+d.z*d.z+d.x*d.x); 
		d.y = camleny*cos(camy); 
	} 
 
	if (offsety < -0.3) 
	{ 
		camy = airy + 0.3; 
		camleny = sqrt(d.y*d.y+d.z*d.z+d.x*d.x); 
		d.y = camleny*cos(camy); 
	} 
 
	if (!d.IsNull()) 
	{ 
		pscene->SetCameraDirection(d); 
	} 
 
	 
} 
 
 
void C3dTWnd::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)  
{ 
	fkey = nChar; 
	if (fkey == key) key = 1;	 
	C3dWnd::OnKeyUp(nChar, nRepCnt, nFlags); 
}