⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 camera.cpp

📁 motion_blur using opengl
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "camera.h"
void Camera::Normalise(XYZ *p)
{
	float length;

	length = (float) sqrt(p->x * p->x + p->y * p->y + p->z * p->z);
	if (length != 0) {
		p->x /= length;
		p->y /= length;
		p->z /= length;
	} else {
		p->x = 0;
		p->y = 0;
		p->z = 0;
	}
}

void Camera::Normalise(float *x, float *y, float *z)
{
	float length;

	length = (float) sqrt( (*x)*(*x) + (*y)*(*y) + (*z)*(*z));
	if (length != 0) 
	{
		*x /= length;			// *x = hodnota z adresy x, x - smernik, adresa
		*y /= length;
		*z /= length;
	}	
	else 
	{
		*x = 0;
		*y = 0;
		*z = 0;
	}
}

void Camera::DerivateMatrix(void)
{
	glLoadIdentity();
	gluLookAt(vp.x, vp.y, vp.z,  vd.x+vp.x, vd.y+vp.y, vd.z+vp.z, vu.x, vu.y, vu.z);
}

void Camera::d(void)
{
	glLoadIdentity();
	gluLookAt(vp.x, vp.y, vp.z,  vd.x+vp.x, vd.y+vp.y, vd.z+vp.z, vu.x, vu.y, vu.z);
}

Camera::Camera(void)
{
	Reset();
	stack_pointer = NULL;
	SetCursorPos(screen_x/2,screen_y/2);	// nastavy mys do stredu obrazovky , je mozne to vypnut
}

Camera::~Camera(void)
{
	if(stack_pointer==NULL)return;
	{
		position	*pom;			// pomocny smernik
		int		i=0,j;
		pom = stack_pointer;
		while(pom->next!=NULL) {pom = pom->next; i++;}	// po skonceni v i bude pocet alokovanych struktur - 1
		while(i>0)						// v kazdom cykle uvolnime poslednu cast spojkoveho zoznamu
		{
			i--;
			pom = stack_pointer;
			for(j=i;j!=0;j--)pom = pom->next;
			delete pom->next;
		}
		delete stack_pointer;
	}
}

void Camera::Reset(void)
{
	vp.x=0.0f;vp.y=0.0f;vp.z=1.5f;
	vd.x=0;vd.y=0;vd.z=-1;
	vu.x=0;vu.y=1;vu.z=0;
	vr.x=1;vr.y=0;vr.z=0;
}

void Camera::RelativeTranslate(float x,float y,float z)
{
	vp.x += x;
	vp.y += y;
	vp.z += z;
}

void Camera::RelativeRotate(float uhol,float x,float y,float z)
{
// rotuje suradnicovu sustavu podla vlastnych osi

/* v - normalizovany vektor v = (x, y, z)	vT - transponovany vektor v
	( 0	-z	 y)		(1	0	0)		(x)				(xx	xy	xz)
S =	( z	 0	-x)	I =	(0	1	0)	vT =(y)		v*vT =	(yx	yy	yz)
	(-y	 x	 0)		(0	0	1)		(z)				(zx	zy	zz)
A = v*vT + cos(uhol)*(I-v*vT) + sin(uhol)*S			*/

	// Najprv vypocitame rotacnu maticu	
	float	a[9];
	float	c,s;

	Normalise(&x, &y, &z);
	c = (float) cos(uhol*PI180);
	s = (float) sin(uhol*PI180);
	a[0] = x*x + c*(1-x*x);				//		(	a0	3	a6	)
	a[1] = x*y + c*(0-x*y) + s*z;		//	A =	(	a1	a4	a7	)
	a[2] = x*z + c*(0-x*z) - s*y;		//		(	a2	a5	a8	)
	a[3] = y*x + c*(0-y*x) - s*z;
	a[4] = y*y + c*(1-y*y);
	a[5] = y*z + c*(0-y*z) + s*x;
	a[6] = z*x + c*(0-z*x) + s*y;
	a[7] = z*y + c*(0-z*y) - s*x;
	a[8] = z*z + c*(1-z*z);
	
	// Rotovanie jednotlivych vektorov pomocou rotacnej matice A
	// Kedze pohybujem kamerov musime nou hybat opacne ako sa bude tocit scena
	// preto nebudem nasobit (x,y,z)T * A, ale naopak A * (x,y,z)T
	vp.x = a[0]*vp.x + a[1]*vp.y + a[2]*vp.z;
	vp.y = a[3]*vp.x + a[4]*vp.y + a[5]*vp.z;
	vp.z = a[6]*vp.x + a[7]*vp.y + a[8]*vp.z;

	vd.x = a[0]*vd.x + a[1]*vd.y + a[2]*vd.z;
	vd.y = a[3]*vd.x + a[4]*vd.y + a[5]*vd.z;
	vd.z = a[6]*vd.x + a[7]*vd.y + a[8]*vd.z;
	Normalise(&vd);

	vu.x = a[0]*vu.x + a[1]*vu.y + a[2]*vu.z;
	vu.y = a[3]*vu.x + a[4]*vu.y + a[5]*vu.z;
	vu.z = a[6]*vu.x + a[7]*vu.y + a[8]*vu.z;
	Normalise(&vu);

	CROSSPROD(vd,vu,vr);
	Normalise(&vr);
}

void Camera::RelativeRotatePoint(float uhol,float x,float y,float z, float px, float py, float pz)
{
	vp.x -= px;		// aby sme rotovali okolo bodu (px,py,pz)
	vp.y -= py;		// najprv polohu posunieme do opacneho bodu
	vp.z -= pz;
	RelativeRotate(uhol, x, y, z);
	vp.x += px;		// po rotacii polohu vratime naspat
	vp.y += py;
	vp.z += pz;
}

