/// <summary> /// Synchronize the viewport between HAPI and Unity. /// </summary> void UpdateViewport(HEU_SessionBase session, HEU_SessionSyncData syncData) { SceneView sceneView = SceneView.lastActiveSceneView; if (sceneView == null) { return; } // Get the latest viewport from HAPI, and check it agianst last update. HAPI_Viewport viewHAPI = new HAPI_Viewport(true); session.GetViewport(ref viewHAPI); if (!HEU_HAPIUtility.IsViewportEqual(ref viewHAPI, ref syncData._viewportHAPI)) { // HAPI has changed. Update local viewport. Transform target = sceneView.camera.transform; // Account for left-handed coordinate system Vector3 pivot = new Vector3(-viewHAPI.position[0], viewHAPI.position[1], viewHAPI.position[2]); Quaternion rotation = new Quaternion(viewHAPI.rotationQuaternion[0], viewHAPI.rotationQuaternion[1], viewHAPI.rotationQuaternion[2], viewHAPI.rotationQuaternion[3]); Vector3 euler = rotation.eulerAngles; euler.y = -euler.y; euler.z = -euler.z; // Flip the camera direction for Unity camera rotation = Quaternion.Euler(euler) * Quaternion.Euler(0, 180f, 0); // TODO: use viewHAPI.offset to set camera distance // Unfortuantely no direct API to set the camera distance in Unity sceneView.LookAtDirect(pivot, rotation); sceneView.Repaint(); // Store HAPI viewport for comparison on next update syncData._viewportHAPI = viewHAPI; syncData._viewportLocal = viewHAPI; syncData._viewportJustUpdated = true; } else { // HAPI hasn't changed, so let's see if local viewport has Vector3 pivot = sceneView.pivot; Quaternion rotation = sceneView.rotation; float localDistance = sceneView.cameraDistance; // Generate the local HAPI_Viewport HAPI_Viewport viewLocal = new HAPI_Viewport(true); // Account for left-handed coordinate system viewLocal.position[0] = -pivot.x; viewLocal.position[1] = pivot.y; viewLocal.position[2] = pivot.z; // Flip the camera direction for Unity camera rotation = rotation * Quaternion.Euler(0, 180f, 0); Vector3 euler = rotation.eulerAngles; euler.y = -euler.y; euler.z = -euler.z; rotation = Quaternion.Euler(euler); viewLocal.rotationQuaternion[0] = rotation.x; viewLocal.rotationQuaternion[1] = rotation.y; viewLocal.rotationQuaternion[2] = rotation.z; viewLocal.rotationQuaternion[3] = rotation.w; viewLocal.offset = syncData._viewportHAPI.offset; if (!HEU_HAPIUtility.IsViewportEqual(ref viewLocal, ref syncData._viewportLocal)) { // Always store local viewport for comparison on next update syncData._viewportLocal = viewLocal; if (syncData._viewportJustUpdated) { // Unity's SceneView internally updates the // viewport after setting it, so this makes sure // to update and store the latest change locally, // and skip sending it to HAPI syncData._viewportJustUpdated = false; } else { session.SetViewport(ref viewLocal); // Store HAPI viewport for comparison on next update syncData._viewportHAPI = viewLocal; } //Debug.Log("Setting HAPI (from local)"); //Debug.LogFormat("Pos: {0}, {1}, {2}", viewLocal.position[0], viewLocal.position[1], viewLocal.position[2]); //Debug.LogFormat("Rot: {0}, {1}, {2}, {3}", viewLocal.rotationQuaternion[0], //viewLocal.rotationQuaternion[1], viewLocal.rotationQuaternion[2], viewLocal.rotationQuaternion[3]); //Debug.LogFormat("Dis: {0}, sceneView.camDist: {1}", viewLocal.offset, sceneView.cameraDistance); } } }