From 1ad5b6b259f5fb1e72bc2b51d7e02bbc22e5ccbb Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Mon, 5 Jun 2017 13:25:07 +1000 Subject: [PATCH] Make matrix operations consistent --- ClassicalSharp/2D/IsometricBlockDrawer.cs | 5 +- ClassicalSharp/Entities/Entity.cs | 14 ++-- .../Rendering/Env/SkyboxRenderer.cs | 10 ++- ClassicalSharp/Rendering/FrustumCulling.cs | 2 +- ClassicalSharp/Utils/Camera.cs | 13 ++-- OpenTK/Math/Matrix4.cs | 74 ++++--------------- src/Client/D3D9Api.c | 4 +- src/Client/FrustumCulling.c | 2 +- src/Client/Matrix.c | 24 +++--- src/Client/Matrix.h | 25 ++++--- src/Client/SkyboxRenderer.c | 10 +-- 11 files changed, 75 insertions(+), 108 deletions(-) diff --git a/ClassicalSharp/2D/IsometricBlockDrawer.cs b/ClassicalSharp/2D/IsometricBlockDrawer.cs index 5d566878f..b3b9fdeed 100644 --- a/ClassicalSharp/2D/IsometricBlockDrawer.cs +++ b/ClassicalSharp/2D/IsometricBlockDrawer.cs @@ -43,7 +43,10 @@ namespace ClassicalSharp { static IsometricBlockDrawer() { FastColour.GetShaded(FastColour.White, out colXSide, out colZSide, out colYBottom); - transform = Matrix4.RotateY(45 * Utils.Deg2Rad) * Matrix4.RotateX(-30f * Utils.Deg2Rad); + Matrix4 rotY, rotX; + Matrix4.RotateY(out rotY, 45 * Utils.Deg2Rad); + Matrix4.RotateX(out rotX, -30f * Utils.Deg2Rad); + transform = rotY * rotX; cosX = (float)Math.Cos(30f * Utils.Deg2Rad); sinX = (float)Math.Sin(30f * Utils.Deg2Rad); diff --git a/ClassicalSharp/Entities/Entity.cs b/ClassicalSharp/Entities/Entity.cs index 8560c6487..6c538b9c4 100644 --- a/ClassicalSharp/Entities/Entity.cs +++ b/ClassicalSharp/Entities/Entity.cs @@ -112,12 +112,14 @@ namespace ClassicalSharp.Entities { } public Matrix4 TransformMatrix(float scale, Vector3 pos) { - return - Matrix4.RotateZ(-RotZ * Utils.Deg2Rad) * - Matrix4.RotateX(-RotX * Utils.Deg2Rad) * - Matrix4.RotateY(-RotY * Utils.Deg2Rad) * - Matrix4.Scale(scale) * - Matrix4.Translate(pos.X, pos.Y, pos.Z); + Matrix4 rotZ, rotX, rotY, translate, scaleM; + Matrix4.RotateX(out rotX, -RotX * Utils.Deg2Rad); + Matrix4.RotateY(out rotY, -RotY * Utils.Deg2Rad); + Matrix4.RotateZ(out rotZ, -RotZ * Utils.Deg2Rad); + Matrix4.Scale(out scaleM, scale, scale, scale); + Matrix4.Translate(out translate, pos.X, pos.Y, pos.Z); + + return rotZ * rotX * rotY * scaleM * translate; } /// Gets the brightness colour of this entity. diff --git a/ClassicalSharp/Rendering/Env/SkyboxRenderer.cs b/ClassicalSharp/Rendering/Env/SkyboxRenderer.cs index 8c0912c60..a81e8b7a1 100644 --- a/ClassicalSharp/Rendering/Env/SkyboxRenderer.cs +++ b/ClassicalSharp/Rendering/Env/SkyboxRenderer.cs @@ -63,11 +63,13 @@ namespace ClassicalSharp.Renderers { game.Graphics.BindTexture(tex); game.Graphics.SetBatchFormat(VertexFormat.P3fT2fC4b); - Matrix4 m = Matrix4.Identity; + Matrix4 m = Matrix4.Identity, rotY, rotX; Vector2 rotation = game.Camera.GetCameraOrientation(); - m *= Matrix4.RotateY(rotation.X); // yaw - m *= Matrix4.RotateX(rotation.Y); // pitch - m = m * game.Camera.tiltM; + Matrix4.RotateY(out rotY, rotation.X); // yaw + m *= rotY; + Matrix4.RotateX(out rotX, rotation.Y); // pitch + m *= rotX; + m *= game.Camera.tiltM; game.Graphics.LoadMatrix(ref m); game.Graphics.BindVb(vb); diff --git a/ClassicalSharp/Rendering/FrustumCulling.cs b/ClassicalSharp/Rendering/FrustumCulling.cs index 042423edd..458ce2ec8 100644 --- a/ClassicalSharp/Rendering/FrustumCulling.cs +++ b/ClassicalSharp/Rendering/FrustumCulling.cs @@ -34,7 +34,7 @@ namespace ClassicalSharp { public unsafe void CalcFrustumEquations(ref Matrix4 projection, ref Matrix4 modelView) { Matrix4 clipMatrix; - Matrix4.Mult(ref modelView, ref projection, out clipMatrix); + Matrix4.Mult(out clipMatrix, ref modelView, ref projection); float* clip = (float*)&clipMatrix; // Extract the numbers for the RIGHT plane diff --git a/ClassicalSharp/Utils/Camera.cs b/ClassicalSharp/Utils/Camera.cs index 425af2d95..b77943cdb 100644 --- a/ClassicalSharp/Utils/Camera.cs +++ b/ClassicalSharp/Utils/Camera.cs @@ -126,21 +126,22 @@ namespace ClassicalSharp { protected void CalcViewBobbing(float t, float velTiltScale) { if (!game.ViewBobbing) { tiltM = Matrix4.Identity; return; } - LocalPlayer p = game.LocalPlayer; - tiltM = Matrix4.RotateZ(-p.anim.tiltX * p.anim.bobStrength); - tiltM = tiltM * Matrix4.RotateX(Math.Abs(p.anim.tiltY) * 3 * p.anim.bobStrength); + Matrix4 tiltY, velX; + Matrix4.RotateZ(out tiltM, -p.anim.tiltX * p.anim.bobStrength); + Matrix4.RotateX(out tiltY, Math.Abs(p.anim.tiltY) * 3 * p.anim.bobStrength); + tiltM *= tiltY; bobbingHor = (p.anim.bobbingHor * 0.3f) * p.anim.bobStrength; bobbingVer = (p.anim.bobbingVer * 0.6f) * p.anim.bobStrength; float vel = Utils.Lerp(p.OldVelocity.Y + 0.08f, p.Velocity.Y + 0.08f, t); - tiltM = tiltM * Matrix4.RotateX(-vel * 0.05f * p.anim.velTiltStrength / velTiltScale); + Matrix4.RotateX(out velX, -vel * 0.05f * p.anim.velTiltStrength / velTiltScale); + tiltM *= velX; } protected Vector3 GetDirVector() { - return Utils.GetDirVector(player.HeadYRadians, - AdjustHeadX(player.HeadX)); + return Utils.GetDirVector(player.HeadYRadians, AdjustHeadX(player.HeadX)); } } diff --git a/OpenTK/Math/Matrix4.cs b/OpenTK/Math/Matrix4.cs index 3cf557c52..dd410067d 100644 --- a/OpenTK/Math/Matrix4.cs +++ b/OpenTK/Math/Matrix4.cs @@ -108,7 +108,7 @@ namespace OpenTK { /// Gets or sets the value at row 4, column 4 of this instance. public float M44 { get { return Row3.W; } set { Row3.W = value; } } - public static void RotateX(float angle, out Matrix4 result) { + public static void RotateX(out Matrix4 result, float angle) { float cos = (float)Math.Cos(angle); float sin = (float)Math.Sin(angle); @@ -118,13 +118,7 @@ namespace OpenTK { result.Row3 = Vector4.UnitW; } - public static Matrix4 RotateX(float angle) { - Matrix4 result; - RotateX(angle, out result); - return result; - } - - public static void RotateY(float angle, out Matrix4 result) { + public static void RotateY(out Matrix4 result, float angle) { float cos = (float)Math.Cos(angle); float sin = (float)Math.Sin(angle); @@ -134,13 +128,7 @@ namespace OpenTK { result.Row3 = Vector4.UnitW; } - public static Matrix4 RotateY(float angle) { - Matrix4 result; - RotateY(angle, out result); - return result; - } - - public static void RotateZ(float angle, out Matrix4 result) { + public static void RotateZ(out Matrix4 result, float angle) { float cos = (float)System.Math.Cos(angle); float sin = (float)System.Math.Sin(angle); @@ -150,32 +138,16 @@ namespace OpenTK { result.Row3 = Vector4.UnitW; } - public static Matrix4 RotateZ(float angle) { - Matrix4 result; - RotateZ(angle, out result); - return result; - } - - public static void Translate(float x, float y, float z, out Matrix4 result) { + public static void Translate(out Matrix4 result, float x, float y, float z) { result = Identity; result.Row3 = new Vector4(x, y, z, 1); } - - public static void Translate(ref Vector3 vector, out Matrix4 result) { - result = Identity; - result.Row3 = new Vector4(vector.X, vector.Y, vector.Z, 1); - } - - public static Matrix4 Translate(float x, float y, float z) { - Matrix4 result = Identity; - result.Row3 = new Vector4(x, y, z, 1); - return result; - } - - public static Matrix4 Translate(Vector3 vector) { - Matrix4 result = Identity; - result.Row3 = new Vector4(vector.X, vector.Y, vector.Z, 1); - return result; + + public static void Scale(out Matrix4 result, float x, float y, float z) { + result.Row0 = Vector4.UnitX; result.Row0.X *= x; + result.Row1 = Vector4.UnitY; result.Row1.Y *= y; + result.Row2 = Vector4.UnitZ; result.Row2.Z *= z; + result.Row3 = Vector4.UnitW; } public static void CreateOrthographic(float width, float height, float zNear, float zFar, out Matrix4 result) { @@ -264,23 +236,6 @@ namespace OpenTK { return result; } - public static Matrix4 Scale(float scale) { - return Scale(scale, scale, scale); - } - - public static Matrix4 Scale(Vector3 scale) { - return Scale(scale.X, scale.Y, scale.Z); - } - - public static Matrix4 Scale(float x, float y, float z) { - Matrix4 result; - result.Row0 = Vector4.UnitX; result.Row0.X *= x; - result.Row1 = Vector4.UnitY; result.Row1.Y *= y; - result.Row2 = Vector4.UnitZ; result.Row2.Z *= z; - result.Row3 = Vector4.UnitW; - return result; - } - public static Matrix4 LookAt(Vector3 eye, Vector3 target, Vector3 up) { Vector3 z = Vector3.Normalize(eye - target); Vector3 x = Vector3.Normalize(Vector3.Cross(up, z)); @@ -291,18 +246,19 @@ namespace OpenTK { new Vector4(x.Z, y.Z, z.Z, 0.0f), Vector4.UnitW); - Matrix4 trans = Matrix4.Translate(-eye); - + + Matrix4 trans; + Matrix4.Translate(out trans, -eye.X, -eye.Y, -eye.Z); return trans * rot; } public static Matrix4 Mult(Matrix4 left, Matrix4 right) { Matrix4 result; - Mult(ref left, ref right, out result); + Mult(out result, ref left, ref right); return result; } - public static void Mult(ref Matrix4 left, ref Matrix4 right, out Matrix4 result) { + public static void Mult(out Matrix4 result, ref Matrix4 left, ref Matrix4 right) { // Originally from http://www.edais.co.uk/blog/?p=27 float lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W, lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W, diff --git a/src/Client/D3D9Api.c b/src/Client/D3D9Api.c index 43d0a0df8..88e7498d4 100644 --- a/src/Client/D3D9Api.c +++ b/src/Client/D3D9Api.c @@ -424,7 +424,7 @@ void Gfx_LoadIdentityMatrix() { void Gfx_MultiplyMatrix(Matrix* matrix) { Int32 idx = curStack->Index; - Matrix_Mul(matrix, &curStack->Stack[idx], &curStack->Stack[idx]); + Matrix_Mul(&curStack->Stack[idx], matrix, &curStack->Stack[idx]); ReturnCode hresult = IDirect3DDevice9_SetTransform(device, curStack->Type, &curStack->Stack[idx]); ErrorHandler_CheckOrFail(hresult, "D3D9_MultiplyMatrix"); @@ -455,7 +455,7 @@ void Gfx_PopMatrix() { #define d3d9_zF 10000.0f void Gfx_LoadOrthoMatrix(Real32 width, Real32 height) { Matrix matrix; - Matrix_OrthographicOffCenter(0, width, height, 0, d3d9_zN, d3d9_zF, &matrix); + Matrix_OrthographicOffCenter(&matrix, 0.0f, width, height, 0.0f, d3d9_zN, d3d9_zF); matrix.Row2.Y = 1.0f / (d3d9_zN - d3d9_zF); matrix.Row2.Z = d3d9_zN / (d3d9_zN - d3d9_zF); diff --git a/src/Client/FrustumCulling.c b/src/Client/FrustumCulling.c index 5258467ab..6d6b76355 100644 --- a/src/Client/FrustumCulling.c +++ b/src/Client/FrustumCulling.c @@ -29,7 +29,7 @@ bool FrustumCulling_SphereInFrustum(Real32 x, Real32 y, Real32 z, Real32 radius) void FrustumCulling_CalcFrustumEquations(Matrix* projection, Matrix* modelView) { Matrix clipMatrix; - Matrix_Mul(modelView, projection, &clipMatrix); + Matrix_Mul(&clipMatrix, modelView, projection); Real32* clip = (Real32*)&clipMatrix; // Extract the numbers for the RIGHT plane diff --git a/src/Client/Matrix.c b/src/Client/Matrix.c index 8a5445870..ff6e36f3c 100644 --- a/src/Client/Matrix.c +++ b/src/Client/Matrix.c @@ -10,42 +10,42 @@ Matrix Matrix_Identity = { /* Transposed, copied from https://open.gl/transformations */ -void Matrix_RotateX(Real32 angle, Matrix* result) { +void Matrix_RotateX(Matrix* result, Real32 angle) { Real32 cosA = Math_Cos(angle), sinA = Math_Sin(angle); *result = Matrix_Identity; result->Row1.Y = cosA; result->Row1.Z = sinA; result->Row2.Y = -sinA; result->Row2.Z = cosA; } -void Matrix_RotateY(Real32 angle, Matrix* result) { +void Matrix_RotateY(Matrix* result, Real32 angle) { Real32 cosA = Math_Cos(angle), sinA = Math_Sin(angle); *result = Matrix_Identity; result->Row1.X = cosA; result->Row1.Z = -sinA; result->Row2.X = sinA; result->Row2.Z = cosA; } -void Matrix_RotateZ(Real32 angle, Matrix* result) { +void Matrix_RotateZ(Matrix* result, Real32 angle) { Real32 cosA = Math_Cos(angle), sinA = Math_Sin(angle); *result = Matrix_Identity; result->Row1.X = cosA; result->Row1.Y = sinA; result->Row2.X = -sinA; result->Row2.Y = cosA; } -void Matrix_Translate(Real32 x, Real32 y, Real32 z, Matrix* result) { +void Matrix_Translate(Matrix* result, Real32 x, Real32 y, Real32 z) { *result = Matrix_Identity; result->Row3.X = x; result->Row3.Y = y; result->Row3.Z = z; } -void Matrix_Scale(Real32 x, Real32 y, Real32 z, Matrix* result) { +void Matrix_Scale(Matrix* result, Real32 x, Real32 y, Real32 z) { *result = Matrix_Identity; result->Row0.X = x; result->Row1.Y = y; result->Row2.Z = z; } -void Matrix_Mul(Matrix* left, Matrix* right, Matrix* result) { +void Matrix_Mul(Matrix* result, Matrix* left, Matrix* right) { /* Originally from http://www.edais.co.uk/blog/?p=27 */ Real32 lM11 = left->Row0.X, lM12 = left->Row0.Y, lM13 = left->Row0.Z, lM14 = left->Row0.W, @@ -81,11 +81,11 @@ void Matrix_Mul(Matrix* left, Matrix* right, Matrix* result) { -void Matrix_Orthographic(Real32 width, Real32 height, Real32 zNear, Real32 zFar, Matrix* result) { - Matrix_OrthographicOffCenter(-width * 0.5f, width * 0.5f, -height * 0.5f, height * 0.5f, zNear, zFar, result); +void Matrix_Orthographic(Matrix* result, Real32 width, Real32 height, Real32 zNear, Real32 zFar) { + Matrix_OrthographicOffCenter(result, -width * 0.5f, width * 0.5f, -height * 0.5f, height * 0.5f, zNear, zFar); } -void Matrix_OrthographicOffCenter(Real32 left, Real32 right, Real32 bottom, Real32 top, Real32 zNear, Real32 zFar, Matrix* result) { +void Matrix_OrthographicOffCenter(Matrix* result, Real32 left, Real32 right, Real32 bottom, Real32 top, Real32 zNear, Real32 zFar) { /* Transposed, sourced from https://msdn.microsoft.com/en-us/library/dd373965(v=vs.85).aspx */ *result = Matrix_Identity; @@ -98,12 +98,12 @@ void Matrix_OrthographicOffCenter(Real32 left, Real32 right, Real32 bottom, Real result->Row3.Z = -(zFar + zNear) / (zFar - zNear); } -void Matrix_PerspectiveFieldOfView(Real32 fovy, Real32 aspect, Real32 zNear, Real32 zFar, Matrix* result) { +void Matrix_PerspectiveFieldOfView(Matrix* result, Real32 fovy, Real32 aspect, Real32 zNear, Real32 zFar) { Real32 c = zNear * Math_Tan(0.5f * fovy); - Matrix_PerspectiveOffCenter(-c * aspect, c * aspect, -c, c, zNear, zFar, result); + Matrix_PerspectiveOffCenter(result, -c * aspect, c * aspect, -c, c, zNear, zFar); } -void Matrix_PerspectiveOffCenter(Real32 left, Real32 right, Real32 bottom, Real32 top, Real32 zNear, Real32 zFar, Matrix* result) { +void Matrix_PerspectiveOffCenter(Matrix* result, Real32 left, Real32 right, Real32 bottom, Real32 top, Real32 zNear, Real32 zFar) { /* Transposed, sourced from https://msdn.microsoft.com/en-us/library/dd373537(v=vs.85).aspx */ *result = Matrix_Identity; diff --git a/src/Client/Matrix.h b/src/Client/Matrix.h index 0d2d33156..c643475e1 100644 --- a/src/Client/Matrix.h +++ b/src/Client/Matrix.h @@ -25,37 +25,40 @@ typedef struct Matrix { extern Matrix Matrix_Identity; /* Transformation matrix representing rotation angle radians around X axis. */ -void Matrix_RotateX(Real32 angle, Matrix* result); +void Matrix_RotateX(Matrix* result, Real32 angle); /* Transformation matrix representing rotation angle radians around Y axis. */ -void Matrix_RotateY(Real32 angle, Matrix* result); +void Matrix_RotateY(Matrix* result, Real32 angle); /* Transformation matrix representing rotation angle radians around Z axis. */ -void Matrix_RotateZ(Real32 angle, Matrix* result); +void Matrix_RotateZ(Matrix* result, Real32 angle); /* Transformation matrix representing translation of given coordinates. */ -void Matrix_Translate(Real32 x, Real32 y, Real32 z, Matrix* result); +void Matrix_Translate(Matrix* result, Real32 x, Real32 y, Real32 z); /* Transformation matrix representing scaling of given axes. */ -void Matrix_Scale(Real32 x, Real32 y, Real32 z, Matrix* result); +void Matrix_Scale(Matrix* result, Real32 x, Real32 y, Real32 z); +/* Multiplies a matrix by another.*/ +#define Matrix_MulBy(dst, right) Matrix_Mul(dst, dst, right) + /* Multiplies two matrices.*/ -void Matrix_Mul(Matrix* left, Matrix* right, Matrix* result); +void Matrix_Mul(Matrix* result, Matrix* left, Matrix* right); /* Transformation matrix representing orthographic projection. */ -void Matrix_Orthographic(Real32 width, Real32 height, Real32 zNear, Real32 zFar, Matrix* result); +void Matrix_Orthographic(Matrix* result, Real32 width, Real32 height, Real32 zNear, Real32 zFar); /* Transformation matrix representing orthographic projection. */ -void Matrix_OrthographicOffCenter(Real32 left, Real32 right, Real32 bottom, Real32 top, Real32 zNear, Real32 zFar, Matrix* result); +void Matrix_OrthographicOffCenter(Matrix* result, Real32 left, Real32 right, Real32 bottom, Real32 top, Real32 zNear, Real32 zFar); /* Transformation matrix representing perspective projection. */ -void Matrix_PerspectiveFieldOfView(Real32 fovy, Real32 aspect, Real32 zNear, Real32 zFar, Matrix* result); +void Matrix_PerspectiveFieldOfView(Matrix* result, Real32 fovy, Real32 aspect, Real32 zNear, Real32 zFar); /* Transformation matrix representing perspective projection. */ -void Matrix_PerspectiveOffCenter(Real32 left, Real32 right, Real32 bottom, Real32 top, Real32 zNear, Real32 zFar, Matrix* result); +void Matrix_PerspectiveOffCenter(Matrix* result, Real32 left, Real32 right, Real32 bottom, Real32 top, Real32 zNear, Real32 zFar); /* Transformation matrix representing camera look at. */ -void Matrix_LookAt(Vector3 eye, Vector3 target, Vector3 up, Matrix* result); +void Matrix_LookAt(Matrix* result, Vector3 eye, Vector3 target, Vector3 up); #endif \ No newline at end of file diff --git a/src/Client/SkyboxRenderer.c b/src/Client/SkyboxRenderer.c index 6db884a52..5bf2594ed 100644 --- a/src/Client/SkyboxRenderer.c +++ b/src/Client/SkyboxRenderer.c @@ -76,12 +76,12 @@ void SkyboxRenderer_Render(Real64 deltaTime) { Vector2 rotation = Camera_ActiveCamera->GetCameraOrientation(); Matrix rotX, rotY; - Matrix_RotateY(rotation.Y, &rotY); /* Yaw */ - Matrix_Mul(&m, &rotY, &m); - Matrix_RotateX(rotation.X, &rotX); /* Pitch */ - Matrix_Mul(&m, &rotY, &m); + Matrix_RotateY(&rotY, rotation.Y); /* Yaw */ + Matrix_MulBy(&m, &rotY); + Matrix_RotateX(&rotX, rotation.X); /* Pitch */ + Matrix_MulBy(&m, &rotX); /* Tilt skybox too. */ - Matrix_Mul(&m, &Camera_ActiveCamera->tiltM, &m); + Matrix_MulBy(&m, &Camera_ActiveCamera->tiltM); Gfx_LoadMatrix(&m); Gfx_BindVb(skybox_vb);