Ejemplo n.º 1
0
	//-----------------------------------------------------------------------
	const Matrix4& Frustum::getProjectionMatrixRS(void) const
	{

		updateFrustum();

		return mProjMatrixRS;
	}
Ejemplo n.º 2
0
	//-----------------------------------------------------------------------
	const Matrix4& Frustum::getProjectionMatrixWithRSDepth(void) const
	{

		updateFrustum();

		return mProjMatrixRSDepth;
	}
Ejemplo n.º 3
0
    //-----------------------------------------------------------------------
    void Frustum::_notifyCurrentCamera(Camera* cam)
    {
        // Make sure bounding box up-to-date
        updateFrustum();

        MovableObject::_notifyCurrentCamera(cam);
    }
Ejemplo n.º 4
0
Archivo: camera.cpp Proyecto: xThaid/Xi
const Frustum& Camera::getFrustum()
{
	if (frustumDirty_)
		updateFrustum();

	return frustum_;
}
Ejemplo n.º 5
0
void drawScene3D()
{
    // setup projection
    #ifdef TEST_PROJECTION_MORPHING
    updateProjection();
    #endif

    glMatrixMode(GL_PROJECTION);
    auto proj = projection.ToMatrix4();
    glLoadMatrix_T(proj.Ptr());

    // update view matrix
    glMatrixMode(GL_MODELVIEW);
    viewMatrix = cameraTransform.GetMatrix().Inverse();

    // update view frustum
    updateFrustum();

    // draw models
    for (const auto& mdl : models)
    {
        drawModel(mdl);
        drawAABB(mdl.mesh.BoundingBox(mdl.transform.GetMatrix()));
    }
}
Ejemplo n.º 6
0
	//---------------------------------------------------------------------
	void Frustum::getFrustumExtents(Real& outleft, Real& outright, Real& outtop, Real& outbottom) const
	{
		updateFrustum();
		outleft = mLeft;
		outright = mRight;
		outtop = mTop;
		outbottom = mBottom;
	}
Ejemplo n.º 7
0
void TileRender::ortho( float left, float right, float bottom, float top, float nearPlane, float farPlane )
{
	mCurrentFrustumCoords = Rectf( Vec2f( left, top ), Vec2f( right, bottom ) );
	mCurrentFrustumNear = nearPlane;
	mCurrentFrustumFar = farPlane;
	mCurrentFrustumPersp = false;
	updateFrustum();
}
Ejemplo n.º 8
0
void CameraNode::setAngles(const Geometry::Angle & _fovLeft, const Geometry::Angle & _fovRight, 
						const Geometry::Angle & _fovBottom, const Geometry::Angle & _fovTop) {
	fovLeft = _fovLeft;
	fovRight = _fovRight;
	fovBottom = _fovBottom;
	fovTop = _fovTop;
	updateFrustum();
}
Ejemplo n.º 9
0
void Camera3D::updateMatricies ()
{
	Matrix4F basis;
	Vector3DF temp;	
	
	// compute camera direction vectors	--- MATCHES OpenGL's gluLookAt function (DO NOT MODIFY)
	dir_vec = to_pos;					// f vector in gluLookAt docs						
	dir_vec -= from_pos;				// eye = from_pos in gluLookAt docs
	dir_vec.Normalize ();
	side_vec = dir_vec;
	side_vec.Cross ( up_dir );
	side_vec.Normalize ();
	up_vec = side_vec;
	up_vec.Cross ( dir_vec );
	up_vec.Normalize();
	dir_vec *= -1;
	
	// construct view matrix
	rotate_matrix.Basis (side_vec, up_vec, dir_vec );
	view_matrix = rotate_matrix;
	//Matrix4F trans;
	//trans.Translate ( -from_pos.x, -from_pos.y, -from_pos.z );		// !efficiency
	view_matrix.PreTranslate ( Vector3DF(-from_pos.x, -from_pos.y, -from_pos.z ) );

	// construct projection matrix  --- MATCHES OpenGL's gluPerspective function (DO NOT MODIFY)
	float sx = tan ( mFov * 0.5 * DEGtoRAD ) * mNear;
	float sy = sx / mAspect;
	proj_matrix = 0.0;
	proj_matrix(0,0) = 2.0*mNear / sx;				// matches OpenGL definition
	proj_matrix(1,1) = 2.0*mNear / sy;
	proj_matrix(2,2) = -(mFar + mNear)/(mFar - mNear);			// C
	proj_matrix(2,3) = -(2.0*mFar * mNear)/(mFar - mNear);		// D
	proj_matrix(3,2) = -1.0;

	// construct tile projection matrix --- MATCHES OpenGL's glFrustum function (DO NOT MODIFY) 
	float l, r, t, b;
	l = -sx + 2.0*sx*mTile.x;						// Tile is in range 0 <= x,y <= 1
	r = -sx + 2.0*sx*mTile.z;
	t =  sy - 2.0*sy*mTile.y;
	b =  sy - 2.0*sy*mTile.w;
	tileproj_matrix = 0.0;
	tileproj_matrix(0,0) = 2.0*mNear / (r - l);
	tileproj_matrix(1,1) = 2.0*mNear / (t - b);
	tileproj_matrix(0,2) = (r + l) / (r - l);		// A
	tileproj_matrix(1,2) = (t + b) / (t - b);		// B
	tileproj_matrix(2,2) = proj_matrix(2,2);		// C
	tileproj_matrix(2,3) = proj_matrix(2,3);		// D
	tileproj_matrix(3,2) = -1.0;

	// construct inverse rotate and inverse projection matrix
    Vector3DF tvz(0, 0, 0);
	//invrot_matrix.InverseView ( rotate_matrix.GetDataF(), Vector3DF(0,0,0) );		// Computed using rule: "Inverse of a basis rotation matrix is its transpose." (So long as translation is taken out)
	invrot_matrix.InverseView ( rotate_matrix.GetDataF(), tvz );		// Computed using rule: "Inverse of a basis rotation matrix is its transpose." (So long as translation is taken out)
	invproj_matrix.InverseProj ( tileproj_matrix.GetDataF() );							// Computed using rule: 

	updateFrustum ();
}
Ejemplo n.º 10
0
void CCAMERA::ResetXYpos()
{
    m_parametersChanged = true;
    m_camera_pos.x = 0.0f;
    m_camera_pos.y = 0.0f;

    updateViewMatrix();
    updateFrustum();
}
Ejemplo n.º 11
0
void Z3DCamera::setFrustum(float fov, float ratio, float nearDist, float farDist)
{
  m_fieldOfView = fov;
  m_aspectRatio = ratio;
  m_nearDist = nearDist;
  m_farDist = farDist;
  updateFrustum();
  invalidProjectionMatrix();
}
Ejemplo n.º 12
0
void StGLProjCamera::resize(StGLContext&  theCtx,
                            const GLsizei theSizeX,
                            const GLsizei theSizeY) {
    const GLsizei aSizeY = (theSizeY > 0) ? theSizeY : 1;
    myAspect = GLfloat(theSizeX) / GLfloat(aSizeY);

    theCtx.stglResizeViewport(theSizeX, aSizeY); // reset the current viewport
    updateFrustum();
}
Ejemplo n.º 13
0
	//-----------------------------------------------------------------------
	void Frustum::updateFrustumPlanes(void) const
	{
		updateView();
		updateFrustum();

		if (mRecalcFrustumPlanes)
		{
			updateFrustumPlanesImpl();
		}
	}
Ejemplo n.º 14
0
void Camera::setView( RenderView* view )
{
	if( !view ) return;

	activeView = view;
	activeView->viewMatrix = viewMatrix;
	activeView->projectionMatrix = frustum.matProjection;

	updateFrustum();
}
Ejemplo n.º 15
0
 // This is called to set up the Camera-View
 void Camera::look(float windowRatio) {
   MatStack.matrixMode(MatrixStack::PROJECTION);
   MatStack.loadIdentity();
   updateFrustum();
   MatStack.loadMatrix(getFrustumMatrix(windowRatio));
   MatStack.matrixMode(MatrixStack::MODELVIEW);
   MatStack.loadIdentity();
   updateVM();
   MatStack.loadMatrix(viewMatrix_);
 }
Ejemplo n.º 16
0
// This is called to set up the Camera-View
void Camera::look() {
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    updateFrustum();
    loadMatrix(getFrustumMatrix());
    //getProjectionMatrix();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    updateVM();
    loadMatrix(viewMatrix_);
}
Ejemplo n.º 17
0
void updateEditorCamera(void)
{
	camera_struct* c=&editorCamera;

	c->viewPosition=c->position;
	
	updateViewMatrix(c);
	updateFrustum(c);
	
	fixMatrix(c->transformationMatrix);
}
Ejemplo n.º 18
0
void Z3DCamera::resetCameraNearFarPlane(const std::vector<double> &bound)
{
  double a = m_viewVector[0];
  double b = m_viewVector[1];
  double c = m_viewVector[2];
  double d = -(a*m_eye[0] + b*m_eye[1] + c*m_eye[2]);

  // Set the max near clipping plane and the min far clipping plane
  double range[2];
  range[0] = a*bound[0] + b*bound[2] + c*bound[4] + d;
  range[1] = 1e-18;

  // Find the closest / farthest bounding box vertex
  for (int k = 0; k < 2; k++ ) {
    for (int j = 0; j < 2; j++ ) {
      for (int i = 0; i < 2; i++ ) {
        double dist = a*bound[i] + b*bound[2+j] + c*bound[4+k] + d;
        range[0] = (dist<range[0])?(dist):(range[0]);
        range[1] = (dist>range[1])?(dist):(range[1]);
      }
    }
  }

  // Do not let the range behind the camera throw off the calculation.
  if (range[0] < 0.0) {
    range[0] = 0.0;
  }

  // Give ourselves a little breathing room
  range[0] = 0.99*range[0] - (range[1] - range[0])*0.5;
  range[1] = 1.01*range[1] + (range[1] - range[0])*0.5;

  // Make sure near is not bigger than far
  //range[0] = (range[0] >= range[1])?(0.01*range[1]):(range[0]);

  // Make sure near is at least some fraction of far - this prevents near
  // from being behind the camera or too close in front.
  double nearClippingPlaneTolerance = 0.001;

  // make sure the front clipping range is not too far from the far clippnig
  // range, this is to make sure that the zbuffer resolution is effectively
  // used
  if (range[0] < nearClippingPlaneTolerance*range[1]) {
    range[0] = nearClippingPlaneTolerance*range[1];
  }

  m_nearDist = range[0];
  m_farDist = range[1];
  updateFrustum();
  invalidProjectionMatrix();
}
Ejemplo n.º 19
0
void Z3DCamera::set(const ZJsonObject &cameraJson)
{
  if (cameraJson.hasKey("eye")) {
    for (int i = 0; i < 3; ++i) {
      m_eye[i] = ZJsonParser::numberValue(cameraJson["eye"], i);
    }
  }

  if (cameraJson.hasKey("center")) {
    for (int i = 0; i < 3; ++i) {
      m_center[i] = ZJsonParser::numberValue(cameraJson["center"], i);
    }
  }

  if (cameraJson.hasKey("up_vector")) {
    for (int i = 0; i < 3; ++i) {
      m_upVector[i] = ZJsonParser::numberValue(cameraJson["up_vector"], i);
    }
  }

  if (cameraJson.hasKey("projection")) {
    if (strcmp(ZJsonParser::stringValue(cameraJson["projection"]),
               "Perspective") == 0) {
      m_projectionType = Perspective;
    } else if (strcmp(ZJsonParser::stringValue(cameraJson["projection"]),
                      "Orthographic") == 0) {
      m_projectionType = Orthographic;
    }
  }

  if (cameraJson.hasKey("field_of_view")) {
    m_fieldOfView = ZJsonParser::numberValue(cameraJson["field_of_view"]);
  }

  if (cameraJson.hasKey("aspect_ratio")) {
    m_aspectRatio = ZJsonParser::numberValue(cameraJson["aspect_ratio"]);
  }

  if (cameraJson.hasKey("near_dist")) {
    m_nearDist = ZJsonParser::numberValue(cameraJson["near_dist"]);
  }

  if (cameraJson.hasKey("far_dist")) {
    m_farDist = ZJsonParser::numberValue(cameraJson["far_dist"]);
  }

  updateCamera();
  updateFrustum();
  invalidViewMatrix();
  invalidProjectionMatrix();
}
Ejemplo n.º 20
0
Z3DCamera::Z3DCamera()
  : m_eye(0.f, 0.f, 0.f)
  , m_center(0.f, 0.f, -1.f)
  , m_upVector(0.f, 1.f, 0.f)
  //, m_projectionType(Orthographic)
  , m_projectionType(Perspective)
  , m_fieldOfView(glm::radians(45.f))
  , m_aspectRatio(1.f)
  , m_nearDist(.1f)
  , m_farDist(50.f)
  , m_windowAspectRatio(1.f)
  , m_eyeSeparationAngle(glm::radians(8.f))
{
  updateCamera();
  updateFrustum();
  invalidViewMatrix();
  invalidProjectionMatrix();
}
Ejemplo n.º 21
0
void Camera::update( float )
{
	if( !activeView ) return;

	drawer.reset();
	bool frustumUpdated = false;

	if( !frustumUpdated)
		updateFrustum();

	// Only run the following code once.
	if( transform ) return;

	transform = getEntity()->getTransform().get();
	transform->onTransformed.Connect( this, &Camera::onTransformed );

	// Update the view transform the first update.
	updateViewTransform();
}
Ejemplo n.º 22
0
StGLProjCamera::StGLProjCamera()
: myMatrix(),
  myMatrixMono(),
  myFOVy(45.0f),
  myZoom(1.0f),
  myAspect(1.0f),
  myZScreen(10.0f),
  myIOD(0.5f),
  myFrustL(),
  myFrustR(),
  myFrustM(),
  myFrust(NULL),
  myIsPersp(true) {
    //
    myFrust = &myFrustM;
    myFrustM.zNear = myFrustL.zNear = myFrustR.zNear = 3.0f;
    myFrustM.zFar  = myFrustL.zFar  = myFrustR.zFar  = 30.0f;
    updateFrustum();
}
Ejemplo n.º 23
0
void CCAMERA::updateRotationMatrix()
{
    m_rotationMatrixAux = glm::rotate( glm::mat4( 1.0f ),
                                       m_rotate_aux.x,
                                       SFVEC3F( 1.0f, 0.0f, 0.0f ) );

    m_rotationMatrixAux = glm::rotate( m_rotationMatrixAux,
                                       m_rotate_aux.y,
                                       SFVEC3F( 0.0f, 1.0f, 0.0f ) );

    m_rotationMatrixAux = glm::rotate( m_rotationMatrixAux,
                                       m_rotate_aux.z,
                                       SFVEC3F( 0.0f, 0.0f, 1.0f ) );

    m_parametersChanged = true;

    updateViewMatrix();
    updateFrustum();
}
Ejemplo n.º 24
0
void CCamera::_UpdateEx(void)  const
{
	//------------------------
	//更新view matrix和 视锥体
	//------------------------
	// View matrix is:
	//  [ Rx  Ry  Rz  0  ]
	//  [ Ux  Uy  Uz  0  ]
	//  [ Dx  Dy  Dz  0  ]
	//  [ Tx  Ty  Tz  1  ]

	CVector3f vDIRECTIONz = m_matCached.getColumn(2);
	CVector2f DirYZr(vDIRECTIONz.x, vDIRECTIONz.z);
	DirYZr.Normalize();
	m_matBillboardNoneX.Identity();
	m_matBillboardNoneX._11 =  DirYZr.y;
	m_matBillboardNoneX._13 = -DirYZr.x;
	m_matBillboardNoneX._31 =  DirYZr.x;
	m_matBillboardNoneX._33 =  DirYZr.y;
	CMatrix RotateX;
	RotateX.SetRotateX(asinf( -vDIRECTIONz.y ));
	m_matBillboardAll = RotateX*m_matBillboardNoneX;

	m_matView = m_matCached;
	m_matView.Transpose3x3();
	CVector3f  trans  = m_v3Position;
	trans.Rotate( m_matView );
	m_matView.m[3][0] = -trans.x;
	m_matView.m[3][1] = -trans.y;
	m_matView.m[3][2] = -trans.z;
	m_matView = m_matDeltaView * m_matView;
	//View matrix 更新完毕
	//下面更新 视锥体
	updateFrustum();

	m_matViewProject = m_matView * m_matProj;
	//向量向视锥体里
	m_Frustum.Update(m_matViewProject);
}
Ejemplo n.º 25
0
StGLProjCamera::StGLProjCamera(const GLfloat theFOVy,
                               const GLfloat theZNear,
                               const GLfloat theZFar,
                               const GLfloat theZScreen)
