Matrix4 Matrix4::multiply(Matrix4 a) { Matrix4 b; /* for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { b.m[i][j] = m[0][j] * a.m[i][0] + m[1][j] * a.m[i][1] + m[2][j] * a.m[i][2] + m[3][j] * a.m[i][3]; } }*/ Vector4 row1(m[0][0], m[1][0], m[2][0], m[3][0]); Vector4 row2(m[0][1], m[1][1], m[2][1], m[3][1]); Vector4 row3(m[0][2], m[1][2], m[2][2], m[3][2]); Vector4 row4(m[0][3], m[1][3], m[2][3], m[3][3]); Vector4 col1(a.m[0][0], a.m[0][1], a.m[0][2], a.m[0][3]); Vector4 col2(a.m[1][0], a.m[1][1], a.m[1][2], a.m[1][3]); Vector4 col3(a.m[2][0], a.m[2][1], a.m[2][2], a.m[2][3]); Vector4 col4(a.m[3][0], a.m[3][1], a.m[3][2], a.m[3][3]); b.set(row1.dot(col1), row2.dot(col1), row3.dot(col1), row4.dot(col1), row1.dot(col2), row2.dot(col2), row3.dot(col2), row4.dot(col2), row1.dot(col3), row2.dot(col3), row3.dot(col3), row4.dot(col3), row1.dot(col4), row2.dot(col4), row3.dot(col4), row4.dot(col4)); return b; }
// Return a matrix to represent a nonuniform scale with the given factors. Matrix4x4 scaling(const Vector3D& scale) { Vector4D row1(scale[0], 0, 0, 0); Vector4D row2(0, scale[1], 0, 0); Vector4D row3(0, 0, scale[2], 0); Vector4D row4(0, 0, 0, 1); Matrix4x4 s(row1, row2, row3, row4); return s; }
// Return a matrix to represent a displacement of the given vector. Matrix4x4 translation(const Vector3D& displacement) { Vector4D row1(1, 0, 0, displacement[0]); Vector4D row2(0, 1, 0, displacement[1]); Vector4D row3(0, 0, 1, displacement[2]); Vector4D row4(0, 0, 0, 1); Matrix4x4 t(row1, row2, row3, row4); return t; }
std::vector<QVector> ViewingParams::updateVewingTranformationMatrix(){ QVector row1(eyeCoord[0].getX(),eyeCoord[1].getX(),eyeCoord[2].getX(),eye.getX()); QVector row2(eyeCoord[0].getY(),eyeCoord[1].getY(),eyeCoord[2].getY(),eye.getY()); QVector row3(eyeCoord[0].getZ(),eyeCoord[1].getZ(),eyeCoord[2].getZ(),eye.getZ()); QVector row4(0,0,0,1); transMatrix.clear(); transMatrix.push_back(row1); transMatrix.push_back(row2); transMatrix.push_back(row3); transMatrix.push_back(row4); return transMatrix; }
FMatrix OSVRHMDDescription::GetProjectionMatrix(float left, float right, float bottom, float top, float nearClip, float farClip) const { // original code //float sumRightLeft = static_cast<float>(right + left); //float sumTopBottom = static_cast<float>(top + bottom); //float inverseRightLeft = 1.0f / static_cast<float>(right - left); //float inverseTopBottom = 1.0f / static_cast<float>(top - bottom); //FPlane row1(2.0f * inverseRightLeft, 0.0f, 0.0f, 0.0f); //FPlane row2(0.0f, 2.0f * inverseTopBottom, 0.0f, 0.0f); //FPlane row3((sumRightLeft * inverseRightLeft), (sumTopBottom * inverseTopBottom), 0.0f, 1.0f); //FPlane row4(0.0f, 0.0f, zNear, 0.0f); // OSVR Render Manager OSVR_Projection_to_D3D with adjustment for unreal (from steamVR plugin) OSVR_ProjectionMatrix projection; projection.left = static_cast<double>(left); projection.right = static_cast<double>(right); projection.top = static_cast<double>(top); projection.bottom = static_cast<double>(bottom); projection.nearClip = static_cast<double>(nearClip); // @todo Since farClip may be FLT_MAX, round-trip casting to double // and back (via the OSVR_Projection_to_Unreal call) it should // be checked for conversion issues. projection.farClip = static_cast<double>(farClip); float p[16]; OSVR_Projection_to_Unreal(p, projection); FPlane row1(p[0], p[1], p[2], p[3]); FPlane row2(p[4], p[5], p[6], p[7]); FPlane row3(p[8], p[9], p[10], p[11]); FPlane row4(p[12], p[13], p[14], p[15]); FMatrix ret = FMatrix(row1, row2, row3, row4); //ret.M[3][3] = 0.0f; //ret.M[2][3] = 1.0f; //ret.M[2][2] = 0.0f; //ret.M[3][2] = nearClip; // This was suggested by Nick at Epic, but doesn't seem to work? Black screen. //ret.M[2][2] = nearClip / (nearClip - farClip); //ret.M[3][2] = -nearClip * nearClip / (nearClip - farClip); // Adjustment suggested on a forum post for an off-axis projection. Doesn't work. //ret *= 1.0f / ret.M[0][0]; //ret.M[3][2] = GNearClippingPlane; return ret; }