void PerspectiveCamera::setCameraForSelection(int x,int y,int selectionWidth,int selectionHeight,float width,float height,float ratio)
{
	GLint viewport[4];
	glGetIntegerv(GL_VIEWPORT,viewport);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
/*
	glColor3ub(255,0,0);
	glBegin(GL_QUADS);
	glVertex2f(-1,-1);
glVertex2f(-1,1);
glVertex2f(1,1);
glVertex2f(1,-1);
	glEnd();
*/


	gluPickMatrix(x+selectionWidth*0.5f,viewport[3]-y-selectionHeight*0.5f,selectionWidth,selectionHeight,viewport);

	gluPerspective(fov(), ratio, nearPlane(), farPlane());
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(from()[0],from()[1],from()[2] ,to()[0],to()[1], to()[2],up()[0],up()[1],up()[2]);
}
void PerspectiveCamera::setCamera(float width,float height,float ratio)
{
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	//qDebug("%f,%f,",nearPlane(),farPlane());
	gluPerspective(fov(), ratio, nearPlane(), farPlane());
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(from()[0],from()[1],from()[2] ,to()[0],to()[1], to()[2],up()[0],up()[1],up()[2]);
}
void PerspectiveCamera::save(const QString &filename)
{
        FILE *fp=fopen(filename.toStdString().c_str(),"wb");

	float sfov=fov();

	float sfarPlane=farPlane();
	float snearPlane=nearPlane();

	GGL::Point3f sfrom=from();
	GGL::Point3f sto=to();
	GGL::Point3f sup=up();


	fwrite(&sfov,sizeof(float),1,fp);
	fwrite(&sfarPlane,sizeof(float),1,fp);
	fwrite(&snearPlane,sizeof(float),1,fp);

	float vsfrom[3];
	vsfrom[0]=from().X();
	vsfrom[1]=from().Y();
	vsfrom[2]=from().Z();

	fwrite(vsfrom,sizeof(float),3,fp);

	float vsto[3];
	vsto[0]=to().X();
	vsto[1]=to().Y();
	vsto[2]=to().Z();

	fwrite(vsto,sizeof(float),3,fp);

	float vsup[3];

	vsup[0]=up().X();
	vsup[1]=up().Y();
	vsup[2]=up().Z();


	fwrite(vsup,sizeof(float),3,fp);


	fclose(fp);
}
예제 #4
0
/**
 * @brief cwOrthogonalProjection::calculateProjection
 * @return
 */
