src/core/engines/ogl/ogl.js
/**
     * This method calculates the transformations between the Geo coordinate system and the current WebXR session
     * based on a pair of (localImagePose, globalImagePose) that belong to the same photo.
     * @param {*} localImagePose The local pose of the photo
     * @param {*} globalImagePose The global pose of the photo
     */
This method calculates the transformations between the Geo coordinate system and the current WebXR session
based on a pair of (localImagePose, globalImagePose) that belong to the same photo.
@param {*} localImagePose The local pose of the photo
@param {*} globalImagePose The global pose of the photo
This method calculates the transformations between the Geo coordinate system and the current WebXR session based on a pair of ( localImagePose globalImagePose ) that belong to the same photo . @param { * } localImagePose The local pose of the photo @param { * } globalImagePose The global pose of the photo
beginSpatialContentRecords(localImagePose, globalImagePose) {
        let localImageOrientation = quat.fromValues(localImagePose.orientation.x,
                                                    localImagePose.orientation.y,
                                                    localImagePose.orientation.z,
                                                    localImagePose.orientation.w);
        let arCamNode = new Transform(); 
        scene.addChild(arCamNode);
        let arCamSubNode = createAxesBoxPlaceholder(gl, [1, 1, 0, 0.5], false) 
        arCamSubNode.scale.set(0.02, 0.04, 0.06);
        arCamSubNode.position.set(0.001, 0.001, 0.001); 
        arCamNode.addChild(arCamSubNode);
        arCamNode.position.set(localImagePose.position.x,
                               localImagePose.position.y,
                               localImagePose.position.z);
        arCamNode.quaternion.set(localImagePose.orientation.x,
                                 localImagePose.orientation.y,
                                 localImagePose.orientation.z,
                                 localImagePose.orientation.w);
        _geo2ArTransformNode = new Transform();
        scene.addChild(_geo2ArTransformNode);
        _geo2ArTransformNode.position.set(0,0,0);
        _geo2ArTransformNode.quaternion.set(0,0,0,1);
        let geoCamNode = createAxesBoxPlaceholder(gl, [0, 1, 1, 0.5], false) 
        _geo2ArTransformNode.addChild(geoCamNode);
        geoCamNode.scale.set(0.02, 0.04, 0.06);
        let geoCamRelativePosition = getRelativeGlobalPosition(globalImagePose, globalImagePose); 
        geoCamRelativePosition = convertAugmentedCityCam2WebVec3(geoCamRelativePosition); 
        geoCamNode.position.set(geoCamRelativePosition[0],
                                geoCamRelativePosition[1],
                                geoCamRelativePosition[2]); 
        let globalImagePoseQuaternion = quat.fromValues(globalImagePose.quaternion.x,
                                                        globalImagePose.quaternion.y,
                                                        globalImagePose.quaternion.z,
                                                        globalImagePose.quaternion.w);
        let geoCamOrientation = convertAugmentedCityCam2WebQuat(globalImagePoseQuaternion); 
        geoCamNode.quaternion.set(geoCamOrientation[0],
                                  geoCamOrientation[1],
                                  geoCamOrientation[2],
                                  geoCamOrientation[3]);
        let geoCoordinateSystemNode = createAxesBoxPlaceholder(gl, [1, 1, 1, 0.5]); 
        _geo2ArTransformNode.addChild(geoCoordinateSystemNode);
        geoCoordinateSystemNode.scale.set(0.02, 0.04, 0.06);
        let geoCoordinateSystemRelativePosition = getRelativeGlobalPosition(globalImagePose, globalImagePose); 
        geoCoordinateSystemRelativePosition = convertGeo2WebVec3(geoCoordinateSystemRelativePosition); 
        geoCoordinateSystemNode.position.set(geoCoordinateSystemRelativePosition[0],
                                             geoCoordinateSystemRelativePosition[1],
                                             geoCoordinateSystemRelativePosition[2]); 
        geoCoordinateSystemNode.quaternion.set(0,0,0,1); 
        let deltaRotAr2Geo = getRelativeOrientation(localImageOrientation, geoCamOrientation); 
        let deltaRotGeo2Ar = quat.create(); 
        quat.invert(deltaRotGeo2Ar, deltaRotAr2Geo);
        _globalImagePose = globalImagePose;
        _localImagePose = localImagePose;
        _geo2ArTransformNode.quaternion.set(deltaRotGeo2Ar[0], deltaRotGeo2Ar[1], deltaRotGeo2Ar[2], deltaRotGeo2Ar[3]); 
        _geo2ArTransformNode.position.x = _geo2ArTransformNode.position.x + localImagePose.position.x;
        _geo2ArTransformNode.position.y = _geo2ArTransformNode.position.y + localImagePose.position.y;
        _geo2ArTransformNode.position.z = _geo2ArTransformNode.position.z + localImagePose.position.z;
        _geo2ArTransformNode.updateMatrix();
        _geo2ArTransformNode.updateMatrixWorld(true);
        _ar2GeoTransformNode = new Transform();
        scene.addChild(_ar2GeoTransformNode);
        _ar2GeoTransformNode.matrix.inverse(_geo2ArTransformNode.matrix);
        _ar2GeoTransformNode.decompose();
        _ar2GeoTransformNode.updateMatrixWorld(true);
    }