: myMatrix(),
  myMatrixMono(),
  myFOVy(theFOVy),
  myZoom(1.0f),
  myAspect(1.0f),
  myZScreen(theZScreen),
  myIOD(0.5f),
  myFrustL(),
  myFrustR(),
  myFrustM(),
  myFrust(NULL),
  myIsPersp(true) {
    //
    myFrust = &myFrustM;
    myFrustM.zNear = myFrustL.zNear = myFrustR.zNear = theZNear;
    myFrustM.zFar  = myFrustL.zFar  = myFrustR.zFar  = theZFar;
    updateFrustum();
}
Ejemplo n.º 26
0
	//-----------------------------------------------------------------------
	Frustum::Frustum(const String& name) :
		mProjType(PT_PERSPECTIVE),
		mFOVy(Radian(Math::_PI / 4.0f)),
		mFarDist(100000.0f),
		mNearDist(100.0f),
		mAspect(1.33333333333333f),
		mOrthoHeight(1000),
		mFrustumOffset(Vector2::ZERO),
		mFocalLength(1.0f),
		mLastParentOrientation(Quaternion::IDENTITY),
		mLastParentPosition(Vector3::ZERO),
		mRecalcFrustum(true),
		mRecalcView(true),
		mRecalcFrustumPlanes(true),
		mRecalcWorldSpaceCorners(true),
		mRecalcVertexData(true),
		mCustomViewMatrix(false),
		mCustomProjMatrix(false),
		mFrustumExtentsManuallySet(false),
		mOrientationMode(OR_DEGREE_0),
		mReflect(false),
		//mLinkedReflectPlane(0),
		mObliqueDepthProjection(false)
		//mLinkedObliqueProjPlane(0)
	{
		// 初始化材质
		//mMaterial = MaterialManager::getSingleton().getByName("BaseWhiteNoLighting");

		// 修改超类成员变量
		//mVisible = false;
		//mParentNode = 0;
		//mName = name;

		//mLastLinkedReflectionPlane.normal = Vector3::ZERO;
		//mLastLinkedObliqueProjPlane.normal = Vector3::ZERO;

		updateView();
		updateFrustum();
	}
Ejemplo n.º 27
0
    //-----------------------------------------------------------------------
    Frustum::Frustum() : 
        mProjType(PT_PERSPECTIVE), 
        mFOVy(Radian(Math::PI/4.0)), 
        mFarDist(100000.0f), 
        mNearDist(100.0f), 
        mAspect(1.33333333333333f), 
		mOrthoHeight(1000),
        mFrustumOffset(Vector2::ZERO),
        mFocalLength(1.0f),
        mLastParentOrientation(Quaternion::IDENTITY),
        mLastParentPosition(Vector3::ZERO),
        mRecalcFrustum(true), 
        mRecalcView(true), 
        mRecalcFrustumPlanes(true),
        mRecalcWorldSpaceCorners(true),
        mRecalcVertexData(true),
		mCustomViewMatrix(false),
		mCustomProjMatrix(false),
		mFrustumExtentsManuallySet(false),
        mReflect(false), 
        mLinkedReflectPlane(0),
        mObliqueDepthProjection(false), 
        mLinkedObliqueProjPlane(0)
    {
        // Initialise material
        mMaterial = MaterialManager::getSingleton().getByName("BaseWhiteNoLighting");
        
        // Alter superclass members
        mVisible = false;
        mParentNode = 0;

        mLastLinkedReflectionPlane.normal = Vector3::ZERO;
        mLastLinkedObliqueProjPlane.normal = Vector3::ZERO;


        updateView();
        updateFrustum();
    }
