Refactored MatrixVectorMultiply(), added TransformDivide() for cases where perspective divide is needed

dev
Tomasz Kapuściński 2022-01-05 19:22:57 +01:00
parent 9c37f6cbd5
commit 754684bfe9
2 changed files with 20 additions and 35 deletions

View File

@ -3923,25 +3923,25 @@ void CEngine::RenderDebugBox(const glm::vec3& mins, const glm::vec3& maxs, const
auto vert = m_pendingDebugDraws.vertices.begin() + firstVert; auto vert = m_pendingDebugDraws.vertices.begin() + firstVert;
*vert++ = VertexCol{Math::MatrixVectorMultiply(transform, glm::vec3{mins.x, mins.y, mins.z}), color}; *vert++ = VertexCol{Math::Transform(transform, glm::vec3{mins.x, mins.y, mins.z}), color};
*vert++ = VertexCol{Math::MatrixVectorMultiply(transform, glm::vec3{maxs.x, mins.y, mins.z}), color}; *vert++ = VertexCol{Math::Transform(transform, glm::vec3{maxs.x, mins.y, mins.z}), color};
*vert++ = VertexCol{Math::MatrixVectorMultiply(transform, glm::vec3{maxs.x, maxs.y, mins.z}), color}; *vert++ = VertexCol{Math::Transform(transform, glm::vec3{maxs.x, maxs.y, mins.z}), color};
*vert++ = VertexCol{Math::MatrixVectorMultiply(transform, glm::vec3{maxs.x, maxs.y, maxs.z}), color}; *vert++ = VertexCol{Math::Transform(transform, glm::vec3{maxs.x, maxs.y, maxs.z}), color};
*vert++ = VertexCol{Math::MatrixVectorMultiply(transform, glm::vec3{mins.x, mins.y, maxs.z}), color}; *vert++ = VertexCol{Math::Transform(transform, glm::vec3{mins.x, mins.y, maxs.z}), color};
*vert++ = VertexCol{Math::MatrixVectorMultiply(transform, glm::vec3{mins.x, mins.y, mins.z}), color}; *vert++ = VertexCol{Math::Transform(transform, glm::vec3{mins.x, mins.y, mins.z}), color};
*vert++ = VertexCol{Math::MatrixVectorMultiply(transform, glm::vec3{mins.x, maxs.y, mins.z}), color}; *vert++ = VertexCol{Math::Transform(transform, glm::vec3{mins.x, maxs.y, mins.z}), color};
*vert++ = VertexCol{Math::MatrixVectorMultiply(transform, glm::vec3{maxs.x, maxs.y, mins.z}), color}; *vert++ = VertexCol{Math::Transform(transform, glm::vec3{maxs.x, maxs.y, mins.z}), color};
*vert++ = VertexCol{Math::MatrixVectorMultiply(transform, glm::vec3{maxs.x, mins.y, maxs.z}), color}; *vert++ = VertexCol{Math::Transform(transform, glm::vec3{maxs.x, mins.y, maxs.z}), color};
*vert++ = VertexCol{Math::MatrixVectorMultiply(transform, glm::vec3{mins.x, mins.y, maxs.z}), color}; *vert++ = VertexCol{Math::Transform(transform, glm::vec3{mins.x, mins.y, maxs.z}), color};
*vert++ = VertexCol{Math::MatrixVectorMultiply(transform, glm::vec3{mins.x, maxs.y, maxs.z}), color}; *vert++ = VertexCol{Math::Transform(transform, glm::vec3{mins.x, maxs.y, maxs.z}), color};
*vert++ = VertexCol{Math::MatrixVectorMultiply(transform, glm::vec3{mins.x, maxs.y, mins.z}), color}; *vert++ = VertexCol{Math::Transform(transform, glm::vec3{mins.x, maxs.y, mins.z}), color};
*vert++ = VertexCol{Math::MatrixVectorMultiply(transform, glm::vec3{maxs.x, mins.y, mins.z}), color}; *vert++ = VertexCol{Math::Transform(transform, glm::vec3{maxs.x, mins.y, mins.z}), color};
*vert++ = VertexCol{Math::MatrixVectorMultiply(transform, glm::vec3{maxs.x, mins.y, maxs.z}), color}; *vert++ = VertexCol{Math::Transform(transform, glm::vec3{maxs.x, mins.y, maxs.z}), color};
*vert++ = VertexCol{Math::MatrixVectorMultiply(transform, glm::vec3{maxs.x, maxs.y, maxs.z}), color}; *vert++ = VertexCol{Math::Transform(transform, glm::vec3{maxs.x, maxs.y, maxs.z}), color};
*vert++ = VertexCol{Math::MatrixVectorMultiply(transform, glm::vec3{mins.x, maxs.y, maxs.z}), color}; *vert++ = VertexCol{Math::Transform(transform, glm::vec3{mins.x, maxs.y, maxs.z}), color};
} }
void CEngine::RenderPendingDebugDraws() void CEngine::RenderPendingDebugDraws()
@ -4071,7 +4071,7 @@ void CEngine::RenderShadowMap()
// axes are aligned with the x/y/z axes (not necessarily in that order, and +/- signs don't matter). // axes are aligned with the x/y/z axes (not necessarily in that order, and +/- signs don't matter).
glm::mat4 lightRotation; glm::mat4 lightRotation;
Math::LoadViewMatrix(lightRotation, glm::vec3{0, 0, 0}, lightDir, worldUp); Math::LoadViewMatrix(lightRotation, glm::vec3{0, 0, 0}, lightDir, worldUp);
pos = Math::MatrixVectorMultiply(lightRotation, pos); pos = Math::Transform(lightRotation, pos);
// ...then we round to the nearest worldUnitsPerTexel: // ...then we round to the nearest worldUnitsPerTexel:
const float worldUnitsPerTexel = (dist * 2.0f) / m_shadowMap.size.x; const float worldUnitsPerTexel = (dist * 2.0f) / m_shadowMap.size.x;
pos /= worldUnitsPerTexel; pos /= worldUnitsPerTexel;
@ -4080,7 +4080,7 @@ void CEngine::RenderShadowMap()
pos.z = round(pos.z); pos.z = round(pos.z);
pos *= worldUnitsPerTexel; pos *= worldUnitsPerTexel;
// ...and convert back to world space. // ...and convert back to world space.
pos = Math::MatrixVectorMultiply(glm::inverse(lightRotation), pos); pos = Math::Transform(glm::inverse(lightRotation), pos);
} }
glm::vec3 lookAt = pos - lightDir; glm::vec3 lookAt = pos - lightDir;