beginSpatialContentRecords ( localImagePose , globalImagePose ) { let localImageOrientation = quat . fromValues ( localImagePose . orientation . x , localImagePose . orientation . y , localImagePose . orientation . z , localImagePose . orientation . w ) ; let arCamNode = new Transform ( ) ; scene . addChild ( arCamNode ) ; let arCamSubNode = createAxesBoxPlaceholder ( gl , [ 1 , 1 , 0 , 0.5 ] , false ) arCamSubNode . scale . set ( 0.02 , 0.04 , 0.06 ) ; arCamSubNode . position . set ( 0.001 , 0.001 , 0.001 ) ; arCamNode . addChild ( arCamSubNode ) ; arCamNode . position . set ( localImagePose . position . x , localImagePose . position . y , localImagePose . position . z ) ; arCamNode . quaternion . set ( localImagePose . orientation . x , localImagePose . orientation . y , localImagePose . orientation . z , localImagePose . orientation . w ) ; _geo2ArTransformNode = new Transform ( ) ; scene . addChild ( _geo2ArTransformNode ) ; _geo2ArTransformNode . position . set ( 0 , 0 , 0 ) ; _geo2ArTransformNode . quaternion . set ( 0 , 0 , 0 , 1 ) ; let geoCamNode = createAxesBoxPlaceholder ( gl , [ 0 , 1 , 1 , 0.5 ] , false ) _geo2ArTransformNode . addChild ( geoCamNode ) ; geoCamNode . scale . set ( 0.02 , 0.04 , 0.06 ) ; let geoCamRelativePosition = getRelativeGlobalPosition ( globalImagePose , globalImagePose ) ; geoCamRelativePosition = convertAugmentedCityCam2WebVec3 ( geoCamRelativePosition ) ; geoCamNode . position . set ( geoCamRelativePosition [ 0 ] , geoCamRelativePosition [ 1 ] , geoCamRelativePosition [ 2 ] ) ; let globalImagePoseQuaternion = quat . fromValues ( globalImagePose . quaternion . x , globalImagePose . quaternion . y , globalImagePose . quaternion . z , globalImagePose . quaternion . w ) ; let geoCamOrientation = convertAugmentedCityCam2WebQuat ( globalImagePoseQuaternion ) ; geoCamNode . quaternion . set ( geoCamOrientation [ 0 ] , geoCamOrientation [ 1 ] , geoCamOrientation [ 2 ] , geoCamOrientation [ 3 ] ) ; let geoCoordinateSystemNode = createAxesBoxPlaceholder ( gl , [ 1 , 1 , 1 , 0.5 ] ) ; _geo2ArTransformNode . addChild ( geoCoordinateSystemNode ) ; geoCoordinateSystemNode . scale . set ( 0.02 , 0.04 , 0.06 ) ; let geoCoordinateSystemRelativePosition = getRelativeGlobalPosition ( globalImagePose , globalImagePose ) ; geoCoordinateSystemRelativePosition = convertGeo2WebVec3 ( geoCoordinateSystemRelativePosition ) ; geoCoordinateSystemNode . position . set ( geoCoordinateSystemRelativePosition [ 0 ] , geoCoordinateSystemRelativePosition [ 1 ] , geoCoordinateSystemRelativePosition [ 2 ] ) ; geoCoordinateSystemNode . quaternion . set ( 0 , 0 , 0 , 1 ) ; let deltaRotAr2Geo = getRelativeOrientation ( localImageOrientation , geoCamOrientation ) ; let deltaRotGeo2Ar = quat . create ( ) ; quat . invert ( deltaRotGeo2Ar , deltaRotAr2Geo ) ; _globalImagePose = globalImagePose ; _localImagePose = localImagePose ; _geo2ArTransformNode . quaternion . set ( deltaRotGeo2Ar [ 0 ] , deltaRotGeo2Ar [ 1 ] , deltaRotGeo2Ar [ 2 ] , deltaRotGeo2Ar [ 3 ] ) ; _geo2ArTransformNode . position . x = _geo2ArTransformNode . position . x + localImagePose . position . x ; _geo2ArTransformNode . position . y = _geo2ArTransformNode . position . y + localImagePose . position . y ; _geo2ArTransformNode . position . z = _geo2ArTransformNode . position . z + localImagePose . position . z ; _geo2ArTransformNode . updateMatrix ( ) ; _geo2ArTransformNode . updateMatrixWorld ( true ) ; _ar2GeoTransformNode = new Transform ( ) ; scene . addChild ( _ar2GeoTransformNode ) ; _ar2GeoTransformNode . matrix . inverse ( _geo2ArTransformNode . matrix ) ; _ar2GeoTransformNode . decompose ( ) ; _ar2GeoTransformNode . updateMatrixWorld ( true ) ; }
This method calculates the transformations between the Geo coordinate system and the current WebXR session
 based on a pair of (localImagePose, globalImagePose) that belong to the same photo.
