Search Unity

Resolved For those that don't know how to use the PostTransformScale matrix

Discussion in 'Entity Component System' started by slims, Jan 26, 2023.

  1. slims

    slims

    Joined:
    Dec 31, 2013
    Posts:
    86
    I can't be the only one that doesn't know matrix math and didn't know how to properly apply the PostTransformScale. Google yields no useful results apart from youtube videos showing old guys giving linear algebra math lessons, so I'm going to lay it out here simply:

    To set a PostTransformScale using the old float3 that you'd use in NonUniformScale, simple call

    float3x3.Scale(yourFloat3Scale)


    So if you wanted to scale something by 2 in the X direction, 3 in the Y, and 1 in the Z, you'd have this float3:

    var scale = new float3(2, 3, 1);


    Now, you want to apply this to the PostTransformScale:

    var postTransformScale = new PostTransformScale { Value = float3x3.Scale(scale) };


    Note the Scale method just creates this matrix

    Code (CSharp):
    1.             return float3x3(s,    0.0f, 0.0f,
    2.                             0.0f, s,    0.0f,
    3.                             0.0f, 0.0f, s);
    It wasn't obvious to me that float3x3 had this method, nor was it obvious how I was supposed to construct the matrix to properly apply the scale, so hopefully this will help people in the future.

    As a side note, for Unity devs, in the LocalToWorldSystem, it really seems like you could just either keep the old float3 from NonUniformScale and apply the .Scale() method yourself inside the job right before you do the multiplication, or just change the Scale property on the LocalTransform to a float3 and get rid of the post transform stuff altogether.

    In the LocalToWorldSystem system you do this:

    Code (CSharp):
    1.                         PostTransformScale* chunkPostTransformScales =
    2.                             (PostTransformScale*)chunk.GetRequiredComponentDataPtrRO(
    3.                                 ref PostTransformScaleTypeHandleRO);
    4.                         for (int i = 0, chunkEntityCount = chunk.Count; i < chunkEntityCount; ++i)
    5.                         {
    6.                             chunkWorldTransforms[i] = (WorldTransform)chunkLocalTransforms[i];
    7.                             chunkLocalToWorlds[i].Value = math.mul(chunkLocalTransforms[i].ToMatrix(),
    8.                                 new float4x4(chunkPostTransformScales[i].Value, float3.zero));
    9.                         }
    If the PostTransformScale just held a float3, do
    float3x3.Scale(chunkPostTransformScales[i].Value)
    here and that would hide the matrix from the small brain end users like myself who get real confused.

    Also, the ToMatrix method spreads the LocalTransform Scale float into a float3 anyway, so why not just let the scale be a float3 for the end user and get rid of PostTransformScale altogether?

    Anyway I'm sure there were good reasons the engineers at Unity decided on this, I am interested to know them as someone bad at matrix maths. This seems overly complicated for something that has been an established idiom in almost all game engines, including Unity itself.