//----------------------------------------------------------------------- void Frustum::calcProjectionParameters(Real& left, Real& right, Real& bottom, Real& top) const { if (mCustomProjMatrix) //自定义投影矩阵 { // 转换剪裁平面角到相机空间中 Matrix4 invProj = mProjMatrix.inverse(); //对透视投影矩阵求逆得观察矩阵 Vector3 topLeft(-0.5f, 0.5f, 0.0f); //左上角 Vector3 bottomRight(0.5f, -0.5f, 0.0f); //右下角 topLeft = invProj * topLeft; bottomRight = invProj * bottomRight; left = topLeft.x; top = topLeft.y; right = bottomRight.x; bottom = bottomRight.y; } else { //视锥体手动扩展设置 if (mFrustumExtentsManuallySet) { left = mLeft; right = mRight; top = mTop; bottom = mBottom; } // 计算通用的投影参数 else if (mProjType == PT_PERSPECTIVE) //透视投影 { Radian thetaY(mFOVy * 0.5f); //thetaY= mFovy的一半 Real tanThetaY = Math::Tan(thetaY); Real tanThetaX = tanThetaY * mAspect; //用于3d立体显示参数 Real nearFocal = mNearDist / mFocalLength; Real nearOffsetX = mFrustumOffset.x * nearFocal; Real nearOffsetY = mFrustumOffset.y * nearFocal; Real half_w = tanThetaX * mNearDist; Real half_h = tanThetaY * mNearDist; left = -half_w + nearOffsetX; right = +half_w + nearOffsetX; bottom = -half_h + nearOffsetY; top = +half_h + nearOffsetY; mLeft = left; mRight = right; mTop = top; mBottom = bottom; } else { //正交投影 // 不知道怎样应用视锥体偏移到正交投影相机,这里就无效化 Real half_w = getOrthoWindowWidth() * 0.5f; Real half_h = getOrthoWindowHeight() * 0.5f; left = -half_w; right = +half_w; bottom = -half_h; top = +half_h; mLeft = left; mRight = right; mTop = top; mBottom = bottom; } } }
//----------------------------------------------------------------------- void Frustum::calcProjectionParameters(Real& left, Real& right, Real& bottom, Real& top) const { if (mCustomProjMatrix) { // Convert clipspace corners to camera space Matrix4 invProj = mProjMatrix.inverse(); Vector3 topLeft(-0.5f, 0.5f, 0.0f); Vector3 bottomRight(0.5f, -0.5f, 0.0f); topLeft = invProj * topLeft; bottomRight = invProj * bottomRight; left = topLeft.x; top = topLeft.y; right = bottomRight.x; bottom = bottomRight.y; } else { if (mFrustumExtentsManuallySet) { left = mLeft; right = mRight; top = mTop; bottom = mBottom; } // Calculate general projection parameters else if (mProjType == PT_PERSPECTIVE) { Radian thetaY (mFOVy * 0.5f); Real tanThetaY = Math::Tan(thetaY); Real tanThetaX = tanThetaY * mAspect; Real nearFocal = mNearDist / mFocalLength; Real nearOffsetX = mFrustumOffset.x * nearFocal; Real nearOffsetY = mFrustumOffset.y * nearFocal; Real half_w = tanThetaX * mNearDist; Real half_h = tanThetaY * mNearDist; left = - half_w + nearOffsetX; right = + half_w + nearOffsetX; bottom = - half_h + nearOffsetY; top = + half_h + nearOffsetY; mLeft = left; mRight = right; mTop = top; mBottom = bottom; } else { // Unknown how to apply frustum offset to orthographic camera, just ignore here Real half_w = getOrthoWindowWidth() * 0.5f; Real half_h = getOrthoWindowHeight() * 0.5f; left = - half_w; right = + half_w; bottom = - half_h; top = + half_h; mLeft = left; mRight = right; mTop = top; mBottom = bottom; } } }