matrix.decompose

by MaxenceBrasselet

HTML

<script src="https://rawgithub.com/BabylonJS/Babylon.js/master/babylon.1.8.0.js"></script>
<div id="rootDiv">
  <canvas id="renderCanvas"></canvas>
</div>

CSS

html, body, div, canvas {
    width: 100%;
    height: 100%;
    padding: 0;
    margin: 0;
    overflow: hidden;
}

JavaScript

function sign(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; }

BABYLON.Matrix.prototype.toQuaternion = function() {
    var mat = this.clone();
    
    mat.setTranslation(BABYLON.Vector3.Zero());
    mat.removeScale();
    
    var q = new BABYLON.Quaternion(0, 0, 0, 0);
    
    /*/ V1 (http://www.cg.info.hiroshima-cu.ac.jp/~miyazaki/knowledge/teche52.html)
    
    q.x = (mat.m[0] + mat.m[5] + mat.m[10] + 1) / 4;
    q.y = (mat.m[0] - mat.m[5] - mat.m[10] + 1) / 4;
    q.z = (-mat.m[0] + mat.m[5] - mat.m[10] + 1) / 4;
    q.w = (-mat.m[0] - mat.m[5] + mat.m[10] + 1) / 4;
    
    if(q.x < 0) q.x = 0;
    if(q.y < 0) q.y = 0;
    if(q.z < 0) q.z = 0;
    if(q.w < 0) q.w = 0;
    
    q.x = Math.sqrt(q.x);
    q.y = Math.sqrt(q.y);
    q.z = Math.sqrt(q.z);
    q.w = Math.sqrt(q.w);
    
    if(q.x >= q.y && q.x >= q.z && q.x >= q.w) {b
//        q.x *= 1;
//        q.y *= sign(r21 - r12);
//        q.z *= sign(r02 - r20);
//        q.w *= sign(r10 - r01);
        
        q.x *= 1;        
        q.y *= sign(mat.m[9] - mat.m[6]);
        q.z *= sign(mat.m[2] - mat.m[8]);
        q.w *= sign(mat.m[4] - mat.m[1]);
    } 
    else if(q.y >= q.x && q.y >= q.z && q.y >= q.w) {
//        q.x *= Math.sign(r21 - r12);
//        q.x *= 1;        
//        q.z *= sign(r10 + r01);
//        q.w *= sign(r02 + r20);
        
        q.x *= sign(mat.m[9] - mat.m[6]);
        q.y *= 1;
        q.z *= sign(mat.m[4] + mat.m[1]);
        q.w *= sign(mat.m[2] + mat.m[8]);
    }
    else if(q.z >= q.x && q.z >= q.y && q.z >= q.w) {
//        q.x *= sign(r02 - r20);
//        q.y *= sign(r10 + r01);
//        q.z *= 1;        
//        q.w *= sign(r21 + r12);
        
        q.x *= sign(mat.m[2] - mat.m[8]);
        q.y *= sign(mat.m[4] + mat.m[1]);
        q.z *= 1;
        q.w *= sign(mat.m[9] + mat.m[6]);
    } 
    else if(q.w >= q.x && q.w >= q.y && q.w >= q.z) {
//        q.x *= sign(r10 - r01);
//        q.y *= sign(r20 + r02);
//        q.z *= sign(r21 + r12);
//        q.w...