void MatrixBuildOrtho( VMatrix& dst, double left, double top, double right, double bottom, double zNear, double zFar ) { // FIXME: This is being used incorrectly! Should read: // D3DXMatrixOrthoOffCenterRH( &matrix, left, right, bottom, top, zNear, zFar ); // Which is certainly why we need these extra -1 scales in y. Bleah // NOTE: The camera can be imagined as the following diagram: // /z // / // /____ x Z is going into the screen // | // | // |y // // (0,0,z) represents the upper-left corner of the screen. // Our projection transform needs to transform from this space to a LH coordinate // system that looks thusly: // // y| /z // | / // |/____ x Z is going into the screen // // Where x,y lies between -1 and 1, and z lies from 0 to 1 // This is because the viewport transformation from projection space to pixels // introduces a -1 scale in the y coordinates // D3DXMatrixOrthoOffCenterRH( &matrix, left, right, top, bottom, zNear, zFar ); dst.Init( 2.0f / ( right - left ), 0.0f, 0.0f, ( left + right ) / ( left - right ), 0.0f, 2.0f / ( bottom - top ), 0.0f, ( bottom + top ) / ( top - bottom ), 0.0f, 0.0f, 1.0f / ( zNear - zFar ), zNear / ( zNear - zFar ), 0.0f, 0.0f, 0.0f, 1.0f ); }
void MatrixBuildPerspectiveX( VMatrix& dst, double flFovX, double flAspect, double flZNear, double flZFar ) { float flWidth = 2.0f * flZNear * tanf( flFovX * M_PI / 360.0f ); float flHeight = flWidth / flAspect; dst.Init( 2.0f * flZNear / flWidth, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f * flZNear/ flHeight, 0.0f, 0.0f, 0.0f, 0.0f, flZFar / ( flZNear - flZFar ), flZNear * flZFar / ( flZNear - flZFar ), 0.0f, 0.0f, -1.0f, 0.0f ); }
void CSplinePatch::SetupPatchQuery( float s, float t ) { m_is = (int)s; m_it = (int)t; if( m_is >= m_Width ) { m_is = m_Width - 1; m_fs = 1.0f; } else { m_fs = s - m_is; } if( m_it >= m_Height ) { m_it = m_Height - 1; m_ft = 1.0f; } else { m_ft = t - m_it; } ComputeIndices( ); // The patch equation is: // px = S * M * Gx * M^T * T^T // py = S * M * Gy * M^T * T^T // pz = S * M * Gz * M^T * T^T // where S = [s^3 s^2 s 1], T = [t^3 t^2 t 1] // M is the patch type matrix, in my case I'm using a catmull-rom // G is the array of control points. rows have constant t // We're gonna cache off S * M and M^T * T^T... Vector4D svec, tvec; float fs2 = m_fs * m_fs; svec[0] = fs2 * m_fs; svec[1] = fs2; svec[2] = m_fs; svec[3] = 1.0f; float ft2 = m_ft * m_ft; tvec[0] = ft2 * m_ft; tvec[1] = ft2; tvec[2] = m_ft; tvec[3] = 1.0f; // This sets up the catmull rom matrix based on the blend factor!! // we can go from linear to curvy! s_CatmullRom.Init( -0.5 * m_LinearFactor, 1.5 * m_LinearFactor, -1.5 * m_LinearFactor, 0.5 * m_LinearFactor, m_LinearFactor, -2.5 * m_LinearFactor, 2 * m_LinearFactor, -0.5 * m_LinearFactor, -0.5 * m_LinearFactor, -1 + m_LinearFactor, 1 - 0.5 * m_LinearFactor, 0, 0, 1, 0, 0 ); Vector4DMultiplyTranspose( s_CatmullRom, svec, m_SVec ); Vector4DMultiplyTranspose( s_CatmullRom, tvec, m_TVec ); }
void MatrixBuildPerspectiveOffCenterX( VMatrix& dst, double flFovX, double flAspect, double flZNear, double flZFar, double bottom, double top, double left, double right ) { float flWidth = 2.0f * flZNear * tanf( flFovX * M_PI / 360.0f ); float flHeight = flWidth / flAspect; // bottom, top, left, right are 0..1 so convert to -<val>/2..<val>/2 float flLeft = -(flWidth/2.0f) * (1.0f - left) + left * (flWidth/2.0f); float flRight = -(flWidth/2.0f) * (1.0f - right) + right * (flWidth/2.0f); float flBottom = -(flHeight/2.0f) * (1.0f - bottom) + bottom * (flHeight/2.0f); float flTop = -(flHeight/2.0f) * (1.0f - top) + top * (flHeight/2.0f); dst.Init( (2.0f * flZNear) / (flRight-flLeft), 0.0f, (flLeft+flRight)/(flRight-flLeft), 0.0f, 0.0f, 2.0f*flZNear/(flTop-flBottom), (flTop+flBottom)/(flTop-flBottom), 0.0f, 0.0f, 0.0f, flZFar/(flZNear-flZFar), flZNear*flZFar/(flZNear-flZFar), 0.0f, 0.0f, -1.0f, 0.0f ); }
void VMatrix::MatrixMul( const VMatrix &vm, VMatrix &out ) const { out.Init( m[0][0]*vm.m[0][0] + m[0][1]*vm.m[1][0] + m[0][2]*vm.m[2][0] + m[0][3]*vm.m[3][0], m[0][0]*vm.m[0][1] + m[0][1]*vm.m[1][1] + m[0][2]*vm.m[2][1] + m[0][3]*vm.m[3][1], m[0][0]*vm.m[0][2] + m[0][1]*vm.m[1][2] + m[0][2]*vm.m[2][2] + m[0][3]*vm.m[3][2], m[0][0]*vm.m[0][3] + m[0][1]*vm.m[1][3] + m[0][2]*vm.m[2][3] + m[0][3]*vm.m[3][3], m[1][0]*vm.m[0][0] + m[1][1]*vm.m[1][0] + m[1][2]*vm.m[2][0] + m[1][3]*vm.m[3][0], m[1][0]*vm.m[0][1] + m[1][1]*vm.m[1][1] + m[1][2]*vm.m[2][1] + m[1][3]*vm.m[3][1], m[1][0]*vm.m[0][2] + m[1][1]*vm.m[1][2] + m[1][2]*vm.m[2][2] + m[1][3]*vm.m[3][2], m[1][0]*vm.m[0][3] + m[1][1]*vm.m[1][3] + m[1][2]*vm.m[2][3] + m[1][3]*vm.m[3][3], m[2][0]*vm.m[0][0] + m[2][1]*vm.m[1][0] + m[2][2]*vm.m[2][0] + m[2][3]*vm.m[3][0], m[2][0]*vm.m[0][1] + m[2][1]*vm.m[1][1] + m[2][2]*vm.m[2][1] + m[2][3]*vm.m[3][1], m[2][0]*vm.m[0][2] + m[2][1]*vm.m[1][2] + m[2][2]*vm.m[2][2] + m[2][3]*vm.m[3][2], m[2][0]*vm.m[0][3] + m[2][1]*vm.m[1][3] + m[2][2]*vm.m[2][3] + m[2][3]*vm.m[3][3], m[3][0]*vm.m[0][0] + m[3][1]*vm.m[1][0] + m[3][2]*vm.m[2][0] + m[3][3]*vm.m[3][0], m[3][0]*vm.m[0][1] + m[3][1]*vm.m[1][1] + m[3][2]*vm.m[2][1] + m[3][3]*vm.m[3][1], m[3][0]*vm.m[0][2] + m[3][1]*vm.m[1][2] + m[3][2]*vm.m[2][2] + m[3][3]*vm.m[3][2], m[3][0]*vm.m[0][3] + m[3][1]*vm.m[1][3] + m[3][2]*vm.m[2][3] + m[3][3]*vm.m[3][3] ); }