How do I set the global scale of an object in a transform hierachy?

I've written a COLLADA importer that uses the element of the COLLADA file to define rotation, translation, and scale values for transforms. The values of the matrix are as follows:


Rotation and translation are working correctly by creating the coordinate basis from the x,y, and z axes, and taking the x,y, and z position values. The problem is that scale values, which are derived from the magnitude of the basis vectors represent scaling in the global coordinate system (not the local system as one would assume). This is a problem because after creating the transform, parenting it, and setting it's translation and rotation, the local system is rotated and setting transform.localScale (the only scale property available) applies the global scale values to the local system.

How do I set a transform's global scale in a transform hierarchy?

It was much easier than I was making it out to be. The COLLADA matrices make complete sense if you decompose them and set the localPosition, localScale, and localRotation as follows:

Vector3 x = new Vector3((float)matrix[0], (float)matrix[4], (float)matrix[8]);
Vector3 y = new Vector3((float)matrix[1], (float)matrix[5], (float)matrix[9]);
Vector3 z = new Vector3((float)matrix[2], (float)matrix[6], (float)matrix[10]);
float xScale         = x.magnitude;
float yScale        = y.magnitude;
float zScale        = z.magnitude;

newParentTrans.localPosition = new Vector3((float)matrix[3] * conversion,
                                                            (float)matrix[7] * conversion,
                                                            (float)matrix[11] * conversion);
newParentTrans.localScale = new Vector3(xScale, yScale, zScale);

Quaternion rotation = newParentTrans.rotation;
newParentTrans.localRotation = rotation;

Because well-formed COLLADA files have one top-level element, you can rotate the entire scene by -90 deg around the x axis, if Z_UP is true.

Maybe it will be helpful:

function GetParentScale(): Vector3 {
    var sf: Vector3 =;

    var parentTransform: Transform = null;
    if (thisTransform.parent) parentTransform = thisTransform.parent;

    while (parentTransform) {
        sf.x *= 1.0f / parentTransform.localScale.x;
        sf.y *= 1.0f / parentTransform.localScale.y;
        sf.z *= 1.0f / parentTransform.localScale.z;
        if (parentTransform.parent) {
            parentTransform = parentTransform.parent;
        } else {
            parentTransform = null;
    return sf;      

function SetScale(globalScale: Vector3) {
    var parentGlobalScale: Vector3 = GetParentScale();
    thisTransform.localScale.x = globalScale.x * parentGlobalScale.x;
    thisTransform.localScale.y = globalScale.y * parentGlobalScale.y;
    thisTransform.localScale.z = globalScale.z * parentGlobalScale.z;

where thisTransform = gameObject.transform