This method calculates the transformations between the Geo coordinate system and the current WebXR session based on a pair of ( localImagePose globalImagePose ) that belong to the same photo .
// NOTE: // The GeoPose location coordinates are in local tangent plane (LTP) approximation, in // East-North-Up (ENU) right-handed coordinate system // https://en.wikipedia.org/wiki/Local_tangent_plane_coordinates // The GeoPose orientation is ENU (but it used to be WebXR (Y up) in the previous version) // The WebXR (and OGL Renderer's scene) coordinate system has its origin where the AR session started, // and uses a Y up right-handed coordinate system. // We receive the GeoPose of the camera and the GeoPoses of objects, plus the local pose of the camera in the WebXR coordinate system. // We want to place the objects in the WebXR coordinate system, and we know the position of the objects relative to the camera. // The basic idea is the following: // 1. calculate the relative displacement between camera and object in Geo coordinate system (LTP approximation East-North-Up) // 2. convert relative displacement from Geo (right handed, Z up) to WebXR/GLEngine (right handed, Y up). // 3. OLD AC API: //      calculate the _relative_ rotation between the camera in local and the camera in global coordinate system (both orientations were given in WebXR coordinates). //    NEW AC API: //      stay in the ENU system, just take the ENU quaternion but rotate it by additional -90 around UP so that the camera orientation is measured w.r.t North instead of East. //      Next, swap the axes from ENU to match the WebXR axes. No relative calculations needed. // 4. We create a new scene node, which will represent the camera in the Geo system. // 5. For all objects, we create a scene node and append the relative transformation (calculated in the Geo system) between camera and object as child of the camera node. // 6. We rotate the camera node to match the WebXR coordinate system // 7. We translate the camera node to the local camera pose. // (It is unsure whether and how we need to take into account the photo's portrait/landscape orientation, and similary the UI orientation, and the camera sensor orientation) // We add the AR Camera for visualization // this represents the camera in the WebXR coordinate system // This is a virtual node at the local camera pose where the photo was taken // yellow // tiny offset so that we can see both the yellow and the cyan when the alignment is correct // DEBUG: place GeoPose of camera as a content entry with full orientation // this should appear exactly where the picture was taken, with the same orientation of the camera in the world // cyan // will be (0,0,0) // convert from AC to WebXR // from vec3 to Vec3 // convert from AC to WebXR // DEBUG: place GeoPose of camera as a content entry with zero orientation // this should appear exactly where the picture was taken, but oriented according to the Geo axes. // white // will be (0,0,0) // convert from Geo to WebXR // from vec3 to Vec3 // neutral orientation // WebXR to Geo // Geo to WebXR // rotate around the origin by the rotation that brings the Geo system to the WebXR system // from quat to Quat // translate to the camera position // [R|t]^{-1} = [R^{T} | -R^{T} * t] // there is no matrix-vector multiplication in OGL :( Therefore we do the pose inversion directly with matrices //printOglTransform("_geo2ArTransformNode", _geo2ArTransformNode); //printOglTransform("_ar2GeoTransformNode", _ar2GeoTransformNode);