Ejemplo n.º 28
0
bool TileRender::nextTile()
{
	if( mCurrentTile >= mNumTilesX * mNumTilesY ) {
		// suck the pixels out of the final tile
		mSurface.copyFrom( app::copyWindowSurface( Area( 0, app::getWindowHeight() - mCurrentArea.getHeight(), mCurrentArea.getWidth(), app::getWindowHeight() ) ), 
			Area( 0, 0, mCurrentArea.getWidth(), mCurrentArea.getHeight() ), mCurrentArea.getUL() );
		// all done
		gl::setViewport( mSavedViewport );
		mCurrentTile = -1;
		return false;
	}
	
	if( mCurrentTile == -1 ) { // first tile of this frame
		mSavedViewport = gl::getViewport();
		mCurrentTile = 0;
		mSurface = Surface( mImageWidth, mImageHeight, false );
	}
	else {
		// suck the pixels out of the previous tile
		mSurface.copyFrom( app::copyWindowSurface( Area( 0, app::getWindowHeight() - mCurrentArea.getHeight(), mCurrentArea.getWidth(), app::getWindowHeight() ) ), 
			Area( 0, 0, mCurrentArea.getWidth(), mCurrentArea.getHeight() ), mCurrentArea.getUL() );
	}
	
	int tileX = mCurrentTile % mNumTilesX;
	int tileY = mCurrentTile / mNumTilesX;
	int currentTileWidth = ( ( tileX == mNumTilesX - 1 ) && ( mImageWidth != mTileWidth * mNumTilesX ) ) ? ( mImageWidth % mTileWidth ) : mTileWidth;
	int currentTileHeight = ( ( tileY == mNumTilesY - 1 ) && ( mImageHeight != mTileHeight * mNumTilesY ) ) ? ( mImageHeight % mTileHeight ) : mTileHeight;
	mCurrentArea.x1 = tileX * mTileWidth;
	mCurrentArea.x2 = mCurrentArea.x1 + currentTileWidth;
	mCurrentArea.y1 = tileY * mTileHeight;
	mCurrentArea.y2 = mCurrentArea.y1 + currentTileHeight;

	gl::setViewport( Area( 0, 0, mCurrentArea.getWidth(), mCurrentArea.getHeight() ) );
	updateFrustum();

	mCurrentTile++;
	return true;
}
Ejemplo n.º 29
0
	bool Frustum::projectSphere(const Sphere& sphere,
		Real* left, Real* top, Real* right, Real* bottom) const
	{
		// 变换光源位置到相机空间

		updateView();
		Vector3 eyeSpacePos = mViewMatrix.transformAffine(sphere.getCenter()); //将球中心坐标转到观察空间中

		// 初始化
		*left = *bottom = -1.0f;
		*right = *top = 1.0f;

		if (eyeSpacePos.z < 0)
		{
			updateFrustum();
			const Matrix4& projMatrix = getProjectionMatrix();
			Real r = sphere.getRadius();
			Real rsq = r * r;  //半径的平方


			if (eyeSpacePos.squaredLength() <= rsq)
				return false;

			Real Lxz = Math::Sqr(eyeSpacePos.x) + Math::Sqr(eyeSpacePos.z);  //设原点O,球心P, 向量Vop在XZ平面上的投影
			Real Lyz = Math::Sqr(eyeSpacePos.y) + Math::Sqr(eyeSpacePos.z);  //设原点O,球心P, 向量Vop在YZ平面上的投影

			// 用点法式 找出球体切平面
			// 首先XZ 
			// 计算二次根判别式: b*b - 4ac
			// x = Nx
			// a = Lx^2 + Lz^2
			// b = -2rLx
			// c = r^2 - Lz^2
			Real a = Lxz;
			Real b = -2.0f * r * eyeSpacePos.x;
			Real c = rsq - Math::Sqr(eyeSpacePos.z);
			Real D = b*b - 4.0f*a*c;

			// 两个根
			if (D > 0)
			{
				Real sqrootD = Math::Sqrt(D);
				// 解除二次方获取法线的分量
				Real Nx0 = (-b + sqrootD) / (2 * a);
				Real Nx1 = (-b - sqrootD) / (2 * a);

				// 取得Z
				Real Nz0 = (r - Nx0 * eyeSpacePos.x) / eyeSpacePos.z;
				Real Nz1 = (r - Nx1 * eyeSpacePos.x) / eyeSpacePos.z;

				// 获取切点
				// 只考虑相机前面的切点
				Real Pz0 = (Lxz - rsq) / (eyeSpacePos.z - ((Nz0 / Nx0) * eyeSpacePos.x));
				if (Pz0 < 0)
				{
					// 投影在近剪裁平面在世界空间的点
					Real nearx0 = (Nz0 * mNearDist) / Nx0;
					// 现在我们需要映射它到视口坐标
					// 用投影矩阵,并考虑所有的因素
					Vector3 relx0 = projMatrix * Vector3(nearx0, 0, -mNearDist);

					//找出这是左边还是右边
					Real Px0 = -(Pz0 * Nz0) / Nx0;
					if (Px0 > eyeSpacePos.x)
					{
						*right = std::min(*right, relx0.x);
					}
					else
					{
						*left = std::max(*left, relx0.x);
					}
				}
				Real Pz1 = (Lxz - rsq) / (eyeSpacePos.z - ((Nz1 / Nx1) * eyeSpacePos.x));
				if (Pz1 < 0)
				{
					//投影在近剪裁平面在世界空间的点
					Real nearx1 = (Nz1 * mNearDist) / Nx1;
					// 现在我们需要映射它到视口坐标
					// 用投影矩阵,并考虑所有的因素
					Vector3 relx1 = projMatrix * Vector3(nearx1, 0, -mNearDist);

					//找出这是左边还是右边
					Real Px1 = -(Pz1 * Nz1) / Nx1;
					if (Px1 > eyeSpacePos.x)
					{
						*right = std::min(*right, relx1.x);
					}
					else
					{
						*left = std::max(*left, relx1.x);
					}
				}
			}


			// 现在是 YZ 平面
			// 计算二次方根判别式: b*b - 4ac
			// x = Ny
			// a = Ly^2 + Lz^2
			// b = -2rLy
			// c = r^2 - Lz^2
			a = Lyz;
			b = -2.0f * r * eyeSpacePos.y;
			c = rsq - Math::Sqr(eyeSpacePos.z);
			D = b*b - 4.0f*a*c;

			//两个根
			if (D > 0)
			{
				Real sqrootD = Math::Sqrt(D);
				// 解除二次根获得法线的分量
				Real Ny0 = (-b + sqrootD) / (2 * a);
				Real Ny1 = (-b - sqrootD) / (2 * a);

				// 从这里取得Z
				Real Nz0 = (r - Ny0 * eyeSpacePos.y) / eyeSpacePos.z;
				Real Nz1 = (r - Ny1 * eyeSpacePos.y) / eyeSpacePos.z;

				// 获取切点
				// 只考虑相机前面的切点
				Real Pz0 = (Lyz - rsq) / (eyeSpacePos.z - ((Nz0 / Ny0) * eyeSpacePos.y));
				if (Pz0 < 0)
				{
					//投影在近剪裁平面在世界空间的点
					Real neary0 = (Nz0 * mNearDist) / Ny0;
					// 现在我们需要映射它到视口坐标
					// 用投影矩阵,并考虑所有的因素
					Vector3 rely0 = projMatrix * Vector3(0, neary0, -mNearDist);

					//找出这是左边还是右边
					Real Py0 = -(Pz0 * Nz0) / Ny0;
					if (Py0 > eyeSpacePos.y)
					{
						*top = std::min(*top, rely0.y);
					}
					else
					{
						*bottom = std::max(*bottom, rely0.y);
					}
				}
				Real Pz1 = (Lyz - rsq) / (eyeSpacePos.z - ((Nz1 / Ny1) * eyeSpacePos.y));
				if (Pz1 < 0)
				{
					//投影在近剪裁平面在世界空间的点
					Real neary1 = (Nz1 * mNearDist) / Ny1;
					// 现在我们需要映射它到视口坐标
					// 用投影矩阵,并考虑所有的因素
					Vector3 rely1 = projMatrix * Vector3(0, neary1, -mNearDist);

					//找出这是左边还是右边
					Real Py1 = -(Pz1 * Nz1) / Ny1;
					if (Py1 > eyeSpacePos.y)
					{
						*top = std::min(*top, rely1.y);
					}
					else
					{
						*bottom = std::max(*bottom, rely1.y);
					}
				}
			}
		}

		return (*left != -1.0f) || (*top != 1.0f) || (*right != 1.0f) || (*bottom != -1.0f);

	}
Ejemplo n.º 30
0
void CCAMERA::rebuildProjection()
{
    if( (m_windowSize.x == 0) ||
        (m_windowSize.y == 0) )
        return;

    m_frustum.ratio = (float) m_windowSize.x / (float)m_windowSize.y;

    // Consider that we can render double the length multiplied by the 2/sqrt(2)
    //
    m_frustum.farD = glm::length( m_camera_pos_init ) * 2.0f * ( 2.0f * sqrtf( 2.0f ) );

    switch( m_projectionType )
    {
    default:
    case PROJECTION_PERSPECTIVE:

        m_frustum.nearD = 0.10f;

        // Ratio width / height of the window display
        m_frustum.angle = 45.0f * m_zoom;


        m_projectionMatrix = glm::perspective( glm::radians( m_frustum.angle ),
                                               m_frustum.ratio,
                                               m_frustum.nearD,
                                               m_frustum.farD );

        m_projectionMatrixInv = glm::inverse( m_projectionMatrix );

        m_frustum.tang = glm::tan( glm::radians( m_frustum.angle ) * 0.5f ) ;

        m_focalLen.x = ( (float)m_windowSize.y / (float)m_windowSize.x ) / m_frustum.tang;
        m_focalLen.y = 1.0f / m_frustum.tang;

        m_frustum.nh = m_frustum.nearD * m_frustum.tang;
        m_frustum.nw = m_frustum.nh * m_frustum.ratio;
        m_frustum.fh = m_frustum.farD * m_frustum.tang;
        m_frustum.fw = m_frustum.fh * m_frustum.ratio;
        break;

    case PROJECTION_ORTHO:

        m_frustum.nearD = 0.01f;

        const float orthoReductionFactor = m_zoom / 75.0f;

        // Initialize Projection Matrix for Ortographic View
        m_projectionMatrix = glm::ortho( -m_windowSize.x * orthoReductionFactor,
                                          m_windowSize.x * orthoReductionFactor,
                                         -m_windowSize.y * orthoReductionFactor,
                                          m_windowSize.y * orthoReductionFactor,
                                          m_frustum.nearD, m_frustum.farD );

        m_projectionMatrixInv = glm::inverse( m_projectionMatrix );

        m_frustum.nw = m_windowSize.x * orthoReductionFactor * 2.0f;
        m_frustum.nh = m_windowSize.y * orthoReductionFactor * 2.0f;
        m_frustum.fw = m_frustum.nw;
        m_frustum.fh = m_frustum.nh;

        break;
    }

    m_scr_nX.resize( m_windowSize.x );
    m_scr_nY.resize( m_windowSize.y );

    // Precalc X values for camera -> ray generation
    for( unsigned int x = 0; x < (unsigned int)m_windowSize.x; ++x )
    {
        // Converts 0.0 .. 1.0
        const float xNormalizedDeviceCoordinates = ( ( (float)x + 0.5f ) /
                                                     (m_windowSize.x - 0.0f) );

        // Converts -1.0 .. 1.0
        m_scr_nX[x] = 2.0f * xNormalizedDeviceCoordinates - 1.0f;
    }

    // Precalc Y values for camera -> ray generation
    for( unsigned int y = 0; y < (unsigned int)m_windowSize.y; ++y )
    {
        // Converts 0.0 .. 1.0
        const float yNormalizedDeviceCoordinates = ( ( (float)y + 0.5f ) /
                                                     (m_windowSize.y - 0.0f) );

        // Converts -1.0 .. 1.0
        m_scr_nY[y] = 2.0f * yNormalizedDeviceCoordinates - 1.0f;
    }

    updateFrustum();
}