void Camera::AbsoluteRotate(float x, float y, float z)
{
	float dd;

	// velkost vp
	dd = (float) sqrt(vp.x*vp.x + vp.y*vp.y + vp.z*vp.z);

	vp.x += dd * x * vu.x + dd * y * vr.x;
	vp.y += dd * x * vu.y + dd * y * vr.y;
	vp.z += dd * x * vu.z + dd * y * vr.z;
	Normalise(&vp);

	vp.x *= dd;
	vp.y *= dd;
	vp.z *= dd;

	vr.x = vp.x + vr.x;		// vypocet noveho praveho vektora
	vr.y = vp.y + vr.y;
	vr.z = vp.z + vr.z;
	Normalise(&vr);

	vd.x = - vp.x;			// pozerame na bod 0,0,0
	vd.y = - vp.y;
	vd.z = - vp.z;
	Normalise(&vd);

	CROSSPROD(vr,vd,vu);	// vypocet noveho up vektora
	Normalise(&vu);

	CROSSPROD(vd,vu,vr);
	Normalise(&vr);

	// otocenie kamery okolo osi
	if (z != 0) {
		vu.x += z * vr.x;
		vu.y += z * vr.y;
		vu.z += z * vr.z;
		Normalise(&vu);
		CROSSPROD(vd,vu,vr);
		Normalise(&vr);
	}
}

void Camera::AbsoluteRotatePoint(float x, float y, float z, float px, float py, float pz)
{
	XYZ pr,d;
	float dd;
	
	pr.x = px;
	pr.y = py;
	pr.z = pz;

	// vypocet vzdialenosti k bodu okolo ktoreho sa bude rotovat
	d.x = vp.x - pr.x;
	d.y = vp.y - pr.y;
	d.z = vp.z - pr.z;
	dd = (float) sqrt(d.x*d.x + d.y*d.y + d.z*d.z);

	// vypocet noveho bodu z ktoreho sa pozerame
	vp.x += dd * x * vu.x + dd * y * vr.x - pr.x;
	vp.y += dd * x * vu.y + dd * y * vr.y - pr.y;
	vp.z += dd * x * vu.z + dd * y * vr.z - pr.z;
	Normalise(&vp);
	vp.x = pr.x + dd * vp.x;
	vp.y = pr.y + dd * vp.y;
	vp.z = pr.z + dd * vp.z;

	// vypocet smeroveho vektora
	vd.x = pr.x - vp.x;		// pozerame sa na bod okolo ktoreha sa rotuje
	vd.y = pr.y - vp.y;
	vd.z = pr.z - vp.z;
	Normalise(&vd);

	// vypocet noveho praveho vektora
	vr.x = vp.x - pr.x + vr.x;
	vr.y = vp.y - pr.y + vr.y;
	vr.z = vp.z - pr.z + vr.z;
	Normalise(&vr);
	vr.x = pr.x + dd * vr.x - vp.x;
	vr.y = pr.y + dd * vr.y - vp.y;
	vr.z = pr.z + dd * vr.z - vp.z;

	// vypocet up vektora
	CROSSPROD(vr,vd,vu);		// vektorovy sucin
	Normalise(&vu);

	CROSSPROD(vd,vu,vr);
	Normalise(&vr);

	// otocenie kamery okolo osi
	if (z != 0) {
		vu.x += z * vr.x;
		vu.y += z * vr.y;
		vu.z += z * vr.z;
		Normalise(&vu);
		CROSSPROD(vd,vu,vr);
		Normalise(&vr);
	}
}

void Camera::AbsoluteRotateDistance(float x, float y, float z, float distance)
{
	AbsoluteRotatePoint(x, y, z, distance*vd.x + vp.x, distance*vd.y + vp.y, distance*vd.z + vp.z);
}

void Camera::FlyRotate(float x, float y, float z)
{
// FlyRotate - rotacia, ktora zabezpecuje volny pohyb (Fly - lietanie), surad. sustava (myslim tym osi x,y,z vykreslene po tejto transformacii) 
// sa rotuje tak, ze sa otaca vzdy oko osi horizontalne (x) a vertikalnej (y)

	// v pripade ze mame vp = {0,0,5}, vd = {0,0,-1} a vp = {0,1,0} tak pre
	// x > 0 sa suradnicova sustava posunie dolava t.j. kamera sa otoci doprava
	// x < 0                                doprava                     dolava
	// y > 0 sa suradnicova sustava posunie dole t.j. kamera sa otoci hore
	// y < 0                                hore                      dole
	// z > 0 sa suradnicova sustava otoci proti smeru hodinovych ruciciek
	// z < 0                              v     smere

	
	/* zmenime poluhu smeroveho (direction) vektora tak, 
	ze k nemu pripocitame cast vektora kolmeho na nho v danom smere */
	vd.x += x*vr.x + y*vu.x;	// vr - vektor smerujuci vpravo - v smere osi x
	vd.y += x*vr.y + y*vu.y;	// vu - (up) hore smerujuci vektor - v smere osi y
	vd.z += x*vr.z + y*vu.z;	// 
	Normalise(&vd);				// normalizacia vektora, aby (velkost) ||vd||=1
	
	CROSSPROD(vr,vd,vu);		// vypocitame novy vu vektor a to pomocu vekoroveho sucinu
	Normalise(&vu);				// vektora smerom vpravo a dopredu
	
	CROSSPROD(vd,vu,vr);
	Normalise(&vr);

	if(z!=0)					// v pripade ze chceme kameru rotovat v smere osi
	{
		vu.x += z*vr.x;			// k vektoru smerujucemu hore pripocitame cast vektora
		vu.y += z*vr.y;			// smerujuceho vpravo, tym sa vektor vu otoci vpravo a 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -