|
|
@@ -692,181 +692,12 @@ namespace BansheeEngine
|
|
|
mProjType = pt;
|
|
|
invalidateFrustum();
|
|
|
}
|
|
|
-
|
|
|
//-----------------------------------------------------------------------
|
|
|
ProjectionType Camera::getProjectionType(void) const
|
|
|
{
|
|
|
return mProjType;
|
|
|
}
|
|
|
//---------------------------------------------------------------------
|
|
|
- bool Camera::projectSphere(const Sphere& sphere,
|
|
|
- float* left, float* top, float* right, float* bottom) const
|
|
|
- {
|
|
|
- // See http://www.gamasutra.com/features/20021011/lengyel_06.htm
|
|
|
- // Transform light position into camera space
|
|
|
-
|
|
|
- updateView();
|
|
|
- Vector3 eyeSpacePos = mViewMatrix.transformAffine(sphere.getCenter());
|
|
|
-
|
|
|
- // initialise
|
|
|
- *left = *bottom = -1.0f;
|
|
|
- *right = *top = 1.0f;
|
|
|
-
|
|
|
- if (eyeSpacePos.z < 0)
|
|
|
- {
|
|
|
- updateFrustum();
|
|
|
- const Matrix4& projMatrix = getProjectionMatrix();
|
|
|
- float r = sphere.getRadius();
|
|
|
- float rsq = r * r;
|
|
|
-
|
|
|
- // early-exit
|
|
|
- if (eyeSpacePos.squaredLength() <= rsq)
|
|
|
- return false;
|
|
|
-
|
|
|
- float Lxz = Math::Sqr(eyeSpacePos.x) + Math::Sqr(eyeSpacePos.z);
|
|
|
- float Lyz = Math::Sqr(eyeSpacePos.y) + Math::Sqr(eyeSpacePos.z);
|
|
|
-
|
|
|
- // Find the tangent planes to the sphere
|
|
|
- // XZ first
|
|
|
- // calculate quadratic discriminant: b*b - 4ac
|
|
|
- // x = Nx
|
|
|
- // a = Lx^2 + Lz^2
|
|
|
- // b = -2rLx
|
|
|
- // c = r^2 - Lz^2
|
|
|
- float a = Lxz;
|
|
|
- float b = -2.0f * r * eyeSpacePos.x;
|
|
|
- float c = rsq - Math::Sqr(eyeSpacePos.z);
|
|
|
- float D = b*b - 4.0f*a*c;
|
|
|
-
|
|
|
- // two roots?
|
|
|
- if (D > 0)
|
|
|
- {
|
|
|
- float sqrootD = Math::Sqrt(D);
|
|
|
- // solve the quadratic to get the components of the normal
|
|
|
- float Nx0 = (-b + sqrootD) / (2 * a);
|
|
|
- float Nx1 = (-b - sqrootD) / (2 * a);
|
|
|
-
|
|
|
- // Derive Z from this
|
|
|
- float Nz0 = (r - Nx0 * eyeSpacePos.x) / eyeSpacePos.z;
|
|
|
- float Nz1 = (r - Nx1 * eyeSpacePos.x) / eyeSpacePos.z;
|
|
|
-
|
|
|
- // Get the point of tangency
|
|
|
- // Only consider points of tangency in front of the camera
|
|
|
- float Pz0 = (Lxz - rsq) / (eyeSpacePos.z - ((Nz0 / Nx0) * eyeSpacePos.x));
|
|
|
- if (Pz0 < 0)
|
|
|
- {
|
|
|
- // Project point onto near plane in worldspace
|
|
|
- float nearx0 = (Nz0 * mNearDist) / Nx0;
|
|
|
- // now we need to map this to viewport coords
|
|
|
- // use projection matrix since that will take into account all factors
|
|
|
- Vector3 relx0 = projMatrix * Vector3(nearx0, 0, -mNearDist);
|
|
|
-
|
|
|
- // find out whether this is a left side or right side
|
|
|
- float Px0 = -(Pz0 * Nz0) / Nx0;
|
|
|
- if (Px0 > eyeSpacePos.x)
|
|
|
- {
|
|
|
- *right = std::min(*right, relx0.x);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- *left = std::max(*left, relx0.x);
|
|
|
- }
|
|
|
- }
|
|
|
- float Pz1 = (Lxz - rsq) / (eyeSpacePos.z - ((Nz1 / Nx1) * eyeSpacePos.x));
|
|
|
- if (Pz1 < 0)
|
|
|
- {
|
|
|
- // Project point onto near plane in worldspace
|
|
|
- float nearx1 = (Nz1 * mNearDist) / Nx1;
|
|
|
- // now we need to map this to viewport coords
|
|
|
- // use projection matrix since that will take into account all factors
|
|
|
- Vector3 relx1 = projMatrix * Vector3(nearx1, 0, -mNearDist);
|
|
|
-
|
|
|
- // find out whether this is a left side or right side
|
|
|
- float Px1 = -(Pz1 * Nz1) / Nx1;
|
|
|
- if (Px1 > eyeSpacePos.x)
|
|
|
- {
|
|
|
- *right = std::min(*right, relx1.x);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- *left = std::max(*left, relx1.x);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- // Now YZ
|
|
|
- // calculate quadratic discriminant: 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;
|
|
|
-
|
|
|
- // two roots?
|
|
|
- if (D > 0)
|
|
|
- {
|
|
|
- float sqrootD = Math::Sqrt(D);
|
|
|
- // solve the quadratic to get the components of the normal
|
|
|
- float Ny0 = (-b + sqrootD) / (2 * a);
|
|
|
- float Ny1 = (-b - sqrootD) / (2 * a);
|
|
|
-
|
|
|
- // Derive Z from this
|
|
|
- float Nz0 = (r - Ny0 * eyeSpacePos.y) / eyeSpacePos.z;
|
|
|
- float Nz1 = (r - Ny1 * eyeSpacePos.y) / eyeSpacePos.z;
|
|
|
-
|
|
|
- // Get the point of tangency
|
|
|
- // Only consider points of tangency in front of the camera
|
|
|
- float Pz0 = (Lyz - rsq) / (eyeSpacePos.z - ((Nz0 / Ny0) * eyeSpacePos.y));
|
|
|
- if (Pz0 < 0)
|
|
|
- {
|
|
|
- // Project point onto near plane in worldspace
|
|
|
- float neary0 = (Nz0 * mNearDist) / Ny0;
|
|
|
- // now we need to map this to viewport coords
|
|
|
- // use projection matriy since that will take into account all factors
|
|
|
- Vector3 rely0 = projMatrix * Vector3(0, neary0, -mNearDist);
|
|
|
-
|
|
|
- // find out whether this is a top side or bottom side
|
|
|
- float Py0 = -(Pz0 * Nz0) / Ny0;
|
|
|
- if (Py0 > eyeSpacePos.y)
|
|
|
- {
|
|
|
- *top = std::min(*top, rely0.y);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- *bottom = std::max(*bottom, rely0.y);
|
|
|
- }
|
|
|
- }
|
|
|
- float Pz1 = (Lyz - rsq) / (eyeSpacePos.z - ((Nz1 / Ny1) * eyeSpacePos.y));
|
|
|
- if (Pz1 < 0)
|
|
|
- {
|
|
|
- // Project point onto near plane in worldspace
|
|
|
- float neary1 = (Nz1 * mNearDist) / Ny1;
|
|
|
- // now we need to map this to viewport coords
|
|
|
- // use projection matriy since that will take into account all factors
|
|
|
- Vector3 rely1 = projMatrix * Vector3(0, neary1, -mNearDist);
|
|
|
-
|
|
|
- // find out whether this is a top side or bottom side
|
|
|
- float 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);
|
|
|
-
|
|
|
- }
|
|
|
- //---------------------------------------------------------------------
|
|
|
void Camera::setCustomViewMatrix(bool enable, const Matrix4& viewMatrix)
|
|
|
{
|
|
|
mCustomViewMatrix = enable;
|