+void VectorReflectedByPlane(Vector4 &out, Vector4 &in, Vector4 &plane)
+{
+ float d = float(2.0) * plane.Dot(in);
+ out.x = static_cast<float>(in.x - plane.x*d);
+ out.y = static_cast<float>(in.y - plane.y*d);
+ out.z = static_cast<float>(in.z - plane.z*d);
+ out.w = static_cast<float>(in.w - plane.w*d);
+}
+
+void Camera::AdjustNearPlaneForPerspective( Matrix& perspective, const Vector4& clipPlane )
+{
+ Vector4 q;
+ float* v = perspective.AsFloat();
+
+ q.x = (Sign(clipPlane.x) + v[8]) / v[0];
+ q.y = (Sign(clipPlane.y) + v[9]) / v[5];
+ q.z = -1.0f;
+ q.w = (1.0f + v[10]) / v[14];
+
+ // Calculate the scaled plane vector
+ Vector4 c = clipPlane * (REFLECTION_NORMALIZED_DEVICE_COORDINATE_PARAMETER_A / q.Dot( clipPlane));
+
+ // Replace the third row of the projection v
+ v[2] = c.x;
+ v[6] = c.y;
+ v[10] = c.z + REFLECTION_NORMALIZED_DEVICE_COORDINATE_PARAMETER_D;
+ v[14] = c.w;
+}
+
+void Camera::SetReflectByPlane( const Vector4& plane )
+{
+ float* v = mReflectionMtx.AsFloat();
+ float _2ab = -2.0f * plane.x * plane.y;
+ float _2ac = -2.0f * plane.x * plane.z;
+ float _2bc = -2.0f * plane.y * plane.z;
+
+ v[0] = 1.0f - 2.0f * plane.x * plane.x;
+ v[1] = _2ab;
+ v[2] = _2ac;
+ v[3] = 0.0f;
+
+ v[4] = _2ab;
+ v[5] = 1.0f - 2.0f * plane.y * plane.y;
+ v[6] = _2bc;
+ v[7] = 0.0f;
+
+ v[8] = _2ac;
+ v[9] = _2bc;
+ v[10] = 1.0f - 2.0f * plane.z * plane.z;
+ v[11] = 0.0f;
+
+ v[12] = - 2 * plane.x * plane.w;
+ v[13] = - 2 * plane.y * plane.w;
+ v[14] = - 2 * plane.z * plane.w;
+ v[15] = 1.0f;
+
+ mUseReflection = true;
+ mReflectionPlane = plane;
+ mUpdateViewFlag = UPDATE_COUNT;
+}
+
+void Camera::RotateProjection( int rotationAngle )
+{
+ mProjectionRotation = rotationAngle;
+ mUpdateViewFlag = UPDATE_COUNT;
+}
+