Is it possible to add rigidbody2D.localToWorldMatrix to 2022.3 LTS?

I was looking to port my 2023.1 project to the more stable 2022.3 LTS, but in the process I came to realize that 2022.3 doesn’t have rb2D.localToWorldMatrix which I use extensively in my project. I can obviously replace this by creating my own matrix using the rb2d position and rotation, but after profiling it’s still 30% slower than rb2D.localToWorldMatrix even after optimizing the matrix generation the most I possibly can. My test took into account any caching that could be occurring, so the difference isn’t because of that. I can’t figure out why the built-in matrix is so much faster than creating my own. This is how I am making the matrix

	public static Matrix4x4 CreateMatrix(Vector2 position, float angle)
	{
		float rad = angle * Deg2Rad;
		float cos = (float)Math.Cos(rad);
		float sin = (float)Math.Sin(rad);
		return new Matrix4x4(
			new Vector4(cos, sin, 0, 0),
			new Vector4(-sin, cos, 0, 0),
			new Vector4(0, 0, 1, 0),
			new Vector4(position.x, position.y, 0, 1)
			);
	}
Matrix4x4 builtin = rb2D.localToWorldMatrix; //30% faster than mine
Matrix4x4 mine   = CreateMatrix(rb2D.position, rb2D.rotation);

I’m assuming it’s not possible to port it, but I figured I’d ask.

@MelvMay Sorry to tag you but I figured you’d be the one person who knows the exact answer to this.

Thanks!

Is this the basic C# .NET Math? AFAIK those methods operate on doubles not floats. Do you need that kinda precision?

Since it’s only two transcendentals in your code above I doubt it’s much, but it is something.

No but what’s faster than Math.Cos/Math.Sin? Mathf.Cos and Mathf.Sin just do the same cast and function call.

Apparently

public static void UpdateMatrix(ref Matrix4x4 mat, Vector2 position, float angle)
    {
        float rad = angle * Deg2Rad;
        float cos = (float)Math.Cos(rad);
        float sin = (float)Math.Sin(rad);
        mat.m00 = cos;
        mat.m10 = sin;
        mat.m01 = -sin;
        mat.m11 = cos;
        mat.m03 = position.x;
        mat.m13 = position.y;
    }

this is equivalent in performance to calling rb2D.localToWorldMatrix
but I have a hard time believing that’s what they’re doing under the hood.

No, we never backport API changes/features, only bugs as you suspected.

You can find that detail in this post here: How does Rigidbody2D read transform rotation?

The native code is this which does the same but in C++:

const Box2D::b2Vec2 position = m_Body->GetPosition();
const float rotation = m_Body->GetAngle();
localToWorld.SetTR(Vector3f(position.x, position.y, 0.0f), PhysicsUtility2D::RotFromZAngle(rotation));

Hope that helps.

1 Like