//----------------------------------------------------------------------------
HPlane::HPlane (const AVector& normal, const APoint& p)
{
	mTuple[0] = normal[0];
	mTuple[1] = normal[1];
	mTuple[2] = normal[2];
	mTuple[3] = -p.Dot(normal);
}
Ejemplo n.º 2
0
//----------------------------------------------------------------------------
void HMatrix::MakeReflection (const APoint& origin, const AVector& normal)
{
    //     +-                         -+
    // M = | I-2*N*N^T    2*Dot(N,P)*N |
    //     |     0^T            1      |
    //     +-                         -+
    //
    // where P is a point on the plane and N is a unit-length plane normal.

    float twoDotNO = 2.0f*origin.Dot(normal);

    mEntry[ 0] = 1.0f - 2.0f*normal[0]*normal[0];
    mEntry[ 1] = -2.0f*normal[0]*normal[1];
    mEntry[ 2] = -2.0f*normal[0]*normal[2];
    mEntry[ 3] = twoDotNO*normal[0];
    mEntry[ 4] = -2.0f*normal[1]*normal[0];
    mEntry[ 5] = 1.0f - 2.0f*normal[1]*normal[1];
    mEntry[ 6] = -2.0f*normal[1]*normal[2];
    mEntry[ 7] = twoDotNO*normal[1];
    mEntry[ 8] = -2.0f*normal[2]*normal[0];
    mEntry[ 9] = -2.0f*normal[2]*normal[1];
    mEntry[10] = 1.0f - 2.0f*normal[2]*normal[2];
    mEntry[11] = twoDotNO*normal[2];
    mEntry[12] = 0.0f;
    mEntry[13] = 0.0f;
    mEntry[14] = 0.0f;
    mEntry[15] = 1.0f;
}
Ejemplo n.º 3
0
//----------------------------------------------------------------------------
void HMatrix::MakePerspectiveProjection (const APoint& origin,
    const AVector& normal, const APoint& eye)
{
    //     +-                                                 -+
    // M = | Dot(N,E-P)*I - E*N^T    -(Dot(N,E-P)*I - E*N^T)*E |
    //     |        -N^t                      Dot(N,E)         |
    //     +-                                                 -+
    //
    // where E is the eye point, P is a point on the plane, and N is a
    // unit-length plane normal.

    float dotND = normal.Dot(eye - origin);

    mEntry[ 0] = dotND - eye[0]*normal[0];
    mEntry[ 1] = -eye[0]*normal[1];
    mEntry[ 2] = -eye[0]*normal[2];
    mEntry[ 3] = -(mEntry[0]*eye[0] + mEntry[1]*eye[1] + mEntry[2]*eye[2]);
    mEntry[ 4] = -eye[1]*normal[0];
    mEntry[ 5] = dotND - eye[1]*normal[1];
    mEntry[ 6] = -eye[1]*normal[2];
    mEntry[ 7] = -(mEntry[4]*eye[0] + mEntry[5]*eye[1] + mEntry[6]*eye[2]);
    mEntry[ 8] = -eye[2]*normal[0];
    mEntry[ 9] = -eye[2]*normal[1];
    mEntry[10] = dotND- eye[2]*normal[2];
    mEntry[11] = -(mEntry[8]*eye[0] + mEntry[9]*eye[1] + mEntry[10]*eye[2]);
    mEntry[12] = -normal[0];
    mEntry[13] = -normal[1];
    mEntry[14] = -normal[2];
    mEntry[15] = eye.Dot(normal);
}
//----------------------------------------------------------------------------
HPlane::HPlane (const APoint& p0, const APoint& p1, const APoint& p2)
{
	AVector edge1 = p1 - p0;
	AVector edge2 = p2 - p0;
	AVector normal = edge1.UnitCross(edge2);
	mTuple[0] = normal[0];
	mTuple[1] = normal[1];
	mTuple[2] = normal[2];
	mTuple[3] = -p0.Dot(normal);
}
Ejemplo n.º 5
0
//----------------------------------------------------------------------------
void HMatrix::MakeObliqueProjection (const APoint& origin,
    const AVector& normal, const AVector& direction)
{
    // The projection plane is Dot(N,X-P) = 0 where N is a 3-by-1 unit-length
    // normal vector and P is a 3-by-1 point on the plane.  The projection
    // is oblique to the plane, in the direction of the 3-by-1 vector D.
    // Necessarily Dot(N,D) is not zero for this projection to make sense.
    // Given a 3-by-1 point U, compute the intersection of the line U+t*D
    // with the plane to obtain t = -Dot(N,U-P)/Dot(N,D).  Then
    //
    //   projection(U) = P + [I - D*N^T/Dot(N,D)]*(U-P)
    //
    // A 4-by-4 homogeneous transformation representing the projection is
    //
    //       +-                               -+
    //   M = | D*N^T - Dot(N,D)*I   -Dot(N,P)D |
    //       |          0^T          -Dot(N,D) |
    //       +-                               -+
    //
    // where M applies to [U^T 1]^T by M*[U^T 1]^T.  The matrix is chosen so
    // that M[3][3] > 0 whenever Dot(N,D) < 0 (projection is onto the
    // "positive side" of the plane).

    float dotND = normal.Dot(direction);
    float dotNO = origin.Dot(normal);

    mEntry[ 0] = direction[0]*normal[0] - dotND;
    mEntry[ 1] = direction[0]*normal[1];
    mEntry[ 2] = direction[0]*normal[2];
    mEntry[ 3] = -dotNO*direction[0];
    mEntry[ 4] = direction[1]*normal[0];
    mEntry[ 5] = direction[1]*normal[1] - dotND;
    mEntry[ 6] = direction[1]*normal[2];
    mEntry[ 7] = -dotNO*direction[1];
    mEntry[ 8] = direction[2]*normal[0];
    mEntry[ 9] = direction[2]*normal[1];
    mEntry[10] = direction[2]*normal[2] - dotND;
    mEntry[11] = -dotNO*direction[2];
    mEntry[12] = 0.0f;
    mEntry[13] = 0.0f;
    mEntry[14] = 0.0f;
    mEntry[15] = -dotND;
}
Ejemplo n.º 6
0
//----------------------------------------------------------------------------
void Culler::SetFrustum (const float* frustum)
{
    if (!mCamera)
    {
        assertion(false, "SetFrustum requires the existence of a camera\n");
        return;
    }

    // Copy the frustum values.
    mFrustum[Camera::VF_DMIN] = frustum[Camera::VF_DMIN];
    mFrustum[Camera::VF_DMAX] = frustum[Camera::VF_DMAX];
    mFrustum[Camera::VF_UMIN] = frustum[Camera::VF_UMIN];
    mFrustum[Camera::VF_UMAX] = frustum[Camera::VF_UMAX];
    mFrustum[Camera::VF_RMIN] = frustum[Camera::VF_RMIN];
    mFrustum[Camera::VF_RMAX] = frustum[Camera::VF_RMAX];

    float dMin2 = mFrustum[Camera::VF_DMIN]*mFrustum[Camera::VF_DMIN];
    float uMin2 = mFrustum[Camera::VF_UMIN]*mFrustum[Camera::VF_UMIN];
    float uMax2 = mFrustum[Camera::VF_UMAX]*mFrustum[Camera::VF_UMAX];
    float rMin2 = mFrustum[Camera::VF_RMIN]*mFrustum[Camera::VF_RMIN];
    float rMax2 = mFrustum[Camera::VF_RMAX]*mFrustum[Camera::VF_RMAX];

    // Get the camera coordinate frame.
    APoint position = mCamera->GetPosition();
    AVector dVector = mCamera->GetDVector();
    AVector uVector = mCamera->GetUVector();
    AVector rVector = mCamera->GetRVector();
    float dirDotEye = position.Dot(dVector);

    // Update the near plane.
    mPlane[Camera::VF_DMIN].SetNormal(dVector);
    mPlane[Camera::VF_DMIN].SetConstant(
        dirDotEye + mFrustum[Camera::VF_DMIN]);

    // Update the far plane.
    mPlane[Camera::VF_DMAX].SetNormal(-dVector);
    mPlane[Camera::VF_DMAX].SetConstant(
        -(dirDotEye + mFrustum[Camera::VF_DMAX]));

    // Update the bottom plane
    float invLength = Mathf::InvSqrt(dMin2 + uMin2);
    float c0 = -mFrustum[Camera::VF_UMIN]*invLength;  // D component
    float c1 = +mFrustum[Camera::VF_DMIN]*invLength;  // U component
    AVector normal = c0*dVector + c1*uVector;
    float constant = position.Dot(normal);
    mPlane[Camera::VF_UMIN].SetNormal(normal);
    mPlane[Camera::VF_UMIN].SetConstant(constant);

    // Update the top plane.
    invLength = Mathf::InvSqrt(dMin2 + uMax2);
    c0 = +mFrustum[Camera::VF_UMAX]*invLength;  // D component
    c1 = -mFrustum[Camera::VF_DMIN]*invLength;  // U component
    normal = c0*dVector + c1*uVector;
    constant = position.Dot(normal);
    mPlane[Camera::VF_UMAX].SetNormal(normal);
    mPlane[Camera::VF_UMAX].SetConstant(constant);

    // Update the left plane.
    invLength = Mathf::InvSqrt(dMin2 + rMin2);
    c0 = -mFrustum[Camera::VF_RMIN]*invLength;  // D component
    c1 = +mFrustum[Camera::VF_DMIN]*invLength;  // R component
    normal = c0*dVector + c1*rVector;
    constant = position.Dot(normal);
    mPlane[Camera::VF_RMIN].SetNormal(normal);
    mPlane[Camera::VF_RMIN].SetConstant(constant);

    // Update the right plane.
    invLength = Mathf::InvSqrt(dMin2 + rMax2);
    c0 = +mFrustum[Camera::VF_RMAX]*invLength;  // D component
    c1 = -mFrustum[Camera::VF_DMIN]*invLength;  // R component
    normal = c0*dVector + c1*rVector;
    constant = position.Dot(normal);
    mPlane[Camera::VF_RMAX].SetNormal(normal);
    mPlane[Camera::VF_RMAX].SetConstant(constant);

    // All planes are active initially.
    mPlaneState = 0xFFFFFFFF;
}