View File

@ -612,26 +612,11 @@ inline glm::vec3 Transform(const glm::mat4 &m, const glm::vec3 &p)
} }
//! Calculates the result of multiplying m * v //! Transforms a vector \v by a matrix \m with perspective divide
/** inline glm::vec3 TransformDivide(const glm::mat4& m, const glm::vec3& v)
The multiplication is performed thus:
\verbatim
[ m.m[0 ] m.m[4 ] m.m[8 ] m.m[12] ] [ v.x ]
[ m.m[1 ] m.m[5 ] m.m[9 ] m.m[13] ] [ v.y ]
[ m.m[2 ] m.m[6 ] m.m[10] m.m[14] ] * [ v.z ]
[ m.m[3 ] m.m[7 ] m.m[11] m.m[15] ] [ 1 ]
\endverbatim
The result, a 4x1 vector is then converted to 3x1 by dividing
x,y,z coords by the fourth coord (w). */
inline glm::vec3 MatrixVectorMultiply(const glm::mat4& m, const glm::vec3& v, bool wDivide = false)
{ {
glm::vec4 result = m * glm::vec4(v, 1.0f); glm::vec4 result = m * glm::vec4(v, 1.0f);
if (!wDivide)
return result;
if (IsZero(result.w)) if (IsZero(result.w))
return glm::vec3(result); return glm::vec3(result);