private static void ComputeMeshPoints(int width, int height, bool distortVertices, out Vector3[] vertices, out Vector2[] tex) { float[] lensFrustum = new float[4]; float[] noLensFrustum = new float[4]; Rect viewport; NvrProfile profile = NvrViewer.Instance.Profile; profile.GetLeftEyeVisibleTanAngles(lensFrustum); profile.GetLeftEyeNoLensTanAngles(noLensFrustum); viewport = profile.GetLeftEyeVisibleScreenRect(noLensFrustum); vertices = new Vector3[2 * width * height]; tex = new Vector2[2 * width * height]; for (int e = 0, vidx = 0; e < 2; e++) { for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++, vidx++) { float u = (float)i / (width - 1); float v = (float)j / (height - 1); float s, t; // The texture coordinates in StereoScreen to read from. if (distortVertices) { // Grid points regularly spaced in StreoScreen, and barrel distorted in the mesh. s = u; t = v; float x = Mathf.Lerp(lensFrustum[0], lensFrustum[2], u); float y = Mathf.Lerp(lensFrustum[3], lensFrustum[1], v); float d = Mathf.Sqrt(x * x + y * y); float r = profile.viewer.distortion.distortInv(d); float p = x * r / d; float q = y * r / d; u = (p - noLensFrustum[0]) / (noLensFrustum[2] - noLensFrustum[0]); v = (q - noLensFrustum[3]) / (noLensFrustum[1] - noLensFrustum[3]); } else { // Grid points regularly spaced in the mesh, and pincushion distorted in // StereoScreen. float p = Mathf.Lerp(noLensFrustum[0], noLensFrustum[2], u); float q = Mathf.Lerp(noLensFrustum[3], noLensFrustum[1], v); float r = Mathf.Sqrt(p * p + q * q); float d = profile.viewer.distortion.distort(r); float x = p * d / r; float y = q * d / r; s = Mathf.Clamp01((x - lensFrustum[0]) / (lensFrustum[2] - lensFrustum[0])); t = Mathf.Clamp01((y - lensFrustum[3]) / (lensFrustum[1] - lensFrustum[3])); } // Convert u,v to mesh screen coordinates. float aspect = profile.screen.width / profile.screen.height; u = (viewport.x + u * viewport.width - 0.5f) * aspect; v = viewport.y + v * viewport.height - 0.5f; vertices[vidx] = new Vector3(u, v, 1); // Adjust s to account for left/right split in StereoScreen. s = (s + e) / 2; tex[vidx] = new Vector2(s, t); } } float w = lensFrustum[2] - lensFrustum[0]; lensFrustum[0] = -(w + lensFrustum[0]); lensFrustum[2] = w - lensFrustum[2]; w = noLensFrustum[2] - noLensFrustum[0]; noLensFrustum[0] = -(w + noLensFrustum[0]); noLensFrustum[2] = w - noLensFrustum[2]; viewport.x = 1 - (viewport.x + viewport.width); } }
private void UpdateProfile() { if (NvrViewer.USE_DTR) { _NVR_GetNVRConfig(profileData); } if (profileData[13] > 0) { NvrGlobal.fovNear = profileData[13]; } if (profileData[14] > 0) { NvrGlobal.fovFar = profileData[14]; } if (NvrViewer.USE_DTR && !NvrGlobal.supportDtr && NvrGlobal.dftProfileParams[0] != 0) { // DFT模式加载cardboard参数 // fov profileData[0] = NvrGlobal.dftProfileParams[3]; //45; profileData[1] = NvrGlobal.dftProfileParams[4]; //45; profileData[2] = NvrGlobal.dftProfileParams[5]; //51.5f; profileData[3] = NvrGlobal.dftProfileParams[6]; //51.5f; // screen size profileData[4] = NvrGlobal.dftProfileParams[12]; //0.110f; profileData[5] = NvrGlobal.dftProfileParams[13]; //0.062f; // ipd profileData[7] = NvrGlobal.dftProfileParams[0]; //0.063f; // screen to lens profileData[9] = NvrGlobal.dftProfileParams[2]; //0.035f; // k1 k2 profileData[11] = NvrGlobal.dftProfileParams[7]; //0.252f; profileData[12] = NvrGlobal.dftProfileParams[8]; //0.019f; } NvrProfile.Viewer device = new NvrProfile.Viewer(); NvrProfile.Screen screen = new NvrProfile.Screen(); // left top right bottom device.maxFOV.outer = profileData[0]; device.maxFOV.upper = profileData[2]; device.maxFOV.inner = profileData[1]; device.maxFOV.lower = profileData[3]; screen.width = profileData[4]; screen.height = profileData[5]; screen.border = profileData[6]; device.lenses.separation = profileData[7]; device.lenses.offset = profileData[8]; device.lenses.screenDistance = profileData[9]; device.lenses.alignment = (int)profileData[10]; device.distortion.Coef = new[] { profileData[11], profileData[12] }; Profile.screen = screen; Profile.viewer = device; float[] rect = new float[4]; Profile.GetLeftEyeNoLensTanAngles(rect); float maxRadius = NvrProfile.GetMaxRadius(rect); Profile.viewer.inverse = NvrProfile.ApproximateInverse( Profile.viewer.distortion, maxRadius); }
public override void UpdateScreenData() { Profile = NvrProfile.GetKnownProfile(NvrViewer.Instance.ScreenSize, NvrViewer.Instance.ViewerType); ComputeEyesFromProfile(1, 2000); profileChanged = true; }