Zup, Yup, Xup - handedness space conversion?

I've been writing a dae collada importer, all is going well with geometries etc,

I am a little stuck to implement a quick method when it comes to converting geometry and transform data from Z-up, X-up to unitys Y-up world space.

I already can translate,rotate and scale geometry vertices on a node level to the correct positions by multiplying the imported vertex data by the geometry nodes transfrom data using a TRS matrix and MultiplyPoint3x4(vtx), but am looking for a decent/quick method to correct the vertex and transform data to correspond with unity's cartesian co-ord system.

some kind of vertex pos/translate pos from (a,b,c) to (b,0-a,c) and possibly some kind of quaternion or Euler.v3 from (a,b,c,w)/(a,b,c) to (0-c,b,0-a)

Any links to code or anything not too algebraic would be most usefull.

I found the below is working with Max and sketchup exports:

``````    private Vector3 UpPosConv(Vector3 v) {
Vector3 r=new Vector3();
//All x,y,z Up right handed -> Y_up left, Vertex or Translate Positions
switch (up_axis) {
case 0: //xR-yL
r=new Vector3(0-v.y,v.x,0-v.z);
break;
case 1: //yR-yL
r=new Vector3(v.x,v.y,0-v.z);
break;
case 2: //zR-zL
r=new Vector3(v.x,v.z,v.y);
break;
}
return r;
}

private Vector3 UpScaleConv(Vector3 v) {
Vector3 r=new Vector3();
//All x,y,z Up right handed -> Y_up left, Scale Factors
switch (up_axis) {
case 0: //xR-yL
r=new Vector3(v.y,v.x,v.z);
break;
case 1: //yR-yL
r=new Vector3(v.x,v.y,v.z);
break;
case 2: //zR-zL
r=new Vector3(v.x,v.z,v.y);
break;
}
return r;
}

private Vector3 UpRotDirConv(Vector3 v) {
Vector3 r=new Vector3();
//All x,y,z Up right handed -> Y_up left,Convert Rotation(axis)Directions
switch (up_axis) {
case 0: //xR-yL
r=new Vector3(v.y,0-v.x,v.z);
break;
case 1: //yR-yL
r=new Vector3(0-v.x,0-v.y,v.z);
break;
case 2: //zR-zL
r=new Vector3(0-v.x,0-v.z,0-v.y);
break;
}
return r;
}

``````

I am concerned that this may be wrong and is only working with the examples I can get hold of or create.

Took a while to get back with this, but for other people here’s my working fix:-

In 3D, we have a total of 48 different combinations of space coordinates to choose from:-

2 handed (or single axis flipped) systems x 3 axis x 4 (90 degree possible rotations around each (generally))x 2 (possible 2 flipped axis variations on the same hand same rotation) = 48 possibilities.

There are 6 ways to notate xyz in a file but this would essentially replicate one of the 48 possibilities simply converting it from one possibility to another.

The functions below will only cover translating from the 6 basic types (2 handed (or single axis flipped) systems x 3 axis) to Y-Up Left Hand system used by unity, so discounting the one that unity uses equals five conversions & one non conversion, this also presumes all notation is written x,y,z irrespective of direction.

I couldn’t find a way to do this with a matrix, was possibly thinking of a reflection matrix as the axis need shifting. Any optimisations, corrections, please amend.

``````private Vector3 PositionToYUpLH(Vector3 v,bool RightHanded,int UpAxis) {
Vector3 r=new Vector3();
if (!RightHanded) {
r=UpAxis==0?new Vector3(v.z,v.x,v.y):UpAxis==1?new Vector3(v.x,v.y,v.z):new Vector3(v.y,v.z,v.x);
} else {
r=UpAxis==0?new Vector3(0-v.z,v.x,v.y):UpAxis==1?new Vector3(0-v.x,v.y,v.z):new Vector3(0-v.y,v.z,v.x);
}
return r;
}

private Vector3 RotationToYUpLH(Vector3 v,bool RightHanded,int UpAxis) {
Vector3 r=new Vector3();
if (!RightHanded) {
r=UpAxis==0?new Vector3(v.z,v.x,v.y):UpAxis==1?new Vector3(v.x,v.y,v.z):new Vector3(v.y,v.z,v.x);
} else {
r=UpAxis==0?new Vector3(v.z,0-v.x,0-v.y):UpAxis==1?new Vector3(v.x,0-v.y,0-v.z):new Vector3(v.y,0-v.z,0-v.x);
}
return r;
}

private Vector3 ConvertScaleToYUpLH(Vector3 v,bool RightHanded,int UpAxis) {
Vector3 r=new Vector3();
r=UpAxis==0?new Vector3(v.z,v.x,v.y):UpAxis==1?new Vector3(v.x,v.y,v.z):new Vector3(v.y,v.z,v.x);
return r;
}
``````