11 #ifndef SLOVRWORKAROUND_H
12 #define SLOVRWORKAROUND_H
96 float d0 = ((pFitX[0] - pFitX[1]) * (pFitX[0] - pFitX[2]) * (pFitX[0] - pFitX[3]));
97 float d1 = ((pFitX[1] - pFitX[2]) * (pFitX[1] - pFitX[3]) * (pFitX[1] - pFitX[0]));
98 float d2 = ((pFitX[2] - pFitX[3]) * (pFitX[2] - pFitX[0]) * (pFitX[2] - pFitX[1]));
99 float d3 = ((pFitX[3] - pFitX[0]) * (pFitX[3] - pFitX[1]) * (pFitX[3] - pFitX[2]));
101 if ((d0 == 0.0f) || (d1 == 0.0f) || (d2 == 0.0f) || (d3 == 0.0f))
106 float f0 = pFitY[0] / d0;
107 float f1 = pFitY[1] / d1;
108 float f2 = pFitY[2] / d2;
109 float f3 = pFitY[3] / d3;
111 pResult[0] = -(f0 * pFitX[1] * pFitX[2] * pFitX[3] +
112 f1 * pFitX[0] * pFitX[2] * pFitX[3] +
113 f2 * pFitX[0] * pFitX[1] * pFitX[3] +
114 f3 * pFitX[0] * pFitX[1] * pFitX[2]);
115 pResult[1] = f0 * (pFitX[1] * pFitX[2] + pFitX[2] * pFitX[3] + pFitX[3] * pFitX[1]) +
116 f1 * (pFitX[0] * pFitX[2] + pFitX[2] * pFitX[3] + pFitX[3] * pFitX[0]) +
117 f2 * (pFitX[0] * pFitX[1] + pFitX[1] * pFitX[3] + pFitX[3] * pFitX[0]) +
118 f3 * (pFitX[0] * pFitX[1] + pFitX[1] * pFitX[2] + pFitX[2] * pFitX[0]);
119 pResult[2] = -(f0 * (pFitX[1] + pFitX[2] + pFitX[3]) +
120 f1 * (pFitX[0] + pFitX[2] + pFitX[3]) +
121 f2 * (pFitX[0] + pFitX[1] + pFitX[3]) +
122 f3 * (pFitX[0] + pFitX[1] + pFitX[2]));
123 pResult[3] = f0 + f1 + f2 + f3;
133 #define TPH_SPLINE_STATISTICS 0
134 #if TPH_SPLINE_STATISTICS
135 static float max_scaledVal = 0;
136 static float average_total_out_of_range = 0;
137 static float average_out_of_range;
138 static int num_total = 0;
139 static int num_out_of_range = 0;
140 static int num_out_of_range_over_1 = 0;
141 static int num_out_of_range_over_2 = 0;
142 static int num_out_of_range_over_3 = 0;
143 static float percent_out_of_range;
151 #if TPH_SPLINE_STATISTICS
153 if (scaledVal > (NumSegments - 1))
156 average_total_out_of_range += scaledVal;
157 average_out_of_range = average_total_out_of_range / ((float)num_out_of_range);
158 percent_out_of_range = 100.0f * (num_out_of_range) / num_total;
160 if (scaledVal > (NumSegments - 1 + 1)) num_out_of_range_over_1++;
161 if (scaledVal > (NumSegments - 1 + 2)) num_out_of_range_over_2++;
162 if (scaledVal > (NumSegments - 1 + 3)) num_out_of_range_over_3++;
164 if (scaledVal > max_scaledVal)
166 max_scaledVal = scaledVal;
167 max_scaledVal = scaledVal;
171 float scaledValFloor = floorf(scaledVal);
172 scaledValFloor = std::max(0.0f, std::min((
float)(NumSegments - 1), scaledValFloor));
173 float t = scaledVal - scaledValFloor;
174 int k = (int)scaledValFloor;
185 m1 = 0.5f * (K[2] - K[0]);
190 m0 = 0.5f * (K[k + 1] - K[k - 1]);
192 m1 = 0.5f * (K[k + 2] - K[k]);
194 case NumSegments - 2:
196 p0 = K[NumSegments - 2];
197 m0 = 0.5f * (K[NumSegments - 1] - K[NumSegments - 2]);
198 p1 = K[NumSegments - 1];
199 m1 = K[NumSegments - 1] - K[NumSegments - 2];
201 case NumSegments - 1:
203 p0 = K[NumSegments - 1];
204 m0 = K[NumSegments - 1] - K[NumSegments - 2];
210 float omt = 1.0f - t;
211 float res = (p0 * (1.0f + 2.0f * t) + m0 * t) * omt * omt + (p1 * (1.0f + 2.0f * omt) - m1 * omt) * t * t;
227 scale = (
K[0] + rsq * (
K[1] + rsq * (
K[2] + rsq *
K[3])));
230 scale = 1.0f / (
K[0] + rsq * (
K[1] + rsq * (
K[2] + rsq *
K[3])));
239 float scaledRsq = (float)(NumSegments - 1) * rsq / (
MaxR *
MaxR);
271 assert((r <= 20.0f));
274 float delta = r * 0.25f;
281 for (
int i = 0; i < 20; i++)
283 float sUp =
s + delta;
284 float sDown =
s - delta;
319 scale = 1.0f / (
InvK[0] + rsq * (
InvK[1] + rsq * (
InvK[2] + rsq *
InvK[3])));
328 float scaledRsq = (float)(NumSegments - 1) * rsq / (
MaxInvR *
MaxInvR);
359 sampleR[1] = maxR * 0.4f;
360 sampleR[2] = maxR * 0.8f;
361 sampleR[3] = maxR * 1.5f;
362 for (
int i = 0; i < 4; i++)
364 sampleRSq[i] = sampleR[i] * sampleR[i];
366 sampleFit[i] = sampleR[i] / sampleInv[i];
378 const int maxCheck = 20;
379 for (
int i = 0; i < maxCheck; i++ )
381 float checkR = (float)i * maxR / (
float)maxCheck;
384 float error = fabsf ( realInv - testInv ) / maxR;
385 OVR_ASSERT ( error < 0.1f );
395 for (
int i = 1; i < NumSegments; i++)
397 float scaledRsq = (float)i;
398 float rsq = scaledRsq *
MaxInvR *
MaxInvR / (float)(NumSegments - 1);
399 float r = sqrtf(rsq);
406 const int maxCheck = 20;
407 for (
int i = 0; i <= maxCheck; i++ )
409 float checkR = (float)i *
MaxInvR / (
float)maxCheck;
412 float error = fabsf ( realInv - testInv ) /
MaxR;
413 OVR_ASSERT ( error < 0.01f );
551 float orthoHorizontalOffset = eyeViewAdjustX / orthoDistance;
572 SLfloat orthoData[16] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
574 orthoData[0] = projection.
m(0) * orthoScale.
x;
577 orthoData[12] = -projection.
m(8) + (orthoHorizontalOffset * projection.
m(0));
580 orthoData[5] = -projection.
m(5) * orthoScale.
y;
582 orthoData[13] = -projection.
m(9);
588 orthoData[10] = 0.0f;
589 orthoData[14] = 0.0f;
595 orthoData[11] = 0.0f;
596 orthoData[15] = 1.0f;
666 float tanEyeAngleRadius = tanEyeAngle.
length();
672 SLVec2f tanEyeAngleDistorted = tanEyeAngle;
673 if (tanEyeAngleRadius > 0.0f)
675 tanEyeAngleDistorted = tanEyeAngle * (tanEyeAngleDistortedRadius / tanEyeAngleRadius);
682 return framebufferNDC;
694 float radiusSquared = (tanEyeAngleDistorted.
x * tanEyeAngleDistorted.
x) + (tanEyeAngleDistorted.
y * tanEyeAngleDistorted.
y);
696 *resultR = tanEyeAngleDistorted * distortionScales.
x;
697 *resultG = tanEyeAngleDistorted * distortionScales.
y;
698 *resultB = tanEyeAngleDistorted * distortionScales.
z;
732 textureNDC.
x = tanEyeAngle.
x * eyeToSourceNDC.
Scale.
x + eyeToSourceNDC.
Offset.
x;
733 textureNDC.
y = tanEyeAngle.
y * eyeToSourceNDC.
Scale.
y + eyeToSourceNDC.
Offset.
y;
743 tanEyeAngle.
x = (textureNDC.
x - eyeToSourceNDC.
Offset.
x) / eyeToSourceNDC.
Scale.
x;
744 tanEyeAngle.
y = (textureNDC.
y - eyeToSourceNDC.
Offset.
y) / eyeToSourceNDC.
Scale.
y;
753 float projXOffset = (tanHalfFov.
LeftTan - tanHalfFov.
RightTan) * projXScale * 0.5f;
754 float projYScale = 2.0f / (tanHalfFov.
UpTan + tanHalfFov.
DownTan);
755 float projYOffset = (tanHalfFov.
UpTan - tanHalfFov.
DownTan) * projYScale * 0.5f;
774 float handednessScale = 1.0f;
777 handednessScale = -1.0f;
780 float proj[4][4] = {{1, 0, 0, 0},
786 proj[0][0] = scaleAndOffset.
Scale.
x;
788 proj[0][2] = handednessScale * scaleAndOffset.
Offset.
x;
796 proj[1][1] = scaleAndOffset.
Scale.
y;
797 proj[1][2] = handednessScale * -scaleAndOffset.
Offset.
y;
804 proj[2][2] = -handednessScale * zFar / (zNear - zFar);
805 proj[2][3] = (zFar * zNear) / (zNear - zFar);
810 proj[3][2] = handednessScale;
821 uint16_t** ppTriangleListIndices,
829 static const int DMA_GridSizeLog2 = 6;
830 static const int DMA_GridSize = 1 << DMA_GridSizeLog2;
831 static const int DMA_NumVertsPerEye = (DMA_GridSize + 1) * (DMA_GridSize + 1);
832 static const int DMA_NumTrisPerEye = (DMA_GridSize) * (DMA_GridSize)*2;
835 const float fadeOutBorderFraction = 0.075f;
838 float xOffset = 0.0f;
844 *pNumVertices = DMA_NumVertsPerEye;
845 *pNumTriangles = DMA_NumTrisPerEye;
848 *ppTriangleListIndices = (uint16_t*)(
new uint16_t[
sizeof(uint16_t) * (*pNumTriangles) * 3]);
853 for (
int y = 0; y <= DMA_GridSize; y++)
855 for (
int x = 0; x <= DMA_GridSize; x++)
860 sourceCoordNDC.
x = 2.0f * ((float)x / (
float)DMA_GridSize) - 1.0f;
861 sourceCoordNDC.
y = 2.0f * ((float)y / (
float)DMA_GridSize) - 1.0f;
869 screenNDC.
x = std::max(-1.0f, std::min(screenNDC.
x, 1.0f));
870 screenNDC.
y = std::max(-1.0f, std::min(screenNDC.
y, 1.0f));
874 SLVec2f tanEyeAnglesR, tanEyeAnglesG, tanEyeAnglesB;
907 default: assert(
false);
break;
913 float edgeFadeIn = (1.0f / fadeOutBorderFraction) *
916 float edgeFadeInScreen = (2.0f / fadeOutBorderFraction) *
918 edgeFadeIn = std::min(edgeFadeInScreen, edgeFadeIn);
920 pcurVert->
Shade = std::max(0.0f, std::min(edgeFadeIn, 1.0f));
929 uint16_t* pcurIndex = *ppTriangleListIndices;
931 for (
int triNum = 0; triNum < DMA_GridSize * DMA_GridSize; triNum++)
935 assert(DMA_GridSize <= 256);
936 int x = ((triNum & 0x0001) >> 0) |
937 ((triNum & 0x0004) >> 1) |
938 ((triNum & 0x0010) >> 2) |
939 ((triNum & 0x0040) >> 3) |
940 ((triNum & 0x0100) >> 4) |
941 ((triNum & 0x0400) >> 5) |
942 ((triNum & 0x1000) >> 6) |
943 ((triNum & 0x4000) >> 7);
944 int y = ((triNum & 0x0002) >> 1) |
945 ((triNum & 0x0008) >> 2) |
946 ((triNum & 0x0020) >> 3) |
947 ((triNum & 0x0080) >> 4) |
948 ((triNum & 0x0200) >> 5) |
949 ((triNum & 0x0800) >> 6) |
950 ((triNum & 0x2000) >> 7) |
951 ((triNum & 0x8000) >> 8);
952 int FirstVertex = x * (DMA_GridSize + 1) + y;
974 if ((x < DMA_GridSize / 2) != (y < DMA_GridSize / 2))
976 *pcurIndex++ = (uint16_t)FirstVertex;
977 *pcurIndex++ = (uint16_t)FirstVertex + 1;
978 *pcurIndex++ = (uint16_t)FirstVertex + (DMA_GridSize + 1) + 1;
980 *pcurIndex++ = (uint16_t)FirstVertex + (DMA_GridSize + 1) + 1;
981 *pcurIndex++ = (uint16_t)FirstVertex + (DMA_GridSize + 1);
982 *pcurIndex++ = (uint16_t)FirstVertex;
986 *pcurIndex++ = (uint16_t)FirstVertex;
987 *pcurIndex++ = (uint16_t)FirstVertex + 1;
988 *pcurIndex++ = (uint16_t)FirstVertex + (DMA_GridSize + 1);
990 *pcurIndex++ = (uint16_t)FirstVertex + 1;
991 *pcurIndex++ = (uint16_t)FirstVertex + (DMA_GridSize + 1) + 1;
992 *pcurIndex++ = (uint16_t)FirstVertex + (DMA_GridSize + 1);
1088 distortion.
Lens.
K[0] = 1.00300002f;
1089 distortion.
Lens.
K[1] = 1.01999998f;
1090 distortion.
Lens.
K[2] = 1.04200006f;
1091 distortion.
Lens.
K[3] = 1.06599998f;
1092 distortion.
Lens.
K[4] = 1.09399998f;
1093 distortion.
Lens.
K[5] = 1.12600005f;
1094 distortion.
Lens.
K[6] = 1.16199994f;
1095 distortion.
Lens.
K[7] = 1.20299995f;
1096 distortion.
Lens.
K[8] = 1.25000000f;
1097 distortion.
Lens.
K[9] = 1.30999994f;
1098 distortion.
Lens.
K[10] = 1.38000000f;
1099 distortion.
Lens.
MaxR = 1.00000000f;
1106 distortion.
Lens.
InvK[1] = 0.964599669f;
1107 distortion.
Lens.
InvK[2] = 0.931152463f;
1108 distortion.
Lens.
InvK[3] = 0.898376584f;
1109 distortion.
Lens.
InvK[4] = 0.867980957f;
1110 distortion.
Lens.
InvK[5] = 0.839782715f;
1111 distortion.
Lens.
InvK[6] = 0.813964784f;
1112 distortion.
Lens.
InvK[7] = 0.789245605f;
1113 distortion.
Lens.
InvK[8] = 0.765808105f;
1114 distortion.
Lens.
InvK[9] = 0.745178223f;
1115 distortion.
Lens.
InvK[10] = 0.724639833f;
1133 SLuint triangleCount = 0;
1136 bool rightEye = (eye == rightEye);
1141 eyeToSourceNDC.
Scale.
x = 0.929788947f;
1142 eyeToSourceNDC.
Scale.
y = 0.752283394f;
1143 eyeToSourceNDC.
Offset.
x = -0.0156717598f;
1144 eyeToSourceNDC.
Offset.
y = 0.0f;
1147 eyeToSourceNDC.
Offset.
x *= -1;
1152 (uint16_t**)&indexData,
1160 SLuint indexCount = triangleCount * 3;
1164 verts.resize(vertexCount);
1169 for (
SLuint vertNum = 0; vertNum < vertexCount; vertNum++)
1184 for (
SLuint i = 0; i < indexCount; i++)
1185 tempIndex.push_back(indexData[i]);
1201 delete[] vertexData;
SLEyeType
Enumeration for stereo eye type used for camera projection.
@ AT_custom5
Custom vertex attribute 5.
@ AT_custom1
Custom vertex attribute 1.
@ AT_position
Vertex position as a 2, 3 or 4 component vectors.
@ AT_custom3
Custom vertex attribute 3.
@ AT_custom2
Custom vertex attribute 2.
@ AT_custom4
Custom vertex attribute 4.
@ BT_uint
vertex index type (0-2^32)
SLVec2f TransformTanFovSpaceToRendertargetNDC(ScaleAndOffset2D const &eyeToSourceNDC, SLVec2f const &tanEyeAngle)
ScaleAndOffset2D CreateNDCScaleAndOffsetFromFov(ovrFovPort tanHalfFov)
void TransformScreenNDCToTanFovSpaceChroma(SLVec2f *resultR, SLVec2f *resultG, SLVec2f *resultB, DistortionRenderDesc const &distortion, const SLVec2f &framebufferNDC)
void createSLDistortionMesh(DistortionMeshVertexData **ppVertices, uint16_t **ppTriangleListIndices, SLuint *pNumVertices, SLuint *pNumTriangles, bool rightEye, const HmdRenderInfo &hmdRenderInfo, const DistortionRenderDesc &distortion, const ScaleAndOffset2D &eyeToSourceNDC)
SLVec2f TransformTanFovSpaceToScreenNDC(DistortionRenderDesc const &distortion, const SLVec2f &tanEyeAngle, bool usePolyApprox)
struct ovrFovPort_ ovrFovPort
SLVec2f TransformRendertargetNDCToTanFovSpace(const ScaleAndOffset2D &eyeToSourceNDC, const SLVec2f &textureNDC)
@ HmdType_CrystalCoveProto
@ Distortion_CatmullRom10
@ HmdShutter_RollingLeftToRight
@ HmdShutter_RollingTopToBottom
@ HmdShutter_RollingRightToLeft
float EvalCatmullRom10Spline(float const *K, float scaledVal)
SLMat4f ovrMatrix4f_OrthoSubProjection(SLMat4f projection, SLVec2f orthoScale, float orthoDistance, float eyeViewAdjustX)
struct ovrDistortionVertex_ ovrDistortionVertex
SLMat4f CreateProjection(bool rightHanded, ovrFovPort tanHalfFov, float zNear, float zFar)
struct ovrDistortionMesh_ ovrDistortionMesh
bool FitCubicPolynomial(float *pResult, const float *pFitX, const float *pFitY)
vector< SLVertexOculus > SLVVertexOculus
Wrapper class around OpenGL Vertex Array Objects (VAO)
SLVec2< SLfloat > SLVec2f
Encapsulation of an OpenGL shader program object.
SLGLVertexArray encapsulates the core OpenGL drawing.
void setAttrib(SLGLAttributeType type, SLint elementSize, SLint location, void *dataPointer, SLGLBufferType dataType=BT_float)
Adds a vertex attribute with data pointer and an element size.
void setIndices(SLuint numIndicesElements, SLGLBufferType indexDataType, void *indexDataElements, SLuint numIndicesEdges=0, void *indexDataEdges=nullptr)
Adds the index array for indexed element drawing.
void generate(SLuint numVertices, SLGLBufferUsage usage=BU_static, SLbool outputInterleaved=true, SLuint divisor=0)
Generates the VA & VB objects for a NO. of vertices.
void transpose()
Sets the transposed matrix by swaping around the main diagonal.
The SLScene class represents the top level instance holding the scene structure.
SLVec2f PixelsPerTanAngleAtCenter
float NoseToPupilInMeters
float FirstScanlineToLastScanline
float VsyncToFirstScanline
ovrSizei ResolutionInPixels
struct HmdRenderInfo::ShutterInfo Shutter
float CenterFromTopInMeters
EyeConfig GetEyeCenter() const
float ScreenGapSizeInMeters
float LensSurfaceToMidplateInMeters
struct HmdRenderInfo::EyeConfig EyeLeft
float LensSeparationInMeters
struct HmdRenderInfo::EyeConfig EyeRight
float LensDiameterInMeters
ovrSizef ScreenSizeInMeters
void SetUpInverseApprox()
SLVec3f DistortionFnScaleRadiusSquaredChroma(float rsq) const
float DistortionFn(float r) const
float MetersPerTanAngleAtCenter
float DistortionFnScaleRadiusSquared(float rsq) const
float ChromaticAberration[4]
float InvK[NumCoefficients]
float DistortionFnInverse(float r) const
float DistortionFnInverseApprox(float r) const
ScaleAndOffset2D(float sx=0.0f, float sy=0.0f, float ox=0.0f, float oy=0.0f)
ovrDistortionVertex * pVertexData
unsigned short * pIndexData
float DownTan
The tangent of the angle between the viewing vector and the bottom edge of the field of view.
float UpTan
The tangent of the angle between the viewing vector and the top edge of the field of view.
float RightTan
The tangent of the angle between the viewing vector and the right edge of the field of view.
float LeftTan
The tangent of the angle between the viewing vector and the left edge of the field of view.