📄 camera.cpp
字号:
vu.z += z*vr.z; // suradnicovy system sa otoci proti smeru hodinovych ruciciek
Normalise(&vu); // normalizacia vektora
CROSSPROD(vd,vu,vr);
Normalise(&vr);
}
}
/*
void Camera::WalkRotate(float x, float y, float z)
{
// WalkRotate - rotacia, ktora sa vyuziva pri chodeni (walk) v bludisku
// pri tejto rotacii sa rotuje vzdy okolu osi y t.j. v pripade ze sa pozerame prave v smere
// osi y (hore, alebo dole) tak sa scena otaca okolo vlastnej osi (neposuva sa vpravo alebo vlavo)
// v pripade ze sa otacanim dole alebo hore vektory vd a vu velmi priblizia moze vypocitana
// transformacna matica byt nulova, co sposoby ze na obrazovke nic neuvidime, treba zabranit otacaniu ked su vd a vu velmi blizko
// 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
XYZ vr; // vr - vector right - vektor smerujuci v pravo
CROSSPROD(vd,vu,vr); // vektorovy sucin vd x vu = vr - vektor smerujuci vpravo
Normalise(&vr); // normalizacia vektora
// 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
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
vu.z += z*vr.z; // suradnicovy system sa otoci proti smeru hodinovych ruciciek
Normalise(&vu); // normalizacia vektora
}
}*/
void Camera::WalkRotate(float x, float y, float z)
{
// WalkRotate - rotacia, ktora sa vyuziva pri chodeni (walk) v bludisku
// pri tejto rotacii sa rotuje vzdy okolu osi y t.j. v pripade ze sa pozerame prave v smere
// osi y (hore, alebo dole) tak sa scena otaca okolo vlastnej osi (neposuva sa vpravo alebo vlavo)
// v pripade ze sa otacanim dole alebo hore vektory vd a vu velmi priblizia moze vypocitana
// transformacna matica byt nulova, co sposoby ze na obrazovke nic neuvidime, treba zabranit otacaniu ked su vd a vu velmi blizko
// 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
float angle; // uhol
float vel0,vel1;
XYZ vd_,vr_,p;
vd_ = vd;
angle = (float) atan(-x); // uhol o ktory mame otocit
//angle = (float) asin(-x); // uhol o ktory mame otocit
// otocime okolo osi y, vpravo a vlavo vd
vd.x = vd_.z*(float)sin(angle) + vd_.x*(float)cos(angle);
// vd.y = vd_.y;
vd.z = vd_.z*(float)cos(angle) - vd_.x*(float)sin(angle);
Normalise(&vd); // normalizacia vektora, aby (velkost) ||vd||=1
vr_ = vr;
// otocime okolo osi y, vpravo a vlavo vr_
vr.x = vr_.z*(float)sin(angle) + vr_.x*(float)cos(angle);
// vr.y = vr_.y;
vr.z = vr_.z*(float)cos(angle) - vr_.x*(float)sin(angle);
Normalise(&vr_); // normalizacia vektora, aby (velkost) ||vd||=1
CROSSPROD(vr,vd,vu); // vektorovy sucin vd x vu = vr - vektor smerujuci vpravo
Normalise(&vu); // normalizacia vektora
vd_ = vd;
p.x = y*vu.x; // vr - vektor smerujuci vpravo - v smere osi x
p.y = 0; // vu - (up) hore smerujuci vektor - v smere osi y
p.z = y*vu.z; //
vel0 = (float) sqrt(p.x * p.x + p.y * p.y + p.z * p.z); // o kolko sa otoci
p = vd;
p.y = 0;
vel1 = (float) sqrt(p.x * p.x + p.y * p.y + p.z * p.z); // kolko chyba k osi
vd.x += y*vu.x; // vr - vektor smerujuci vpravo - v smere osi x
vd.y += y*vu.y; // vu - (up) hore smerujuci vektor - v smere osi y
vd.z += y*vu.z; //
Normalise(&vd); // normalizacia vektora, aby (velkost) ||vd||=1
if(vel0>=vel1) // prekroci y
{
if(vd_.y>0 && y>0)
{
vd.x = 0;
vd.y = 1;
vd.z = 0;
}
if(vd_.y<0 && y<0) // smeruje k osi y
{
vd.x = 0;
vd.y =-1;
vd.z = 0;
}
}
if(vd_.x==0 && vd_.z==0 && (vd_.y==1 || vd_.y==-1) )
{
if(y>0 && vd_.y==1)
{
vd.x = 0;
vd.y = 1;
vd.z = 0;
}
else
if(y<0 && vd_.y==-1)
{
vd.x = 0;
vd.y =-1;
vd.z = 0;
}
}
CROSSPROD(vr,vd,vu); // vektorovy sucin vd x vu = vr - vektor smerujuci vpravo
Normalise(&vu); // normalizacia vektora
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
vu.z += z*vr_.z; // suradnicovy system sa otoci proti smeru hodinovych ruciciek
Normalise(&vu); // normalizacia vektora
CROSSPROD(vd,vu,vr);
Normalise(&vr);
}
}
void Camera::Translate(float x,float y,float z)
{
// funkcia posunie suradnicovy sustavu tak, ze ak
// x > 0 posun do lava, y > 0 posun dole, z > 0 posun do obrazovky (v smere vd)
vp.x += x*vr.x + y*vu.x + z*vd.x;
vp.y += x*vr.y + y*vu.y + z*vd.y;
vp.z += x*vr.z + y*vu.z + z*vd.z;
}
void Camera::MoveWorld(float fps,Mode mod)
{
POINT MouseBod;
float mys_x,mys_y,step;
if(keys[VK_SHIFT])step=1.0f/fps;else step=5.0f/fps;
if(keys['R']){ Reset(); keys['R']=0; }
if (keys[VK_UP] || keys[VK_LBUTTON]) Translate(0,0,step);
if (keys[VK_DOWN] || keys[VK_RBUTTON])Translate(0,0,-step);
if (keys[VK_HOME]) Translate(0,step,0);
if (keys[VK_END])Translate(0,-step,0);
if (keys[VK_INSERT]) Translate(step,0,0);
if (keys[VK_DELETE])Translate(-step,0,0);
GetCursorPos(&MouseBod);
SetCursorPos(screen_x/2,screen_y/2);
mys_x = ((float)MouseBod.x - (float)screen_x/2)/200.0f;
mys_y = ((float)MouseBod.y - (float)screen_y/2)/200.0f;
if (keys[VK_NEXT]) mys_y +=-0.3f * step; //Page Down
else if(keys[VK_PRIOR]) mys_y += 0.3f * step; //Page Up
if (keys[VK_RIGHT])mys_x += 0.3f * step;
else if(keys[VK_LEFT]) mys_x +=-0.3f * step;
if(mod==Walk || mod==walk)WalkRotate( mys_x, -mys_y, 0);
else FlyRotate( mys_x, -mys_y, 0);
DerivateMatrix();
}
void Camera::Push(void)
{
if(stack_pointer==NULL)
{
stack_pointer = new position;
stack_pointer->vp = vp;
stack_pointer->vd = vd;
stack_pointer->vu = vu;
stack_pointer->next = NULL;
}
else
{
position *pom;
pom = stack_pointer;
while(pom->next!=NULL) pom = pom->next;
pom->next = new position;
if(pom->next!=NULL)
{
pom = pom->next;
pom->vp = vp;
pom->vd = vd;
pom->vu = vu;
pom->next = NULL;
}
}
}
void Camera::Pop(void)
{
if(stack_pointer==NULL)return;
{
position *pom;
int i=0;
pom = stack_pointer;
while(pom->next!=NULL) {pom = pom->next; i++;}
vp = pom->vp;
vd = pom->vd;
vu = pom->vu;
delete pom;
if(i==0)stack_pointer = NULL;
else
{
pom = stack_pointer;
i--;
while(i!=0){pom = pom->next; i--;}
pom->next = NULL;
}
}
}
void Camera::PrintVector(Font* font,int stlpec,int riadok) // vypise vektory na poziciu riadok, stlpec
{
char text[30];
font->glPrint(stlpec,riadok,"pozicia vp:",0);
gcvt( (double)vp.x, 2, text);
font->glPrint(stlpec+12,riadok, text, 0);
gcvt( (double)vp.y, 2, text);
font->glPrint(stlpec+22,riadok, text, 0);
gcvt( (double)vp.z, 2, text);
font->glPrint(stlpec+32,riadok, text, 0);
gcvt( (double)sqrt(vp.x*vp.x + vp.y*vp.y + vp.z*vp.z), 3, text);
font->glPrint(stlpec+39,riadok,"velkost:",0);
font->glPrint(stlpec+49,riadok,text,0);
font->glPrint(stlpec,riadok+1,"smerov. vd:",0);
gcvt( (double)vd.x, 2, text);
font->glPrint(stlpec+12,riadok+1, text, 0);
gcvt( (double)vd.y, 2, text);
font->glPrint(stlpec+22,riadok+1, text, 0);
gcvt( (double)vd.z, 2, text);
font->glPrint(stlpec+32,riadok+1, text, 0);
font->glPrint(stlpec,riadok+2,"up vek. vu:",0);
gcvt( (double)vu.x, 2, text);
font->glPrint(stlpec+12,riadok+2, text, 0);
gcvt( (double)vu.y, 2, text);
font->glPrint(stlpec+22,riadok+2, text, 0);
gcvt( (double)vu.z, 2, text);
font->glPrint(stlpec+32,riadok+2, text, 0);
}
float Camera::Distance()
{
return (float) sqrt(vp.x*vp.x + vp.y*vp.y + vp.z*vp.z);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -