52 float d0 = ( ( pFitX[0]-pFitX[1] ) * ( pFitX[0]-pFitX[2] ) * ( pFitX[0]-pFitX[3] ) );
53 float d1 = ( ( pFitX[1]-pFitX[2] ) * ( pFitX[1]-pFitX[3] ) * ( pFitX[1]-pFitX[0] ) );
54 float d2 = ( ( pFitX[2]-pFitX[3] ) * ( pFitX[2]-pFitX[0] ) * ( pFitX[2]-pFitX[1] ) );
55 float d3 = ( ( pFitX[3]-pFitX[0] ) * ( pFitX[3]-pFitX[1] ) * ( pFitX[3]-pFitX[2] ) );
57 if ( ( d0 == 0.0f ) || ( d1 == 0.0f ) || ( d2 == 0.0f ) || ( d3 == 0.0f ) )
62 float f0 = pFitY[0] / d0;
63 float f1 = pFitY[1] / d1;
64 float f2 = pFitY[2] / d2;
65 float f3 = pFitY[3] / d3;
67 pResult[0] = -( f0*pFitX[1]*pFitX[2]*pFitX[3]
68 + f1*pFitX[0]*pFitX[2]*pFitX[3]
69 + f2*pFitX[0]*pFitX[1]*pFitX[3]
70 + f3*pFitX[0]*pFitX[1]*pFitX[2] );
71 pResult[1] = f0*(pFitX[1]*pFitX[2] + pFitX[2]*pFitX[3] + pFitX[3]*pFitX[1])
72 + f1*(pFitX[0]*pFitX[2] + pFitX[2]*pFitX[3] + pFitX[3]*pFitX[0])
73 + f2*(pFitX[0]*pFitX[1] + pFitX[1]*pFitX[3] + pFitX[3]*pFitX[0])
74 + f3*(pFitX[0]*pFitX[1] + pFitX[1]*pFitX[2] + pFitX[2]*pFitX[0]);
75 pResult[2] = -( f0*(pFitX[1]+pFitX[2]+pFitX[3])
76 + f1*(pFitX[0]+pFitX[2]+pFitX[3])
77 + f2*(pFitX[0]+pFitX[1]+pFitX[3])
78 + f3*(pFitX[0]+pFitX[1]+pFitX[2]) );
79 pResult[3] = f0 + f1 + f2 + f3;
90 float scaledValFloor = floorf ( scaledVal );
91 scaledValFloor =
Alg::Max ( 0.0f,
Alg::Min ( (
float)(NumSegments-1), scaledValFloor ) );
92 float t = scaledVal - scaledValFloor;
93 int k = (int)scaledValFloor;
102 m0 = ( K[1] - K[0] );
104 m1 = 0.5f * ( K[2] - K[0] );
109 m0 = 0.5f * ( K[k+1] - K[k-1] );
111 m1 = 0.5f * ( K[k+2] - K[k ] );
115 p0 = K[NumSegments-2];
116 m0 = 0.5f * ( K[NumSegments-1] - K[NumSegments-2] );
117 p1 = K[NumSegments-1];
118 m1 = K[NumSegments-1] - K[NumSegments-2];
122 p0 = K[NumSegments-1];
123 m0 = K[NumSegments-1] - K[NumSegments-2];
129 float omt = 1.0f - t;
130 float res = ( p0 * ( 1.0f + 2.0f * t ) + m0 * t ) * omt * omt
131 + ( p1 * ( 1.0f + 2.0f * omt ) - m1 * omt ) * t * t;
173 scale = ( K[0] + rsq * ( K[1] + rsq * ( K[2] + rsq * K[3] ) ) );
176 scale = 1.0f / ( K[0] + rsq * ( K[1] + rsq * ( K[2] + rsq * K[3] ) ) );
183 OVR_ASSERT ( NumSegments <= NumCoefficients );
184 float scaledRsq = (float)(NumSegments-1) * rsq / ( MaxR * MaxR );
205 float scale = DistortionFnScaleRadiusSquared ( rsq );
207 scaleRGB.
x = scale * ( 1.0f + ChromaticAberration[0] + rsq * ChromaticAberration[1] );
209 scaleRGB.
z = scale * ( 1.0f + ChromaticAberration[2] + rsq * ChromaticAberration[3] );
219 float delta = r * 0.25f;
224 d = fabs(r - DistortionFn(s));
226 for (
int i = 0; i < 20; i++)
228 float sUp = s + delta;
229 float sDown = s - delta;
230 float dUp = fabs(r - DistortionFn(sUp));
231 float dDown = fabs(r - DistortionFn(sDown));
265 scale = 1.0f / ( InvK[0] + rsq * ( InvK[1] + rsq * ( InvK[2] + rsq * InvK[3] ) ) );
272 OVR_ASSERT ( NumSegments <= NumCoefficients );
273 float scaledRsq = (float)(NumSegments-1) * rsq / ( MaxInvR * MaxInvR );
292 float maxR = MaxInvR;
309 sampleR[1] = maxR * 0.4f;
310 sampleR[2] = maxR * 0.8f;
311 sampleR[3] = maxR * 1.5f;
312 for (
int i = 0; i < 4; i++ )
314 sampleRSq[i] = sampleR[i] * sampleR[i];
315 sampleInv[i] = DistortionFnInverse ( sampleR[i] );
316 sampleFit[i] = sampleR[i] / sampleInv[i];
323 OVR_ASSERT ( fabs ( DistortionFnInverse ( sampleR[0] ) - DistortionFnInverseApprox ( sampleR[0] ) ) / maxR < 0.0001f );
324 OVR_ASSERT ( fabs ( DistortionFnInverse ( sampleR[1] ) - DistortionFnInverseApprox ( sampleR[1] ) ) / maxR < 0.0001f );
325 OVR_ASSERT ( fabs ( DistortionFnInverse ( sampleR[2] ) - DistortionFnInverseApprox ( sampleR[2] ) ) / maxR < 0.0001f );
326 OVR_ASSERT ( fabs ( DistortionFnInverse ( sampleR[3] ) - DistortionFnInverseApprox ( sampleR[3] ) ) / maxR < 0.0001f );
328 const int maxCheck = 20;
329 for (
int i = 0; i < maxCheck; i++ )
331 float checkR = (float)i * maxR / (
float)maxCheck;
332 float realInv = DistortionFnInverse ( checkR );
333 float testInv = DistortionFnInverseApprox ( checkR );
334 float error = fabsf ( realInv - testInv ) / maxR;
343 OVR_ASSERT ( NumSegments <= NumCoefficients );
344 for (
int i = 1; i < NumSegments; i++ )
346 float scaledRsq = (float)i;
347 float rsq = scaledRsq * MaxInvR * MaxInvR / (float)( NumSegments - 1);
348 float r = sqrtf ( rsq );
349 float inv = DistortionFnInverse ( r );
355 const int maxCheck = 20;
356 for (
int i = 0; i <= maxCheck; i++ )
358 float checkR = (float)i * MaxInvR / (
float)maxCheck;
359 float realInv = DistortionFnInverse ( checkR );
360 float testInv = DistortionFnInverseApprox ( checkR );
361 float error = fabsf ( realInv - testInv ) / MaxR;
376 for (
int i = 0; i < NumCoefficients; i++ )
386 ChromaticAberration[0] = 0.0f;
387 ChromaticAberration[1] = 0.0f;
388 ChromaticAberration[2] = 0.0f;
389 ChromaticAberration[3] = 0.0f;
390 MetersPerTanAngleAtCenter = 0.05f;
415 OVR_ASSERT ( ( fractionalBits >= 0 ) && ( fractionalBits < 31 ) );
416 float valWhole = val * (float)( 1 << fractionalBits );
417 valWhole += (float)zeroVal + 0.5f;
418 valWhole = floorf ( valWhole );
419 OVR_ASSERT ( ( valWhole >= 0.0f ) && ( valWhole < (
float)( 1 << 16 ) ) );
425 OVR_ASSERT ( ( fractionalBits >= 0 ) && ( fractionalBits < 31 ) );
426 float valFloat = (float)val;
427 valFloat -= (float)zeroVal;
428 valFloat *= 1.0f / (float)( 1 << fractionalBits );
436 if ( bufferSizeInBytes < 2 )
452 for (
int i = 0; i < 11; i++ )
458 for (
int i = 0; i < 4; i++ )
467 for (
int i = 0; i < 11; i++ )
478 for (
int i = 0; i < 4; i++ )
517 for (
int i = 0; i < 11; i++ )
528 for (
int i = 0; i < 4; i++ )
537 for (
int i = 0; i < 11; i++ )
543 for (
int i = 0; i < 4; i++ )
552 #ifdef OVR_BUILD_DEBUG
553 void TestSaveLoadLensConfig ( LensConfig
const &config )
557 const int bufferSize = 256;
558 UByte buffer[bufferSize];
563 LensConfig testConfig;
567 for (
int i = 0; i < 11; i++ )
569 OVR_ASSERT ( fabs ( testConfig.K[i] - config.K[i] ) < 0.0001f );
571 OVR_ASSERT ( fabsf ( testConfig.MaxR - config.MaxR ) < 0.0001f );
572 OVR_ASSERT ( fabsf ( testConfig.MetersPerTanAngleAtCenter - config.MetersPerTanAngleAtCenter ) < 0.00001f );
573 for (
int i = 0; i < 4; i++ )
575 OVR_ASSERT ( fabsf ( testConfig.ChromaticAberration[i] - config.ChromaticAberration[i] ) < 0.00001f );
595 LogText(
"Debug HMDInfo - HmdType not supported. Defaulting to DK1.\n");
688 #if 0 // Device settings are out of date - don't use them.
689 if (Contents & Contents_Distortion)
691 memcpy(renderInfo.DistortionK, DistortionK,
sizeof(
float)*4);
723 if ( profile !=
NULL )
762 renderInfo.
EyeCups = eyeCupOverride;
794 if ( profile !=
NULL )
847 for (
int eyeNum = 0; eyeNum < 2; eyeNum++ )
862 struct DistortionDescriptor
868 float SampleRadius[3];
876 DistortionDescriptor distortions[10];
877 for (
unsigned int i = 0; i <
sizeof(distortions)/
sizeof(distortions[0]); i++ )
879 distortions[i].Config.SetToIdentity();
880 distortions[i].EyeRelief = 0.0f;
881 distortions[i].MaxRadius = 1.0f;
883 int numDistortions = 0;
884 int defaultDistortion = 0;
895 distortions[numDistortions].EyeRelief = 0.012760465f - 0.005f;
896 distortions[numDistortions].Config.MetersPerTanAngleAtCenter = 0.0425f;
897 distortions[numDistortions].Config.K[0] = 1.0000f;
898 distortions[numDistortions].Config.K[1] = 1.06505f;
899 distortions[numDistortions].Config.K[2] = 1.14725f;
900 distortions[numDistortions].Config.K[3] = 1.2705f;
901 distortions[numDistortions].Config.K[4] = 1.48f;
902 distortions[numDistortions].Config.K[5] = 1.87f;
903 distortions[numDistortions].Config.K[6] = 2.534f;
904 distortions[numDistortions].Config.K[7] = 3.6f;
905 distortions[numDistortions].Config.K[8] = 5.1f;
906 distortions[numDistortions].Config.K[9] = 7.4f;
907 distortions[numDistortions].Config.K[10] = 11.0f;
908 distortions[numDistortions].SampleRadius[0] = 0.222717149f;
909 distortions[numDistortions].SampleRadius[1] = 0.512249443f;
910 distortions[numDistortions].SampleRadius[2] = 0.712694878f;
911 distortions[numDistortions].MaxRadius = sqrt(1.8f);
912 defaultDistortion = numDistortions;
917 distortions[numDistortions].EyeRelief = 0.012760465f;
918 distortions[numDistortions].Config.MetersPerTanAngleAtCenter = 0.0425f;
919 distortions[numDistortions].Config.K[0] = 1.0f;
920 distortions[numDistortions].Config.K[1] = 1.032407264f;
921 distortions[numDistortions].Config.K[2] = 1.07160462f;
922 distortions[numDistortions].Config.K[3] = 1.11998388f;
923 distortions[numDistortions].Config.K[4] = 1.1808606f;
924 distortions[numDistortions].Config.K[5] = 1.2590494f;
925 distortions[numDistortions].Config.K[6] = 1.361915f;
926 distortions[numDistortions].Config.K[7] = 1.5014339f;
927 distortions[numDistortions].Config.K[8] = 1.6986004f;
928 distortions[numDistortions].Config.K[9] = 1.9940577f;
929 distortions[numDistortions].Config.K[10] = 2.4783147f;
930 distortions[numDistortions].SampleRadius[0] = 0.222717149f;
931 distortions[numDistortions].SampleRadius[1] = 0.512249443f;
932 distortions[numDistortions].SampleRadius[2] = 0.712694878f;
933 distortions[numDistortions].MaxRadius = 1.0f;
938 distortions[numDistortions].EyeRelief = 0.012760465f + 0.005f;
939 distortions[numDistortions].Config.MetersPerTanAngleAtCenter = 0.0425f;
940 distortions[numDistortions].Config.K[0] = 1.0102f;
941 distortions[numDistortions].Config.K[1] = 1.0371f;
942 distortions[numDistortions].Config.K[2] = 1.0831f;
943 distortions[numDistortions].Config.K[3] = 1.1353f;
944 distortions[numDistortions].Config.K[4] = 1.2f;
945 distortions[numDistortions].Config.K[5] = 1.2851f;
946 distortions[numDistortions].Config.K[6] = 1.3979f;
947 distortions[numDistortions].Config.K[7] = 1.56f;
948 distortions[numDistortions].Config.K[8] = 1.8f;
949 distortions[numDistortions].Config.K[9] = 2.25f;
950 distortions[numDistortions].Config.K[10] = 3.0f;
951 distortions[numDistortions].SampleRadius[0] = 0.222717149f;
952 distortions[numDistortions].SampleRadius[1] = 0.512249443f;
953 distortions[numDistortions].SampleRadius[2] = 0.712694878f;
954 distortions[numDistortions].MaxRadius = 1.0f;
958 for (
int i = 0; i < numDistortions; i++ )
960 distortions[i].Config.ChromaticAberration[0] = -0.006f;
961 distortions[i].Config.ChromaticAberration[1] = 0.0f;
962 distortions[i].Config.ChromaticAberration[2] = 0.014f;
963 distortions[i].Config.ChromaticAberration[3] = 0.0f;
972 distortions[numDistortions].EyeRelief = 0.010f;
973 distortions[numDistortions].Config.MetersPerTanAngleAtCenter = 0.0425f;
974 distortions[numDistortions].Config.K[0] = 1.0f;
975 distortions[numDistortions].Config.K[1] = 1.0425f;
976 distortions[numDistortions].Config.K[2] = 1.0826f;
977 distortions[numDistortions].Config.K[3] = 1.130f;
978 distortions[numDistortions].Config.K[4] = 1.185f;
979 distortions[numDistortions].Config.K[5] = 1.250f;
980 distortions[numDistortions].Config.K[6] = 1.338f;
981 distortions[numDistortions].Config.K[7] = 1.455f;
982 distortions[numDistortions].Config.K[8] = 1.620f;
983 distortions[numDistortions].Config.K[9] = 1.840f;
984 distortions[numDistortions].Config.K[10] = 2.200f;
985 distortions[numDistortions].SampleRadius[0] = 0.222717149f;
986 distortions[numDistortions].SampleRadius[1] = 0.512249443f;
987 distortions[numDistortions].SampleRadius[2] = 0.712694878f;
988 distortions[numDistortions].MaxRadius = 1.0f;
990 distortions[numDistortions].SampleRadius[0] = 0.405405405f;
991 distortions[numDistortions].SampleRadius[1] = 0.675675676f;
992 distortions[numDistortions].SampleRadius[2] = 0.945945946f;
993 defaultDistortion = numDistortions;
996 distortions[numDistortions] = distortions[0];
997 distortions[numDistortions].EyeRelief = 0.020f;
1001 for (
int i = 0; i < numDistortions; i++ )
1003 distortions[i].Config.ChromaticAberration[0] = -0.006f;
1004 distortions[i].Config.ChromaticAberration[1] = 0.0f;
1005 distortions[i].Config.ChromaticAberration[2] = 0.014f;
1006 distortions[i].Config.ChromaticAberration[3] = 0.0f;
1014 distortions[numDistortions].EyeRelief = 0.010f;
1015 distortions[numDistortions].Config.MetersPerTanAngleAtCenter = 0.036f;
1018 distortions[numDistortions].Config.K[0] = 1.003f;
1019 distortions[numDistortions].Config.K[1] = 1.02f;
1020 distortions[numDistortions].Config.K[2] = 1.042f;
1021 distortions[numDistortions].Config.K[3] = 1.066f;
1022 distortions[numDistortions].Config.K[4] = 1.094f;
1023 distortions[numDistortions].Config.K[5] = 1.126f;
1024 distortions[numDistortions].Config.K[6] = 1.162f;
1025 distortions[numDistortions].Config.K[7] = 1.203f;
1026 distortions[numDistortions].Config.K[8] = 1.25f;
1027 distortions[numDistortions].Config.K[9] = 1.31f;
1028 distortions[numDistortions].Config.K[10] = 1.38f;
1029 distortions[numDistortions].MaxRadius = 1.0f;
1032 distortions[numDistortions].SampleRadius[0] = 0.405405405f;
1033 distortions[numDistortions].SampleRadius[1] = 0.675675676f;
1034 distortions[numDistortions].SampleRadius[2] = 0.945945946f;
1035 defaultDistortion = numDistortions;
1038 distortions[numDistortions] = distortions[0];
1039 distortions[numDistortions].EyeRelief = 0.020f;
1043 for (
int i = 0; i < numDistortions; i++ )
1045 distortions[i].Config.ChromaticAberration[0] = -0.015f;
1046 distortions[i].Config.ChromaticAberration[1] = -0.02f;
1047 distortions[i].Config.ChromaticAberration[2] = 0.025f;
1048 distortions[i].Config.ChromaticAberration[3] = 0.02f;
1055 distortions[0].EyeRelief = 0.005f;
1056 distortions[0].Config.MetersPerTanAngleAtCenter = 0.043875f;
1058 distortions[0].Config.K[0] = 1.0f;
1059 distortions[0].Config.K[1] = -0.3999f;
1060 distortions[0].Config.K[2] = 0.2408f;
1061 distortions[0].Config.K[3] = -0.4589f;
1062 distortions[0].SampleRadius[0] = 0.2f;
1063 distortions[0].SampleRadius[1] = 0.4f;
1064 distortions[0].SampleRadius[2] = 0.6f;
1066 distortions[1] = distortions[0];
1067 distortions[1].EyeRelief = 0.010f;
1071 for (
int i = 0; i < numDistortions; i++ )
1074 distortions[i].Config.ChromaticAberration[0] = 0.0f;
1075 distortions[i].Config.ChromaticAberration[1] = 0.0f;
1076 distortions[i].Config.ChromaticAberration[2] = 0.0f;
1077 distortions[i].Config.ChromaticAberration[3] = 0.0f;
1081 OVR_ASSERT ( numDistortions < (
sizeof(distortions)/
sizeof(distortions[0])) );
1084 DistortionDescriptor *pUpper =
NULL;
1085 DistortionDescriptor *pLower =
NULL;
1086 float lerpVal = 0.0f;
1087 if (eyeReliefInMeters == 0)
1089 pLower = &(distortions[defaultDistortion]);
1090 pUpper = &(distortions[defaultDistortion]);
1095 for (
int i = 0; i < numDistortions-1; i++ )
1097 OVR_ASSERT ( distortions[i].EyeRelief < distortions[i+1].EyeRelief );
1098 if ( ( distortions[i].EyeRelief <= eyeReliefInMeters ) && ( distortions[i+1].EyeRelief > eyeReliefInMeters ) )
1100 pLower = &(distortions[i]);
1101 pUpper = &(distortions[i+1]);
1102 lerpVal = ( eyeReliefInMeters - pLower->EyeRelief ) / ( pUpper->EyeRelief - pLower->EyeRelief );
1108 if ( pUpper ==
NULL )
1112 if ( distortions[0].EyeRelief > eyeReliefInMeters )
1114 pLower = &(distortions[0]);
1115 pUpper = &(distortions[1]);
1119 OVR_ASSERT ( distortions[numDistortions-1].EyeRelief <= eyeReliefInMeters );
1120 pLower = &(distortions[numDistortions-2]);
1121 pUpper = &(distortions[numDistortions-1]);
1123 lerpVal = ( eyeReliefInMeters - pLower->EyeRelief ) / ( pUpper->EyeRelief - pLower->EyeRelief );
1126 if ( distortions[0].EyeRelief > eyeReliefInMeters )
1128 pLower = &(distortions[0]);
1129 pUpper = &(distortions[0]);
1133 OVR_ASSERT ( distortions[numDistortions-1].EyeRelief <= eyeReliefInMeters );
1134 pLower = &(distortions[numDistortions-1]);
1135 pUpper = &(distortions[numDistortions-1]);
1140 float invLerpVal = 1.0f - lerpVal;
1142 pLower->Config.MaxR = pLower->MaxRadius;
1143 pUpper->Config.MaxR = pUpper->MaxRadius;
1147 float maxValidRadius = invLerpVal * pLower->MaxRadius + lerpVal * pUpper->MaxRadius;
1148 result.
MaxR = maxValidRadius;
1150 switch ( distortionType )
1162 for (
int ctrlPt = 1; ctrlPt < 4; ctrlPt ++ )
1164 float radiusLerp = invLerpVal * pLower->SampleRadius[ctrlPt-1] + lerpVal * pUpper->SampleRadius[ctrlPt-1];
1165 float radiusLerpSq = radiusLerp * radiusLerp;
1166 float fitYLower = pLower->Config.DistortionFnScaleRadiusSquared ( radiusLerpSq );
1167 float fitYUpper = pUpper->Config.DistortionFnScaleRadiusSquared ( radiusLerpSq );
1168 fitX[ctrlPt] = radiusLerpSq;
1169 fitY[ctrlPt] = 1.0f / ( invLerpVal * fitYLower + lerpVal * fitYUpper );
1178 float maxRDist = result.
DistortionFn ( maxValidRadius );
1188 result.
MaxR = maxValidRadius;
1190 result.
K[0] = invLerpVal * pLower->Config.K[0] + lerpVal * pUpper->Config.K[0];
1193 for (
int ctrlPt = 1; ctrlPt < NumSegments; ctrlPt++ )
1195 float radiusSq = ( (float)ctrlPt / (
float)(NumSegments-1) ) * maxValidRadius * maxValidRadius;
1196 float fitYLower = pLower->Config.DistortionFnScaleRadiusSquared ( radiusSq );
1197 float fitYUpper = pUpper->Config.DistortionFnScaleRadiusSquared ( radiusSq );
1198 float fitLerp = invLerpVal * fitYLower + lerpVal * fitYUpper;
1199 result.
K[ctrlPt] = fitLerp;
1204 for (
int ctrlPt = 1; ctrlPt < NumSegments; ctrlPt++ )
1206 float radiusSq = ( (float)ctrlPt / (
float)(NumSegments-1) ) * maxValidRadius * maxValidRadius;
1213 float maxRDist = result.
DistortionFn ( maxValidRadius );
1224 result.
ChromaticAberration[0] = invLerpVal * pLower->Config.ChromaticAberration[0] + lerpVal * pUpper->Config.ChromaticAberration[0];
1225 result.
ChromaticAberration[1] = invLerpVal * pLower->Config.ChromaticAberration[1] + lerpVal * pUpper->Config.ChromaticAberration[1];
1226 result.
ChromaticAberration[2] = invLerpVal * pLower->Config.ChromaticAberration[2] + lerpVal * pUpper->Config.ChromaticAberration[2];
1227 result.
ChromaticAberration[3] = invLerpVal * pLower->Config.ChromaticAberration[3] + lerpVal * pUpper->Config.ChromaticAberration[3];
1231 pUpper->Config.MetersPerTanAngleAtCenter * lerpVal;
1276 if ( pLensOverride !=
NULL )
1278 localDistortion.Lens = *pLensOverride;
1284 localDistortion.PixelsPerTanAngleAtCenter = (pixelsPerMeter * localDistortion.Lens.MetersPerTanAngleAtCenter).ToVector();
1288 (hmd.
ScreenSizeInMeters / localDistortion.Lens.MetersPerTanAngleAtCenter).ToVector());
1300 localDistortion.LensCenter.
x = ( centerFromLeftInMeters / visibleWidthOfOneEye ) * 2.0f - 1.0f;
1304 localDistortion.LensCenter.x = -localDistortion.LensCenter.x;
1307 return localDistortion;
1311 float offsetToRightInMeters,
1312 float offsetDownwardsInMeters,
1313 float lensDiameterInMeters,
1314 float extraEyeRotationInRadians )
1328 float halfLensDiameter = lensDiameterInMeters * 0.5f;
1330 fovPort.
UpTan = ( halfLensDiameter + offsetDownwardsInMeters ) / eyeReliefInMeters;
1331 fovPort.
DownTan = ( halfLensDiameter - offsetDownwardsInMeters ) / eyeReliefInMeters;
1332 fovPort.
LeftTan = ( halfLensDiameter + offsetToRightInMeters ) / eyeReliefInMeters;
1333 fovPort.
RightTan = ( halfLensDiameter - offsetToRightInMeters ) / eyeReliefInMeters;
1335 if ( extraEyeRotationInRadians > 0.0f )
1348 const float eyeballCenterToPupil = 0.0135f;
1349 const float eyeballLateralPull = 0.001f * (extraEyeRotationInRadians /
DegreeToRad ( 30.0f));
1350 float extraTranslation = eyeballCenterToPupil * sinf ( extraEyeRotationInRadians ) + eyeballLateralPull;
1351 float extraRelief = eyeballCenterToPupil * ( 1.0f - cosf ( extraEyeRotationInRadians ) );
1353 fovPort.
UpTan =
Alg::Max ( fovPort.
UpTan , ( halfLensDiameter + offsetDownwardsInMeters + extraTranslation ) / ( eyeReliefInMeters + extraRelief ) );
1354 fovPort.
DownTan =
Alg::Max ( fovPort.
DownTan , ( halfLensDiameter - offsetDownwardsInMeters + extraTranslation ) / ( eyeReliefInMeters + extraRelief ) );
1355 fovPort.
LeftTan =
Alg::Max ( fovPort.
LeftTan , ( halfLensDiameter + offsetToRightInMeters + extraTranslation ) / ( eyeReliefInMeters + extraRelief ) );
1356 fovPort.
RightTan =
Alg::Max ( fovPort.
RightTan, ( halfLensDiameter - offsetToRightInMeters + extraTranslation ) / ( eyeReliefInMeters + extraRelief ) );
1367 float extraEyeRotationInRadians )
1370 float eyeReliefInMeters;
1371 float offsetToRightInMeters;
1386 eyeReliefInMeters =
Alg::Max(eyeReliefInMeters, 0.006f);
1390 offsetToRightInMeters,
1393 extraEyeRotationInRadians );
1420 struct FunctionHider
1426 result.
UpTan = 0.0f;
1431 float stepScale = 1.0f / ( numSteps - 1 );
1432 for (
int step = 0; step < numSteps; step++ )
1434 float lerpFactor = stepScale * (float)step;
1435 Vector2f sample = from + (to - from) * lerpFactor;
1447 FovPort leftFovPort = FunctionHider::FindRange( dmiddle,
Vector2f( -1.0f, dmiddle.
y ), 10, distortion );
1448 FovPort rightFovPort = FunctionHider::FindRange( dmiddle,
Vector2f( 1.0f, dmiddle.
y ), 10, distortion );
1449 FovPort upFovPort = FunctionHider::FindRange( dmiddle,
Vector2f( dmiddle.
x, -1.0f ), 10, distortion );
1450 FovPort downFovPort = FunctionHider::FindRange( dmiddle,
Vector2f( dmiddle.
x, 1.0f ), 10, distortion );
1457 return resultFovPort;
1470 return resultFovPort;
1474 FovPort tanHalfFov,
float pixelsPerDisplayPixel )
1502 float projXScale = 2.0f / ( tanHalfFov.
LeftTan + tanHalfFov.
RightTan );
1503 float projXOffset = ( tanHalfFov.
LeftTan - tanHalfFov.
RightTan ) * projXScale * 0.5f;
1504 float projYScale = 2.0f / ( tanHalfFov.
UpTan + tanHalfFov.
DownTan );
1505 float projYOffset = ( tanHalfFov.
UpTan - tanHalfFov.
DownTan ) * projYScale * 0.5f;
1519 Recti renderedViewport,
1520 Sizei renderTargetSize )
1527 result.
Scale = scaleAndOffsetNDC.
Scale * 0.5f;
1531 Vector2f scale( (
float)renderedViewport.
w / (
float)renderTargetSize.
w,
1532 (
float)renderedViewport.
h / (
float)renderTargetSize.
h );
1533 Vector2f offset( (
float)renderedViewport.
x / (
float)renderTargetSize.
w,
1534 (
float)renderedViewport.
y / (
float)renderTargetSize.
h );
1544 float zNear ,
float zFar )
1549 float handednessScale = 1.0f;
1552 handednessScale = -1.0f;
1557 projection.
M[0][0] = scaleAndOffset.
Scale.
x;
1558 projection.
M[0][1] = 0.0f;
1559 projection.
M[0][2] = handednessScale * scaleAndOffset.
Offset.
x;
1560 projection.
M[0][3] = 0.0f;
1566 projection.
M[1][0] = 0.0f;
1567 projection.
M[1][1] = scaleAndOffset.
Scale.
y;
1568 projection.
M[1][2] = handednessScale * -scaleAndOffset.
Offset.
y;
1569 projection.
M[1][3] = 0.0f;
1573 projection.
M[2][0] = 0.0f;
1574 projection.
M[2][1] = 0.0f;
1575 projection.
M[2][2] = -handednessScale * zFar / (zNear - zFar);
1576 projection.
M[2][3] = (zFar * zNear) / (zNear - zFar);
1579 projection.
M[3][0] = 0.0f;
1580 projection.
M[3][1] = 0.0f;
1581 projection.
M[3][2] = handednessScale;
1582 projection.
M[3][3] = 0.0f;
1589 float tanHalfFovX,
float tanHalfFovY,
1590 float unitsX,
float unitsY,
1591 float distanceFromCamera,
float interpupillaryDistance,
1593 float zNear ,
float zFar )
1597 float orthoHorizontalOffset = interpupillaryDistance * 0.5f / distanceFromCamera;
1601 orthoHorizontalOffset = 0.0f;
1606 orthoHorizontalOffset = -orthoHorizontalOffset;
1630 float orthoScaleX = 2.0f * tanHalfFovX / unitsX;
1631 float orthoScaleY = 2.0f * tanHalfFovY / unitsY;
1633 ortho.
M[0][0] = projection.
M[0][0] * orthoScaleX;
1634 ortho.
M[0][1] = 0.0f;
1635 ortho.
M[0][2] = 0.0f;
1636 ortho.
M[0][3] = -projection.
M[0][2] + ( orthoHorizontalOffset * projection.
M[0][0] );
1638 ortho.
M[1][0] = 0.0f;
1639 ortho.
M[1][1] = -projection.
M[1][1] * orthoScaleY;
1640 ortho.
M[1][2] = 0.0f;
1641 ortho.
M[1][3] = -projection.
M[1][2];
1643 if ( fabsf ( zNear - zFar ) < 0.001f )
1645 ortho.
M[2][0] = 0.0f;
1646 ortho.
M[2][1] = 0.0f;
1647 ortho.
M[2][2] = 0.0f;
1648 ortho.
M[2][3] = zFar;
1652 ortho.
M[2][0] = 0.0f;
1653 ortho.
M[2][1] = 0.0f;
1654 ortho.
M[2][2] = zFar / (zNear - zFar);
1655 ortho.
M[2][3] = (zFar * zNear) / (zNear - zFar);
1659 ortho.
M[3][0] = 0.0f;
1660 ortho.
M[3][1] = 0.0f;
1661 ortho.
M[3][2] = 0.0f;
1662 ortho.
M[3][3] = 1.0f;
1680 float radiusSquared = ( tanEyeAngleDistorted.
x * tanEyeAngleDistorted.
x )
1681 + ( tanEyeAngleDistorted.
y * tanEyeAngleDistorted.
y );
1684 tanEyeAngle.
x = tanEyeAngleDistorted.
x * distortionScale;
1685 tanEyeAngle.
y = tanEyeAngleDistorted.
y * distortionScale;
1700 float radiusSquared = ( tanEyeAngleDistorted.
x * tanEyeAngleDistorted.
x )
1701 + ( tanEyeAngleDistorted.
y * tanEyeAngleDistorted.
y );
1703 *resultR = tanEyeAngleDistorted * distortionScales.
x;
1704 *resultG = tanEyeAngleDistorted * distortionScales.
y;
1705 *resultB = tanEyeAngleDistorted * distortionScales.
z;
1732 framebufferNDC.
x = -1.0f + 2.0f * ( ( pixel.
x - (float)distortionViewport.
x ) / (float)distortionViewport.
w );
1733 framebufferNDC.
y = -1.0f + 2.0f * ( ( pixel.
y - (float)distortionViewport.
y ) / (float)distortionViewport.
h );
1734 return framebufferNDC;
1767 const Vector2f &tanEyeAngle,
bool usePolyApprox )
1769 float tanEyeAngleRadius = tanEyeAngle.
Length();
1771 if ( !usePolyApprox )
1775 Vector2f tanEyeAngleDistorted = tanEyeAngle;
1776 if ( tanEyeAngleRadius > 0.0f )
1778 tanEyeAngleDistorted = tanEyeAngle * ( tanEyeAngleDistortedRadius / tanEyeAngleRadius );
1785 return framebufferNDC;
float(* CustomDistortionInv)(float)
struct OVR::HmdRenderInfo::ShutterInfo Shutter
#define OVR_KEY_EYE_RELIEF_DIAL
void LogText(const char *fmt,...) OVR_LOG_VAARG_ATTRIBUTE(1
float DistortionFnInverse(float r) const
Vector2f TransformScreenPixelToScreenNDC(Recti const &distortionViewport, Vector2f const &pixel)
const char * GetValue(const char *key)
float CenterFromTopInMeters
Size< float > ScreenSizeInMeters
float GetFloatValue(const char *key, float default_val) const
Vector2f TransformTanFovSpaceToScreenNDC(DistortionRenderDesc const &distortion, const Vector2f &tanEyeAngle, bool usePolyApprox)
Recti GetFramebufferViewport(StereoEye eyeType, HmdRenderInfo const &hmd)
float ExtEvalCatmullRom10Spline(float const *K, float scaledVal)
Vector2f TransformScreenPixelToTanFovSpace(Recti const &distortionViewport, DistortionRenderDesc const &distortion, Vector2f const &pixel)
OVR_FORCE_INLINE const T Max(const T a, const T b)
struct OVR::HmdRenderInfo::EyeConfig EyeLeft
__BEGIN_NAMESPACE_STD void * memcpy(void *__restrict __dest, const void *__restrict __src, size_t __n) __THROW __nonnull((1
float VsyncToFirstScanline
void EncodeUInt16(UByte *buffer, UInt16 val)
ScaleAndOffset2D CreateUVScaleAndOffsetfromNDCScaleandOffset(ScaleAndOffset2D scaleAndOffsetNDC, Recti renderedViewport, Sizei renderTargetSize)
float LensSeparationInMeters
UInt16 MetersPerTanAngleAtCenter
struct OVR::HmdRenderInfo::EyeConfig EyeRight
int GetIntValue(const char *key, int default_val) const
float DistortionFn(float r) const
#define OVR_KEY_CUSTOM_EYE_RENDER
Vector2f TanEyeAngleScale
FovPort CalculateFovFromHmdInfo(StereoEye eyeType, DistortionRenderDesc const &distortion, HmdRenderInfo const &hmd, float extraEyeRotationInRadians)
Vector3f DistortionFnScaleRadiusSquaredChroma(float rsq) const
UInt16 DecodeUInt16(const UByte *buffer)
float(* CustomDistortion)(float)
void TransformScreenNDCToTanFovSpaceChroma(Vector2f *resultR, Vector2f *resultG, Vector2f *resultB, DistortionRenderDesc const &distortion, const Vector2f &framebufferNDC)
FovPort CalculateFovFromEyePosition(float eyeReliefInMeters, float offsetToRightInMeters, float offsetDownwardsInMeters, float lensDiameterInMeters, float extraEyeRotationInRadians)
Sizei CalculateIdealPixelSize(StereoEye eyeType, DistortionRenderDesc const &distortion, FovPort tanHalfFov, float pixelsPerDisplayPixel)
float MetersPerTanAngleAtCenter
Vector2< float > Vector2f
float DistortionFnInverseApprox(float r) const
float DistortionFnScaleRadiusSquared(float rsq) const
float ScreenGapSizeInMeters
UInt16 ChromaticAberration[4]
float ScreenGapSizeInMeters
float LensSeparationInMeters
FovPort ClampToPhysicalScreenFov(StereoEye eyeType, DistortionRenderDesc const &distortion, FovPort inputFovPort)
LensConfig GenerateLensConfigFromEyeRelief(float eyeReliefInMeters, HmdRenderInfo const &hmd, DistortionEqnType distortionType)
DistortionRenderDesc CalculateDistortionRenderDesc(StereoEye eyeType, HmdRenderInfo const &hmd, const LensConfig *pLensOverride)
FovPort GetPhysicalScreenFov(StereoEye eyeType, DistortionRenderDesc const &distortion)
Vector2f TransformTanFovSpaceToRendertargetNDC(StereoEyeParams const &eyeParams, Vector2f const &tanEyeAngle)
Size< int > ResolutionInPixels
bool SaveLensConfig(UByte *pbuffer, int bufferSizeInBytes, LensConfig const &config)
int SaveLensConfigSizeInBytes(LensConfig const &config)
Vector2 EntrywiseMultiply(const Vector2 &b) const
Matrix4f CreateProjection(bool rightHanded, FovPort tanHalfFov, float zNear, float zFar)
ScaleAndOffset2D EyeToSourceUV
void SetEyeCup(HmdRenderInfo *renderInfo, const char *cup)
int GetFloatValues(const char *key, float *values, int num_vals) const
HMDInfo CreateDebugHMDInfo(HmdTypeEnum hmdType)
bool GetBoolValue(const char *key, bool default_val) const
float LensDiameterInMeters
int OVR_CDECL OVR_strcmp(const char *dest, const char *src)
void SetUpInverseApprox()
Vector2f TransformTanFovSpaceToRendertargetTexUV(StereoEyeParams const &eyeParams, Vector2f const &tanEyeAngle)
bool FitCubicPolynomial(float *pResult, const float *pFitX, const float *pFitY)
float VsyncToFirstScanline
ScaleAndOffset2D CreateNDCScaleAndOffsetFromFov(FovPort tanHalfFov)
bool LoadLensConfig(LensConfig *presult, UByte const *pbuffer, int bufferSizeInBytes)
UInt16 EncodeFixedPointUInt16(float val, UInt16 zeroVal, int fractionalBits)
float LensSurfaceToMidplateInMeters
OVR_FORCE_INLINE const T Min(const T a, const T b)
Matrix4f CreateOrthoSubProjection(bool rightHanded, StereoEye eyeType, float tanHalfFovX, float tanHalfFovY, float unitsX, float unitsY, float distanceFromCamera, float interpupillaryDistance, Matrix4f const &projection, float zNear, float zFar)
struct OVR::HMDInfo::ShutterInfo Shutter
Size< int > ResolutionInPixels
Vector2f TransformScreenNDCToTanFovSpace(DistortionRenderDesc const &distortion, const Vector2f &framebufferNDC)
float ChromaticAberration[4]
Size< float > ScreenSizeInMeters
float EvalCatmullRom10Spline(float const *K, float scaledVal)
#define OVR_KEY_MAX_EYE_TO_PLATE_DISTANCE
float NoseToPupilInMeters
float FirstScanlineToLastScanline
Vector2f PixelsPerTanAngleAtCenter
Vector2f TransformRendertargetNDCToTanFovSpace(const ScaleAndOffset2D &eyeToSourceNDC, const Vector2f &textureNDC)
Vector2f TransformScreenNDCToRendertargetTexUV(DistortionRenderDesc const &distortion, StereoEyeParams const &eyeParams, Vector2f const &pixel)
Vector2f TransformScreenPixelToRendertargetTexUV(Recti const &distortionViewport, DistortionRenderDesc const &distortion, StereoEyeParams const &eyeParams, Vector2f const &pixel)
HmdRenderInfo GenerateHmdRenderInfoFromHmdInfo(HMDInfo const &hmdInfo, Profile const *profile, DistortionEqnType distortionType, EyeCupType eyeCupOverride)
ScaleAndOffset2D EyeToSourceNDC
OVR_FORCE_INLINE const T Abs(const T v)
#define OVR_COMPILER_ASSERT(x)
float DecodeFixedPointUInt16(UInt16 val, UInt16 zeroVal, int fractionalBits)
#define OVR_KEY_EYE_TO_NOSE_DISTANCE
float FirstScanlineToLastScanline
float CenterFromTopInMeters