cwProjection cwOrthogonalProjection::calculateProjection()
{
    cwProjection proj;
    if(projection().isNull()) {
        proj = viewer()->orthoProjectionDefault();
        setPrivateFarPlane(proj.far());
        setPrivateNearPlane(proj.near());
    } else {
        proj = projection();
    }


    cwProjection viewProj = viewer()->orthoProjectionDefault();
    proj.setOrtho(viewProj.left(), viewProj.right(),
                  viewProj.bottom(), viewProj.top(),
                  nearPlane(), farPlane());


    return proj;
}
예제 #5
0
bool Frustum::bakeProjectionOffset()
{
   // Nothing to bake if ortho
   if( mIsOrtho )
      return false;

   // Nothing to bake if no offset
   if( mProjectionOffset.isZero() )
      return false;

   // Near plane points in camera space
   Point3F np[4];
   np[0].set( mNearLeft, mNearDist, mNearTop );       // NearTopLeft
   np[1].set( mNearRight, mNearDist, mNearTop );      // NearTopRight
   np[2].set( mNearLeft, mNearDist, mNearBottom );    // NearBottomLeft
   np[3].set( mNearRight, mNearDist, mNearBottom );   // NearBottomRight

   // Generate the near plane
   PlaneF nearPlane( np[0], np[1], np[3] );

   // Far plane points in camera space
   const F32 farOverNear = mFarDist / mNearDist;
   Point3F fp0( mNearLeft * farOverNear, mFarDist, mNearTop * farOverNear );     // FarTopLeft
   Point3F fp1( mNearRight * farOverNear, mFarDist, mNearTop * farOverNear );    // FarTopRight
   Point3F fp2( mNearLeft * farOverNear, mFarDist, mNearBottom * farOverNear );  // FarBottomLeft
   Point3F fp3( mNearRight * farOverNear, mFarDist, mNearBottom * farOverNear ); // FarBottomRight

   // Generate the far plane
   PlaneF farPlane( fp0, fp1, fp3 );

   // The offset camera point
   Point3F offsetCamera( mProjectionOffset.x, 0.0f, mProjectionOffset.y );

   // The near plane point we'll be using for our calculations below
   U32 nIndex = 0;
   if( mProjectionOffset.x < 0.0 )
   {
      // Offset to the left so we'll need to use the near plane point on the right
      nIndex = 1;
   }
   if( mProjectionOffset.y > 0.0 )
   {
      // Offset to the top so we'll need to use the near plane point at the bottom
      nIndex += 2;
   }

   // Begin by calculating the offset point on the far plane as it goes
   // from the offset camera to the edge of the near plane.
   Point3F farPoint;
   Point3F fdir = np[nIndex] - offsetCamera;
   fdir.normalize();
   if( farPlane.intersect(offsetCamera, fdir, &farPoint) )
   {
      // Calculate the new near plane edge from the non-offset camera position
      // to the far plane point from above.
      Point3F nearPoint;
      Point3F ndir = farPoint;
      ndir.normalize();
      if( nearPlane.intersect( Point3F::Zero, ndir, &nearPoint) )
      {
         // Handle a x offset
         if( mProjectionOffset.x < 0.0 )
         {
            // The new near plane right side
            mNearRight = nearPoint.x;
         }
         else if( mProjectionOffset.x > 0.0 )
         {
            // The new near plane left side
            mNearLeft = nearPoint.x;
         }

         // Handle a y offset
         if( mProjectionOffset.y < 0.0 )
         {
            // The new near plane top side
            mNearTop = nearPoint.y;
         }
         else if( mProjectionOffset.y > 0.0 )
         {
            // The new near plane bottom side
            mNearBottom = nearPoint.y;
         }
      }
   }

   mDirty = true;

   // Indicate that we've modified the frustum
   return true;
}
예제 #6
0
	Frustum<float> Camera::getFrustum() const
	{
		float hnear, wnear;
		float hfar, wfar;

		hnear = 2 * tanf(fov / 2) * nearDist;
		wnear = hnear * ratio;

		hfar = 2 * tanf(fov / 2) * farDist;
		wfar = hfar * ratio;

		vector3f farCenter = front * farDist;
		vector3f nearCenter = front * nearDist;

		vector3f right = cross(front, up);

		//tworzę wierzchołki
		vector3f ftl = farCenter + (up * hfar / 2) - (right * wfar / 2);
		vector3f ftr = farCenter + (up * hfar / 2) + (right * wfar / 2);
		vector3f fbl = farCenter - (up * hfar / 2) - (right * wfar / 2);
		vector3f fbr = farCenter - (up * hfar / 2) + (right * wfar / 2);

		vector3f ntl = nearCenter + (up * hnear / 2) - (right * wnear / 2);
		vector3f ntr = nearCenter + (up * hnear / 2) + (right * wnear / 2);
		vector3f nbl = nearCenter - (up * hnear / 2) - (right * wnear / 2);
		vector3f nbr = nearCenter - (up * hnear / 2) + (right * wnear / 2);

		//tworzę płaszczyzny
		plane<float> nearPlane(nearCenter, front);
		plane<float> farPlane(farCenter, -front);

		plane<float> rightPlane(vector3f(0, 0, 0), cross(up, (nearCenter + right * wnear / 2).normalized()));
		plane<float> leftPlane(vector3f(0, 0, 0), cross((nearCenter - right * wnear / 2).normalized(), up));

		plane<float> topPlane(vector3f(0, 0, 0), cross((nearCenter + up * hnear / 2).normalized(), right));
		plane<float> bottomPlane(vector3f(0, 0, 0), cross(right, (nearCenter - up * hnear / 2).normalized()));

		/* tu może być komszmarnie dużo błędów, to najbardziej "ludzki" fragment
		 kodu
									  top=3
									   |                                                            
									   v                                                            
                                                                                 
							7___________________6                                               
							/:                 /|                                               
						   / :                / |                                               
						  /  :               /  |                                               
						 /   :              /   |                                               
						/__________________/    |                                               
					   4|    :            5|    |                                               
				4=left->|    :             |    |  <- right =5                                    
						|    :   far=\     |    |                                               
						|    :  rear=1     |    |                                               
						|    :.............|....|                                               
						|   . 3            |   / 2                                              
						|  .               |  /                                                 
						| .                | /                                                  
						|.  front=0=near   |/                                                   
						|__________________/                                                    
						0                  1                                                                        
								^                                                               
								|                                                               
							   bottom=2        

		 */
		std::vector < plane < float >> planes;
		std::vector < vector3f> vertices;
		std::vector<Polyhedron<float>::PolyhedronEdge> edges;


		//KOLEJNOŚĆ ŚCIAN MA ZNACZENIE!
#define pp(_plane) planes.push_back(_plane)
		pp(nearPlane);
		pp(farPlane);
		pp(bottomPlane);
		pp(topPlane);
		pp(leftPlane);
		pp(rightPlane);
#undef pp

		//KOLEJNOŚĆ WIERZCHOŁKÓW MA ZNACZENIE!
#define pv(_vert) vertices.push_back(_vert)
		pv(nbl);
		pv(nbr);
		pv(fbr);
		pv(fbl);
		pv(ntl);
		pv(ntr);
		pv(ftr);
		pv(ftl);
#undef pv

		//kolejność krawędzi nie ma znaczenia
#define pe(v1, v2, p1, p2) edges.push_back(Polyhedron<float>::PolyhedronEdge(v1, v2, p1, p2))

		pe(0, 1, 2, 0); //bottom-front
		pe(1, 2, 2, 5); //bottom-right
		pe(2, 3, 2, 1); //bottom-far
		pe(3, 0, 2, 4); //bottom-left

		pe(0, 4, 4, 0); //left-front
		pe(1, 5, 0, 5); //front-right
		pe(2, 6, 5, 1); //right-far
		pe(3, 7, 1, 4); //far-left

		pe(4, 5, 0, 3); //front-top
		pe(5, 6, 5, 3); //right-top
		pe(6, 7, 1, 3); //far-top
		pe(7, 4, 4, 3); //left-top
#undef pe

		return Frustum<float>(planes, vertices, edges, vector3f(0, 0, 0));
	}
예제 #7
0
void Frustum::Calculate(float angle, float ratio, float near, float far, Vector3 &camPos, Vector3 &lookAt, Vector3 &up)
{
	Vector3		xVec, yVec, zVec;
	Vector3		vecN, vecF;
	Vector3		nearTopLeft, nearTopRight,
				nearBottomLeft, nearBottomRight;
	Vector3		farTopLeft, farTopRight,
				farBottomLeft, farBottomRight;

	float radians	= (float)tan( (angle)  );
	float nearH		= near  * radians;
	float nearW		= nearH * ratio;
	float farH		= far   * radians;
	float farW		= farH  * ratio;

	zVec = camPos - lookAt;
	zVec.Normalize();

	xVec = up.Cross(zVec);
	xVec.Normalize();

	yVec = zVec.Cross(xVec);

	vecN = camPos - zVec * near;
	vecF = camPos - zVec * far;

	nearTopLeft     = vecN + yVec * nearH - xVec * nearW;
	nearTopRight    = vecN + yVec * nearH + xVec * nearW;
	nearBottomLeft  = vecN - yVec * nearH - xVec * nearW;
	nearBottomRight = vecN - yVec * nearH + xVec * nearW;

	farTopLeft      = vecF + yVec * farH - xVec * farW;
	farTopRight     = vecF + yVec * farH + xVec * farW;
	farBottomLeft   = vecF - yVec * farH - xVec * farW;
	farBottomRight  = vecF - yVec * farH + xVec * farW;

	//DumpVector3(nearTopLeft);
	//DumpVector3(nearTopRight);
	//DumpVector3(nearBottomLeft);
	//DumpVector3(nearBottomRight);
	//std::cout<<"------------------------\n";

	// Clear the frustrum & add the 6 planes
	mFrustum.clear();

	Plane top(nearTopRight, nearTopLeft, farTopLeft);
	mFrustum.push_back(top);

	Plane bottom(nearBottomLeft, nearBottomRight, farBottomRight);
	mFrustum.push_back(bottom);

	Plane left(nearTopLeft, nearBottomLeft, farBottomLeft);
	mFrustum.push_back(left);

	Plane right(nearBottomRight, nearTopRight, farBottomRight);
	mFrustum.push_back(right);

	Plane nearPlane(nearTopLeft, nearTopRight, nearBottomRight);
	mFrustum.push_back(nearPlane);

	Plane farPlane(farTopRight, farTopLeft, farBottomLeft);
	mFrustum.push_back(farPlane);
}
예제 #8
0
//! gets a perspective projection matrix from camera
math::matrix4x4<float> geometry::Camera::perspective() const {
	return math::matrix4x4<float>::projection(nearPlane(), farPlane(), fovH(), fovV());
}
예제 #9
0
void FrustumProperty::setFarPlane(float farPlane)
{
	Property::setValue(QVariant::fromValue(Frustum(left(), right(), bottom(), top(), nearPlane(), farPlane)));
}