void PPC::setNearAndFarPoints(){ //Vector3D cNear = (c.normalize()*zNear*GetVD().length())/(c.normalize()*GetVD()); //Vector3D cFar = (c.normalize()*zFar*GetVD().length())/(c.normalize()*GetVD()); if(!frustum){ frustum = new Vector3D[8]; frustumf = new float(24); } /*for(int i = 0; i < 3; i++){ if(abs(a[i]) < 0.000001){ a[i] = 0; } if(abs(b[i]) < 0.000001){ b[i] = 0; } if(abs(c[i]) < 0.000001){ c[i] = 0; } if(abs(C[i]) < 0.000001){ C[i] = 0; } }*/ Vector3D VDNear, VDFar; float wNear, wFar, hNear, hFar; Vector3D n0, n1, n2, n3, f0, f1, f2, f3; VDNear = GetVD() * zNear; //Vector from eye to center of near plane VDFar = GetVD() * zFar; //Vector from eye to center of far plane wNear = 2.0f*zNear*tan(hfovR/2.0f); //width of near plane wFar = 2.0f*zFar*tan(hfovR/2.0f); //width of far plane hNear = wNear*((float)h)/((float)w); //height of near plane hFar = wFar*((float)h)/((float)w); //height of far plane n0 = C + VDNear - (wNear/2.0f) * a.normalize() - (hNear/2.0f) * b.normalize(); //top left near n1 = n0 + hNear * b.normalize(); //bottom left near n2 = n1 + wNear * a.normalize(); //bottom right near n3 = n0 + wNear * a.normalize(); //top right near f0 = C + VDFar - (wFar/2.0f) * a.normalize() - (hFar/2.0f) * b.normalize(); //top left far f1 = f0 + hFar * b.normalize(); //bottom left far f2 = f1 + wFar * a.normalize(); //bottom right far f3 = f0 + wFar * a.normalize(); //top right far frustum[0] = n0; frustum[1] = n1; frustum[2] = n2; frustum[3] = n3; frustum[4] = f0; frustum[5] = f1; frustum[6] = f2; frustum[7] = f3; }
void PPC::Tilt(float rs){ if(rs == 0){ return; } a = a.rotate(GetVD().normalize(), rs); b = b.rotate(GetVD().normalize(), rs); c = c.rotate(GetVD().normalize(), rs); //setNearAndFarPoints(); SetPMat(); }
/** * Interpolate between two cameras and generate N intermediate cameras. * * @param ppc another camera * @param N the number of generated cameras * @param cameras the generated cameras */ PPC PPC::Interpolate(const PPC &ppc, float frac) const { PPC ret = *this; V3 vd = GetVD(); V3 newC = C + (ppc.C - C) * frac; V3 newvd = (vd + (ppc.GetVD() - vd) * frac).UnitVector(); V3 newa = (a + (ppc.a - a) * frac).UnitVector() * a.Length(); ret.Set(newC, newa, newvd); return ret;//PPC(GetHFOV(), w, h, newC, newa, newvd); }
void PPC::Translate(char dir, float ts){ if(ts == 0){ return; } switch(dir){ case 'l':{ C = C - a.normalize() * ts; break; } case 'r':{ C = C + a.normalize() * ts; break; } case 'u':{ C = C - b.normalize() * ts; break; } case 'd':{ C = C + b.normalize() * ts; break; } case 'f':{ C = C + GetVD().normalize() * ts; break; } case 'b':{ C = C - GetVD().normalize() * ts; break; } default:{ cerr << "Invalid key" << endl; } } //setNearAndFarPoints(); }
void PPC::zoom(float s, char S){ if(s == 0.0f){ return; } if(S == 'o'){ s = 1.0f/s; } float f = Getf(); float newf = f*s; Vector3D newc = newf * GetVD() + (float) w / 2.0f * (-1.0f * a) + (float)h / 2.0f * (-1.0f * b); c = newc; //setNearAndFarPoints(); SetPMat(); }
void PPC::SetExtrinsicsHW(){ Vector3D LAP = C + GetVD(); Vector3D up = (b*-1.0f).normalize(); glLoadIdentity(); gluLookAt(C[0], C[1], C[2], LAP[0], LAP[1], LAP[2], up[0], up[1], up[2]); }
void PPC::Print(){ cout << "a: " << a << "\tb: " << b << "\tc: " << c << "\tC: " << C << "\tVD: " << GetVD() << endl; }
float PPC::Getf(){ return GetVD() * c; }
/** * Change the focal length to the specified length. * * @param len the new focal length */ void PPC::SetFocalLength(float len) { c = GetVD() * len - a * ((float)w/2.0f) - b * ((float)h/2.0f); SetPMat(); }
void PPC::Roll(float angle) { a = a.RotateAbout(GetVD(), -angle); b = a.RotateAbout(GetVD(), -angle); c = a.RotateAbout(GetVD(), -angle, C); SetPMat(); }
void PPC::TranslateFB(float step) { C = C + GetVD() * step; }
float PPC::GetFocalLength() const { return GetVD() * c; }